528 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			528 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// 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 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 l_mean = 1) : m_l(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>(static_cast<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>(static_cast<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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    inline RealType kurtosis(const poisson_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								    { // kurtosis is 4th moment about the mean = u4 / sd ^ 4
							 | 
						||
| 
								 | 
							
								      // http://en.wikipedia.org/wiki/Curtosis
							 | 
						||
| 
								 | 
							
								      // kurtosis can range from -2 (flat top) to +infinity (sharp peak & heavy tails).
							 | 
						||
| 
								 | 
							
								      // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
							 | 
						||
| 
								 | 
							
								      return 3 + 1 / dist.mean(); // NIST.
							 | 
						||
| 
								 | 
							
								      // 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    RealType pdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
							 | 
						||
| 
								 | 
							
								    { // Probability Density/Mass Function.
							 | 
						||
| 
								 | 
							
								      // Probability that there are EXACTLY k occurrences (or arrivals).
							 | 
						||
| 
								 | 
							
								      BOOST_FPU_EXCEPTION_GUARD
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      BOOST_MATH_STD_USING // for ADL of std functions.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      RealType mean = dist.mean();
							 | 
						||
| 
								 | 
							
								      // Error check:
							 | 
						||
| 
								 | 
							
								      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;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Special case of mean zero, regardless of the number of events k.
							 | 
						||
| 
								 | 
							
								      if (mean == 0)
							 | 
						||
| 
								 | 
							
								      { // Probability for any k is zero.
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (k == 0)
							 | 
						||
| 
								 | 
							
								      { // mean ^ k = 1, and k! = 1, so can simplify.
							 | 
						||
| 
								 | 
							
								        return exp(-mean);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return boost::math::gamma_p_derivative(k+1, mean, Policy());
							 | 
						||
| 
								 | 
							
								    } // pdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    RealType cdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
							 | 
						||
| 
								 | 
							
								    { // Cumulative Distribution Function Poisson.
							 | 
						||
| 
								 | 
							
								      // The random variate k is the number of 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.
							 | 
						||
| 
								 | 
							
								      // Returns the sum of the terms 0 through k of the Poisson Probability Density or Mass (pdf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // But 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 of the method of calculation using a continuous gamma function,
							 | 
						||
| 
								 | 
							
								      // it is convenient to treat it as if it is a continous function
							 | 
						||
| 
								 | 
							
								      // and permit non-integral values of k.
							 | 
						||
| 
								 | 
							
								      // To enforce the strict mathematical model, users should use floor or ceil functions
							 | 
						||
| 
								 | 
							
								      // outside this function to ensure that k is integral.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // The terms are not summed directly (at least for larger k)
							 | 
						||
| 
								 | 
							
								      // instead the incomplete gamma integral is employed,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      BOOST_MATH_STD_USING // for ADL of std function exp.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      RealType mean = dist.mean();
							 | 
						||
| 
								 | 
							
								      // Error checks:
							 | 
						||
| 
								 | 
							
								      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;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // Special cases:
							 | 
						||
| 
								 | 
							
								      if (mean == 0)
							 | 
						||
| 
								 | 
							
								      { // Probability for any k is zero.
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (k == 0)
							 | 
						||
| 
								 | 
							
								      { // return pdf(dist, static_cast<RealType>(0));
							 | 
						||
| 
								 | 
							
								        // but mean (and k) have already been checked,
							 | 
						||
| 
								 | 
							
								        // so this avoids unnecessary repeated checks.
							 | 
						||
| 
								 | 
							
								       return exp(-mean);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // For small integral k could use a finite sum -
							 | 
						||
| 
								 | 
							
								      // it's cheaper than the gamma function.
							 | 
						||
| 
								 | 
							
								      // BUT this is now done efficiently by gamma_q function.
							 | 
						||
| 
								 | 
							
								      // Calculate poisson cdf using the gamma_q function.
							 | 
						||
| 
								 | 
							
								      return gamma_q(k+1, mean, Policy());
							 | 
						||
| 
								 | 
							
								    } // binomial cdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    RealType cdf(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
							 | 
						||
| 
								 | 
							
								    { // Complemented Cumulative Distribution Function Poisson
							 | 
						||
| 
								 | 
							
								      // 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.
							 | 
						||
| 
								 | 
							
								      // But 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 of the method of calculation using a continuous gamma function,
							 | 
						||
| 
								 | 
							
								      // it is convenient to treat it as is it is a continous function
							 | 
						||
| 
								 | 
							
								      // and permit non-integral values of k.
							 | 
						||
| 
								 | 
							
								      // To enforce the strict mathematical model, users should use floor or ceil functions
							 | 
						||
| 
								 | 
							
								      // outside this function to ensure that k is integral.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Returns the sum of the terms k+1 through inf of the Poisson Probability Density/Mass (pdf).
							 | 
						||
| 
								 | 
							
								      // The terms are not summed directly (at least for larger k)
							 | 
						||
| 
								 | 
							
								      // instead the incomplete gamma integral is employed,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      RealType const& k = c.param;
							 | 
						||
| 
								 | 
							
								      poisson_distribution<RealType, Policy> const& dist = c.dist;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      RealType mean = dist.mean();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Error checks:
							 | 
						||
| 
								 | 
							
								      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;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // Special case of mean, regardless of the number of events k.
							 | 
						||
| 
								 | 
							
								      if (mean == 0)
							 | 
						||
| 
								 | 
							
								      { // Probability for any k is unity, complement of zero.
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (k == 0)
							 | 
						||
| 
								 | 
							
								      { // Avoid repeated checks on k and mean in gamma_p.
							 | 
						||
| 
								 | 
							
								         return -boost::math::expm1(-mean, Policy());
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // Unlike un-complemented cdf (sum from 0 to k),
							 | 
						||
| 
								 | 
							
								      // can't use finite sum from k+1 to infinity for small integral k,
							 | 
						||
| 
								 | 
							
								      // anyway it is now done efficiently by gamma_p.
							 | 
						||
| 
								 | 
							
								      return gamma_p(k + 1, mean, Policy()); // Calculate Poisson cdf using the gamma_p function.
							 | 
						||
| 
								 | 
							
								      // CCDF = gamma_p(k+1, lambda)
							 | 
						||
| 
								 | 
							
								    } // poisson ccdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    inline RealType quantile(const poisson_distribution<RealType, Policy>& dist, const RealType& p)
							 | 
						||
| 
								 | 
							
								    { // Quantile (or Percent Point) Poisson function.
							 | 
						||
| 
								 | 
							
								      // Return the number of expected events k for a given probability p.
							 | 
						||
| 
								 | 
							
								      static const char* function = "boost::math::quantile(const poisson_distribution<%1%>&, %1%)";
							 | 
						||
| 
								 | 
							
								      RealType result = 0; // of Argument checks:
							 | 
						||
| 
								 | 
							
								      if(false == poisson_detail::check_prob(
							 | 
						||
| 
								 | 
							
								        function,
							 | 
						||
| 
								 | 
							
								        p,
							 | 
						||
| 
								 | 
							
								        &result, Policy()))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        return result;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // Special case:
							 | 
						||
| 
								 | 
							
								      if (dist.mean() == 0)
							 | 
						||
| 
								 | 
							
								      { // if mean = 0 then p = 0, so k can be anything?
							 | 
						||
| 
								 | 
							
								         if (false == poisson_detail::check_mean_NZ(
							 | 
						||
| 
								 | 
							
								         function,
							 | 
						||
| 
								 | 
							
								         dist.mean(),
							 | 
						||
| 
								 | 
							
								         &result, Policy()))
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          return result;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if(p == 0)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         return 0; // Exact result regardless of discrete-quantile Policy
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if(p == 1)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         return policies::raise_overflow_error<RealType>(function, 0, Policy());
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      typedef typename Policy::discrete_quantile_type discrete_type;
							 | 
						||
| 
								 | 
							
								      boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								      RealType guess, 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);
							 | 
						||
| 
								 | 
							
								   } // quantile
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								    inline RealType quantile(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
							 | 
						||
| 
								 | 
							
								    { // Quantile (or Percent Point) of Poisson function.
							 | 
						||
| 
								 | 
							
								      // Return the number of expected events k for a given
							 | 
						||
| 
								 | 
							
								      // complement of the probability q.
							 | 
						||
| 
								 | 
							
								      //
							 | 
						||
| 
								 | 
							
								      // Error checks:
							 | 
						||
| 
								 | 
							
								      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;  // of argument checks.
							 | 
						||
| 
								 | 
							
								      if(false == poisson_detail::check_prob(
							 | 
						||
| 
								 | 
							
								        function,
							 | 
						||
| 
								 | 
							
								        q,
							 | 
						||
| 
								 | 
							
								        &result, Policy()))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        return result;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // Special case:
							 | 
						||
| 
								 | 
							
								      if (dist.mean() == 0)
							 | 
						||
| 
								 | 
							
								      { // if mean = 0 then p = 0, so k can be anything?
							 | 
						||
| 
								 | 
							
								         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;  // Exact result regardless of discrete-quantile Policy
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      typedef typename Policy::discrete_quantile_type discrete_type;
							 | 
						||
| 
								 | 
							
								      boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								      RealType guess, 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);
							 | 
						||
| 
								 | 
							
								   } // quantile complement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  } // namespace math
							 | 
						||
| 
								 | 
							
								} // namespace boost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This include must be at the end, *after* the accessors
							 | 
						||
| 
								 | 
							
								// for this distribution have been defined, in order to
							 | 
						||
| 
								 | 
							
								// keep compilers that support two-phase lookup happy.
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/derived_accessors.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_MATH_SPECIAL_POISSON_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |