poisson.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 589 行 · 第 1/2 页
HPP
589 行
// boost\math\distributions\poisson.hpp// Copyright John Maddock 2006.// Copyright Paul A. Bristow 2007.// Use, modification and distribution are subject to the// Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)// Poisson distribution is a discrete probability distribution.// It expresses the probability of a number (k) of// events, occurrences, failures or arrivals occurring in a fixed time,// assuming these events occur with a known average or mean rate (lambda)// and are independent of the time since the last event.// The distribution was discovered by Simeon-Denis Poisson (1781-1840).// Parameter lambda is the mean number of events in the given time interval.// The random variate k is the number of events, occurrences or arrivals.// k argument may be integral, signed, or unsigned, or floating point.// If necessary, it has already been promoted from an integral type.// Note that the Poisson distribution// (like others including the binomial, negative binomial & Bernoulli)// is strictly defined as a discrete function:// only integral values of k are envisaged.// However because the method of calculation uses a continuous gamma function,// it is convenient to treat it as if a continous function,// and permit non-integral values of k.// To enforce the strict mathematical model, users should use floor or ceil functions// on k outside this function to ensure that k is integral.// See http://en.wikipedia.org/wiki/Poisson_distribution// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html#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> // for incomplete gamma. gamma_q#include <boost/math/special_functions/trunc.hpp> // for incomplete gamma. gamma_q#include <boost/math/distributions/complement.hpp> // complements#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks#include <boost/math/special_functions/fpclassify.hpp> // isnan.#include <boost/math/special_functions/factorials.hpp> // factorials.#include <boost/math/tools/roots.hpp> // for root finding.#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>#include <utility>namespace boost{ namespace math { namespace detail{ template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::integer_round_nearest>&, boost::uintmax_t& max_iter); template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::integer_round_up>&, boost::uintmax_t& max_iter); template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::integer_round_down>&, boost::uintmax_t& max_iter); template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::integer_round_outwards>&, boost::uintmax_t& max_iter); template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::integer_round_inwards>&, boost::uintmax_t& max_iter); template <class Dist> inline typename Dist::value_type inverse_discrete_quantile( const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, const typename Dist::value_type& multiplier, const typename Dist::value_type& adder, const policies::discrete_quantile<policies::real>&, boost::uintmax_t& max_iter); } namespace poisson_detail { // Common error checking routines for Poisson distribution functions. // These are convoluted, & apparently redundant, to try to ensure that // checks are always performed, even if exceptions are not enabled. 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; } // bool check_mean template <class RealType, class Policy> inline bool check_mean_NZ(const char* function, const RealType& mean, RealType* result, const Policy& pol) { // mean == 0 is considered an error. 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; } // bool check_mean_NZ template <class RealType, class Policy> inline bool check_dist(const char* function, const RealType& mean, RealType* result, const Policy& pol) { // Only one check, so this is redundant really but should be optimized away. return check_mean_NZ(function, mean, result, pol); } // bool check_dist 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; } // bool check_k 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; } // bool check_dist_and_k template <class RealType, class Policy> inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) { // Check 0 <= p <= 1 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; } // bool check_prob 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; } // bool check_dist_and_prob } // namespace poisson_detail template <class RealType = double, class Policy = policies::policy<> > class poisson_distribution { public: typedef RealType value_type; typedef Policy policy_type; poisson_distribution(RealType mean = 1) : m_l(mean) // mean (lambda). { // Expected mean number of events that occur during the given interval. RealType r; poisson_detail::check_dist( "boost::math::poisson_distribution<%1%>::poisson_distribution", m_l, &r, Policy()); } // poisson_distribution constructor. RealType mean() const { // Private data getter function. return m_l; } private: // Data member, initialized by constructor. RealType m_l; // mean number of occurrences. }; // template <class RealType, class Policy> class poisson_distribution typedef poisson_distribution<double> poisson; // Reserved name of type double. // Non-member functions to give properties of the distribution. template <class RealType, class Policy> inline const std::pair<RealType, RealType> range(const poisson_distribution<RealType, Policy>& /* dist */) { // Range of permissible values for random variable k. using boost::math::tools::max_value; return std::pair<RealType, RealType>(0, max_value<RealType>()); // Max integer? } template <class RealType, class Policy> inline const std::pair<RealType, RealType> support(const poisson_distribution<RealType, Policy>& /* dist */) { // Range of supported values for random variable k. // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. using boost::math::tools::max_value; return std::pair<RealType, RealType>(0, max_value<RealType>()); } template <class RealType, class Policy> inline RealType mean(const poisson_distribution<RealType, Policy>& dist) { // Mean of poisson distribution = lambda. return dist.mean(); } // mean template <class RealType, class Policy> inline RealType mode(const poisson_distribution<RealType, Policy>& dist) { // mode. BOOST_MATH_STD_USING // ADL of std functions. return floor(dist.mean()); } //template <class RealType, class Policy> //inline RealType median(const poisson_distribution<RealType, Policy>& dist) //{ // median = approximately lambda + 1/3 - 0.2/lambda // RealType l = dist.mean(); // return dist.mean() + static_cast<RealType>(0.3333333333333333333333333333333333333333333333) // - static_cast<RealType>(0.2) / l; //} // BUT this formula appears to be out-by-one compared to quantile(half) // Query posted on Wikipedia. // Now implemented via quantile(half) in derived accessors. template <class RealType, class Policy> inline RealType variance(const poisson_distribution<RealType, Policy>& dist) { // variance. return dist.mean(); } // RealType standard_deviation(const poisson_distribution<RealType, Policy>& dist) // standard_deviation provided by derived accessors. template <class RealType, class Policy> inline RealType skewness(const poisson_distribution<RealType, Policy>& dist) { // skewness = sqrt(l). BOOST_MATH_STD_USING // ADL of std functions. return 1 / sqrt(dist.mean()); } template <class RealType, class Policy> inline RealType kurtosis_excess(const poisson_distribution<RealType, Policy>& dist) { // skewness = sqrt(l). return 1 / dist.mean(); // kurtosis_excess 1/mean from Wiki & MathWorld eq 31. // http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess // is more convenient because the kurtosis excess of a normal distribution is zero // whereas the true kurtosis is 3. } // RealType kurtosis_excess
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?