123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- #ifndef BOOST_MATH_SPECIAL_POISSON_HPP
- #define BOOST_MATH_SPECIAL_POISSON_HPP
- #include <boost/math/distributions/fwd.hpp>
- #include <boost/math/special_functions/gamma.hpp>
- #include <boost/math/special_functions/trunc.hpp>
- #include <boost/math/distributions/complement.hpp>
- #include <boost/math/distributions/detail/common_error_handling.hpp>
- #include <boost/math/special_functions/fpclassify.hpp>
- #include <boost/math/special_functions/factorials.hpp>
- #include <boost/math/tools/roots.hpp>
- #include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
- #include <utility>
- #include <limits>
- namespace boost
- {
- namespace math
- {
- namespace poisson_detail
- {
-
-
-
- template <class RealType, class Policy>
- inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol)
- {
- if(!(boost::math::isfinite)(mean) || (mean < 0))
- {
- *result = policies::raise_domain_error<RealType>(
- function,
- "Mean argument is %1%, but must be >= 0 !", mean, pol);
- return false;
- }
- return true;
- }
- template <class RealType, class Policy>
- inline bool check_mean_NZ(const char* function, const RealType& mean, RealType* result, const Policy& pol)
- {
- if( !(boost::math::isfinite)(mean) || (mean <= 0))
- {
- *result = policies::raise_domain_error<RealType>(
- function,
- "Mean argument is %1%, but must be > 0 !", mean, pol);
- return false;
- }
- return true;
- }
- template <class RealType, class Policy>
- inline bool check_dist(const char* function, const RealType& mean, RealType* result, const Policy& pol)
- {
- return check_mean_NZ(function, mean, result, pol);
- }
- template <class RealType, class Policy>
- inline bool check_k(const char* function, const RealType& k, RealType* result, const Policy& pol)
- {
- if((k < 0) || !(boost::math::isfinite)(k))
- {
- *result = policies::raise_domain_error<RealType>(
- function,
- "Number of events k argument is %1%, but must be >= 0 !", k, pol);
- return false;
- }
- return true;
- }
- template <class RealType, class Policy>
- inline bool check_dist_and_k(const char* function, RealType mean, RealType k, RealType* result, const Policy& pol)
- {
- if((check_dist(function, mean, result, pol) == false) ||
- (check_k(function, k, result, pol) == false))
- {
- return false;
- }
- return true;
- }
- template <class RealType, class Policy>
- inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol)
- {
- if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
- {
- *result = policies::raise_domain_error<RealType>(
- function,
- "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
- return false;
- }
- return true;
- }
- template <class RealType, class Policy>
- inline bool check_dist_and_prob(const char* function, RealType mean, RealType p, RealType* result, const Policy& pol)
- {
- if((check_dist(function, mean, result, pol) == false) ||
- (check_prob(function, p, result, pol) == false))
- {
- return false;
- }
- return true;
- }
- }
- template <class RealType = double, class Policy = policies::policy<> >
- class poisson_distribution
- {
- public:
- using value_type = RealType;
- using policy_type = Policy;
- explicit poisson_distribution(RealType l_mean = 1) : m_l(l_mean)
- {
- RealType r;
- poisson_detail::check_dist(
- "boost::math::poisson_distribution<%1%>::poisson_distribution",
- m_l,
- &r, Policy());
- }
- RealType mean() const
- {
- return m_l;
- }
- private:
-
- RealType m_l;
- };
- using poisson = poisson_distribution<double>;
- #ifdef __cpp_deduction_guides
- template <class RealType>
- poisson_distribution(RealType)->poisson_distribution<typename boost::math::tools::promote_args<RealType>::type>;
- #endif
-
- template <class RealType, class Policy>
- inline std::pair<RealType, RealType> range(const poisson_distribution<RealType, Policy>& )
- {
- using boost::math::tools::max_value;
- return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
- }
- template <class RealType, class Policy>
- inline std::pair<RealType, RealType> support(const poisson_distribution<RealType, Policy>& )
- {
-
- using boost::math::tools::max_value;
- return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
- }
- template <class RealType, class Policy>
- inline RealType mean(const poisson_distribution<RealType, Policy>& dist)
- {
- return dist.mean();
- }
- template <class RealType, class Policy>
- inline RealType mode(const poisson_distribution<RealType, Policy>& dist)
- {
- BOOST_MATH_STD_USING
- return floor(dist.mean());
- }
-
- template <class RealType, class Policy>
- inline RealType variance(const poisson_distribution<RealType, Policy>& dist)
- {
- return dist.mean();
- }
-
- template <class RealType, class Policy>
- inline RealType skewness(const poisson_distribution<RealType, Policy>& dist)
- {
- BOOST_MATH_STD_USING
- return 1 / sqrt(dist.mean());
- }
- template <class RealType, class Policy>
- inline RealType kurtosis_excess(const poisson_distribution<RealType, Policy>& dist)
- {
- return 1 / dist.mean();
-
-
-
- }
- template <class RealType, class Policy>
- inline RealType kurtosis(const poisson_distribution<RealType, Policy>& dist)
- {
-
-
-
- return 3 + 1 / dist.mean();
-
-
-
- }
- template <class RealType, class Policy>
- RealType pdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
- {
-
- BOOST_FPU_EXCEPTION_GUARD
- BOOST_MATH_STD_USING
- RealType mean = dist.mean();
-
- RealType result = 0;
- if(false == poisson_detail::check_dist_and_k(
- "boost::math::pdf(const poisson_distribution<%1%>&, %1%)",
- mean,
- k,
- &result, Policy()))
- {
- return result;
- }
-
- if (mean == 0)
- {
- return 0;
- }
- if (k == 0)
- {
- return exp(-mean);
- }
- return boost::math::gamma_p_derivative(k+1, mean, Policy());
- }
- template <class RealType, class Policy>
- RealType logpdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
- {
- BOOST_FPU_EXCEPTION_GUARD
- BOOST_MATH_STD_USING
- using boost::math::lgamma;
- RealType mean = dist.mean();
-
- RealType result = -std::numeric_limits<RealType>::infinity();
- if(false == poisson_detail::check_dist_and_k(
- "boost::math::pdf(const poisson_distribution<%1%>&, %1%)",
- mean,
- k,
- &result, Policy()))
- {
- return result;
- }
-
- if (mean == 0)
- {
- return std::numeric_limits<RealType>::quiet_NaN();
- }
-
-
- if(k > 0 && mean > 0)
- {
- return -lgamma(k+1) + k*log(mean) - mean;
- }
- result = log(pdf(dist, k));
- return result;
- }
- template <class RealType, class Policy>
- RealType cdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOST_MATH_STD_USING
- RealType mean = dist.mean();
-
- RealType result = 0;
- if(false == poisson_detail::check_dist_and_k(
- "boost::math::cdf(const poisson_distribution<%1%>&, %1%)",
- mean,
- k,
- &result, Policy()))
- {
- return result;
- }
-
- if (mean == 0)
- {
- return 0;
- }
- if (k == 0)
- {
-
-
- return exp(-mean);
- }
-
-
-
-
- return gamma_q(k+1, mean, Policy());
- }
- template <class RealType, class Policy>
- RealType cdf(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- RealType const& k = c.param;
- poisson_distribution<RealType, Policy> const& dist = c.dist;
- RealType mean = dist.mean();
-
- RealType result = 0;
- if(false == poisson_detail::check_dist_and_k(
- "boost::math::cdf(const poisson_distribution<%1%>&, %1%)",
- mean,
- k,
- &result, Policy()))
- {
- return result;
- }
-
- if (mean == 0)
- {
- return 1;
- }
- if (k == 0)
- {
- return -boost::math::expm1(-mean, Policy());
- }
-
-
-
- return gamma_p(k + 1, mean, Policy());
-
- }
- template <class RealType, class Policy>
- inline RealType quantile(const poisson_distribution<RealType, Policy>& dist, const RealType& p)
- {
-
- static const char* function = "boost::math::quantile(const poisson_distribution<%1%>&, %1%)";
- RealType result = 0;
- if(false == poisson_detail::check_prob(
- function,
- p,
- &result, Policy()))
- {
- return result;
- }
-
- if (dist.mean() == 0)
- {
- if (false == poisson_detail::check_mean_NZ(
- function,
- dist.mean(),
- &result, Policy()))
- {
- return result;
- }
- }
- if(p == 0)
- {
- return 0;
- }
- if(p == 1)
- {
- return policies::raise_overflow_error<RealType>(function, 0, Policy());
- }
- using discrete_type = typename Policy::discrete_quantile_type;
- std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
- RealType guess;
- RealType factor = 8;
- RealType z = dist.mean();
- if(z < 1)
- guess = z;
- else
- guess = boost::math::detail::inverse_poisson_cornish_fisher(z, p, RealType(1-p), Policy());
- if(z > 5)
- {
- if(z > 1000)
- factor = 1.01f;
- else if(z > 50)
- factor = 1.1f;
- else if(guess > 10)
- factor = 1.25f;
- else
- factor = 2;
- if(guess < 1.1)
- factor = 8;
- }
- return detail::inverse_discrete_quantile(
- dist,
- p,
- false,
- guess,
- factor,
- RealType(1),
- discrete_type(),
- max_iter);
- }
- template <class RealType, class Policy>
- inline RealType quantile(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
- {
-
-
-
-
- static const char* function = "boost::math::quantile(complement(const poisson_distribution<%1%>&, %1%))";
- RealType q = c.param;
- const poisson_distribution<RealType, Policy>& dist = c.dist;
- RealType result = 0;
- if(false == poisson_detail::check_prob(
- function,
- q,
- &result, Policy()))
- {
- return result;
- }
-
- if (dist.mean() == 0)
- {
- if (false == poisson_detail::check_mean_NZ(
- function,
- dist.mean(),
- &result, Policy()))
- {
- return result;
- }
- }
- if(q == 0)
- {
- return policies::raise_overflow_error<RealType>(function, 0, Policy());
- }
- if(q == 1)
- {
- return 0;
- }
- using discrete_type = typename Policy::discrete_quantile_type;
- std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
- RealType guess;
- RealType factor = 8;
- RealType z = dist.mean();
- if(z < 1)
- guess = z;
- else
- guess = boost::math::detail::inverse_poisson_cornish_fisher(z, RealType(1-q), q, Policy());
- if(z > 5)
- {
- if(z > 1000)
- factor = 1.01f;
- else if(z > 50)
- factor = 1.1f;
- else if(guess > 10)
- factor = 1.25f;
- else
- factor = 2;
- if(guess < 1.1)
- factor = 8;
- }
- return detail::inverse_discrete_quantile(
- dist,
- q,
- true,
- guess,
- factor,
- RealType(1),
- discrete_type(),
- max_iter);
- }
- }
- }
- #include <boost/math/distributions/detail/derived_accessors.hpp>
- #endif
|