Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:39

0001 // boost\math\distributions\bernoulli.hpp
0002 
0003 // Copyright John Maddock 2006.
0004 // Copyright Paul A. Bristow 2007.
0005 
0006 // Use, modification and distribution are subject to the
0007 // Boost Software License, Version 1.0.
0008 // (See accompanying file LICENSE_1_0.txt
0009 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 // http://en.wikipedia.org/wiki/bernoulli_distribution
0012 // http://mathworld.wolfram.com/BernoulliDistribution.html
0013 
0014 // bernoulli distribution is the discrete probability distribution of
0015 // the number (k) of successes, in a single Bernoulli trials.
0016 // It is a version of the binomial distribution when n = 1.
0017 
0018 // But note that the bernoulli distribution
0019 // (like others including the poisson, binomial & negative binomial)
0020 // is strictly defined as a discrete function: only integral values of k are envisaged.
0021 // However because of the method of calculation using a continuous gamma function,
0022 // it is convenient to treat it as if a continuous function,
0023 // and permit non-integral values of k.
0024 // To enforce the strict mathematical model, users should use floor or ceil functions
0025 // on k outside this function to ensure that k is integral.
0026 
0027 #ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP
0028 #define BOOST_MATH_SPECIAL_BERNOULLI_HPP
0029 
0030 #include <boost/math/distributions/fwd.hpp>
0031 #include <boost/math/tools/config.hpp>
0032 #include <boost/math/distributions/complement.hpp> // complements
0033 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
0034 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
0035 
0036 #include <utility>
0037 
0038 namespace boost
0039 {
0040   namespace math
0041   {
0042     namespace bernoulli_detail
0043     {
0044       // Common error checking routines for bernoulli distribution functions:
0045       template <class RealType, class Policy>
0046       inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
0047       {
0048         if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
0049         {
0050           *result = policies::raise_domain_error<RealType>(
0051             function,
0052             "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy());
0053           return false;
0054         }
0055         return true;
0056       }
0057       template <class RealType, class Policy>
0058       inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const std::true_type&)
0059       {
0060         return check_success_fraction(function, p, result, Policy());
0061       }
0062       template <class RealType, class Policy>
0063       inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const std::false_type&)
0064       {
0065          return true;
0066       }
0067       template <class RealType, class Policy>
0068       inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
0069       {
0070          return check_dist(function, p, result, Policy(), typename policies::constructor_error_check<Policy>::type());
0071       }
0072 
0073       template <class RealType, class Policy>
0074       inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol)
0075       {
0076         if(check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) == false)
0077         {
0078           return false;
0079         }
0080         if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1)))
0081         {
0082           *result = policies::raise_domain_error<RealType>(
0083             function,
0084             "Number of successes argument is %1%, but must be 0 or 1 !", k, pol);
0085           return false;
0086         }
0087        return true;
0088       }
0089       template <class RealType, class Policy>
0090       inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */)
0091       {
0092         if((check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) && detail::check_probability(function, prob, result, Policy())) == false)
0093         {
0094           return false;
0095         }
0096         return true;
0097       }
0098     } // namespace bernoulli_detail
0099 
0100 
0101     template <class RealType = double, class Policy = policies::policy<> >
0102     class bernoulli_distribution
0103     {
0104     public:
0105       typedef RealType value_type;
0106       typedef Policy policy_type;
0107 
0108       bernoulli_distribution(RealType p = 0.5) : m_p(p)
0109       { // Default probability = half suits 'fair' coin tossing
0110         // where probability of heads == probability of tails.
0111         RealType result; // of checks.
0112         bernoulli_detail::check_dist(
0113            "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution",
0114           m_p,
0115           &result, Policy());
0116       } // bernoulli_distribution constructor.
0117 
0118       RealType success_fraction() const
0119       { // Probability.
0120         return m_p;
0121       }
0122 
0123     private:
0124       RealType m_p; // success_fraction
0125     }; // template <class RealType> class bernoulli_distribution
0126 
0127     typedef bernoulli_distribution<double> bernoulli;
0128 
0129     #ifdef __cpp_deduction_guides
0130     template <class RealType>
0131     bernoulli_distribution(RealType)->bernoulli_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0132     #endif
0133 
0134     template <class RealType, class Policy>
0135     inline const std::pair<RealType, RealType> range(const bernoulli_distribution<RealType, Policy>& /* dist */)
0136     { // Range of permissible values for random variable k = {0, 1}.
0137       using boost::math::tools::max_value;
0138       return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0139     }
0140 
0141     template <class RealType, class Policy>
0142     inline const std::pair<RealType, RealType> support(const bernoulli_distribution<RealType, Policy>& /* dist */)
0143     { // Range of supported values for random variable k = {0, 1}.
0144       // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
0145       return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0146     }
0147 
0148     template <class RealType, class Policy>
0149     inline RealType mean(const bernoulli_distribution<RealType, Policy>& dist)
0150     { // Mean of bernoulli distribution = p (n = 1).
0151       return dist.success_fraction();
0152     } // mean
0153 
0154     // Rely on derived_accessors quantile(half)
0155     //template <class RealType>
0156     //inline RealType median(const bernoulli_distribution<RealType, Policy>& dist)
0157     //{ // Median of bernoulli distribution is not defined.
0158     //  return tools::domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
0159     //} // median
0160 
0161     template <class RealType, class Policy>
0162     inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
0163     { // Variance of bernoulli distribution =p * q.
0164       return  dist.success_fraction() * (1 - dist.success_fraction());
0165     } // variance
0166 
0167     template <class RealType, class Policy>
0168     RealType pdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0169     { // Probability Density/Mass Function.
0170       BOOST_FPU_EXCEPTION_GUARD
0171       // Error check:
0172       RealType result = 0; // of checks.
0173       if(false == bernoulli_detail::check_dist_and_k(
0174         "boost::math::pdf(bernoulli_distribution<%1%>, %1%)",
0175         dist.success_fraction(), // 0 to 1
0176         k, // 0 or 1
0177         &result, Policy()))
0178       {
0179         return result;
0180       }
0181       // Assume k is integral.
0182       if (k == 0)
0183       {
0184         return 1 - dist.success_fraction(); // 1 - p
0185       }
0186       else  // k == 1
0187       {
0188         return dist.success_fraction(); // p
0189       }
0190     } // pdf
0191 
0192     template <class RealType, class Policy>
0193     inline RealType cdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0194     { // Cumulative Distribution Function Bernoulli.
0195       RealType p = dist.success_fraction();
0196       // Error check:
0197       RealType result = 0;
0198       if(false == bernoulli_detail::check_dist_and_k(
0199         "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
0200         p,
0201         k,
0202         &result, Policy()))
0203       {
0204         return result;
0205       }
0206       if (k == 0)
0207       {
0208         return 1 - p;
0209       }
0210       else
0211       { // k == 1
0212         return 1;
0213       }
0214     } // bernoulli cdf
0215 
0216     template <class RealType, class Policy>
0217     inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0218     { // Complemented Cumulative Distribution Function bernoulli.
0219       RealType const& k = c.param;
0220       bernoulli_distribution<RealType, Policy> const& dist = c.dist;
0221       RealType p = dist.success_fraction();
0222       // Error checks:
0223       RealType result = 0;
0224       if(false == bernoulli_detail::check_dist_and_k(
0225         "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
0226         p,
0227         k,
0228         &result, Policy()))
0229       {
0230         return result;
0231       }
0232       if (k == 0)
0233       {
0234         return p;
0235       }
0236       else
0237       { // k == 1
0238         return 0;
0239       }
0240     } // bernoulli cdf complement
0241 
0242     template <class RealType, class Policy>
0243     inline RealType quantile(const bernoulli_distribution<RealType, Policy>& dist, const RealType& p)
0244     { // Quantile or Percent Point Bernoulli function.
0245       // Return the number of expected successes k either 0 or 1.
0246       // for a given probability p.
0247 
0248       RealType result = 0; // of error checks:
0249       if(false == bernoulli_detail::check_dist_and_prob(
0250         "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
0251         dist.success_fraction(),
0252         p,
0253         &result, Policy()))
0254       {
0255         return result;
0256       }
0257       if (p <= (1 - dist.success_fraction()))
0258       { // p <= pdf(dist, 0) == cdf(dist, 0)
0259         return 0;
0260       }
0261       else
0262       {
0263         return 1;
0264       }
0265     } // quantile
0266 
0267     template <class RealType, class Policy>
0268     inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0269     { // Quantile or Percent Point bernoulli function.
0270       // Return the number of expected successes k for a given
0271       // complement of the probability q.
0272       //
0273       // Error checks:
0274       RealType q = c.param;
0275       const bernoulli_distribution<RealType, Policy>& dist = c.dist;
0276       RealType result = 0;
0277       if(false == bernoulli_detail::check_dist_and_prob(
0278         "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
0279         dist.success_fraction(),
0280         q,
0281         &result, Policy()))
0282       {
0283         return result;
0284       }
0285 
0286       if (q <= 1 - dist.success_fraction())
0287       { // // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
0288         return 1;
0289       }
0290       else
0291       {
0292         return 0;
0293       }
0294     } // quantile complemented.
0295 
0296     template <class RealType, class Policy>
0297     inline RealType mode(const bernoulli_distribution<RealType, Policy>& dist)
0298     {
0299       return static_cast<RealType>((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1
0300     }
0301 
0302     template <class RealType, class Policy>
0303     inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
0304     {
0305       BOOST_MATH_STD_USING; // Aid ADL for sqrt.
0306       RealType p = dist.success_fraction();
0307       return (1 - 2 * p) / sqrt(p * (1 - p));
0308     }
0309 
0310     template <class RealType, class Policy>
0311     inline RealType kurtosis_excess(const bernoulli_distribution<RealType, Policy>& dist)
0312     {
0313       RealType p = dist.success_fraction();
0314       // Note Wolfram says this is kurtosis in text, but gamma2 is the kurtosis excess,
0315       // and Wikipedia also says this is the kurtosis excess formula.
0316       // return (6 * p * p - 6 * p + 1) / (p * (1 - p));
0317       // But Wolfram kurtosis article gives this simpler formula for kurtosis excess:
0318       return 1 / (1 - p) + 1/p -6;
0319     }
0320 
0321     template <class RealType, class Policy>
0322     inline RealType kurtosis(const bernoulli_distribution<RealType, Policy>& dist)
0323     {
0324       RealType p = dist.success_fraction();
0325       return 1 / (1 - p) + 1/p -6 + 3;
0326       // Simpler than:
0327       // return (6 * p * p - 6 * p + 1) / (p * (1 - p)) + 3;
0328     }
0329 
0330   } // namespace math
0331 } // namespace boost
0332 
0333 // This include must be at the end, *after* the accessors
0334 // for this distribution have been defined, in order to
0335 // keep compilers that support two-phase lookup happy.
0336 #include <boost/math/distributions/detail/derived_accessors.hpp>
0337 
0338 #endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP
0339 
0340 
0341