annotate DEPENDENCIES/generic/include/boost/math/distributions/bernoulli.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // boost\math\distributions\bernoulli.hpp
Chris@16 2
Chris@16 3 // Copyright John Maddock 2006.
Chris@16 4 // Copyright Paul A. Bristow 2007.
Chris@16 5
Chris@16 6 // Use, modification and distribution are subject to the
Chris@16 7 // Boost Software License, Version 1.0.
Chris@16 8 // (See accompanying file LICENSE_1_0.txt
Chris@16 9 // or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 // http://en.wikipedia.org/wiki/bernoulli_distribution
Chris@16 12 // http://mathworld.wolfram.com/BernoulliDistribution.html
Chris@16 13
Chris@16 14 // bernoulli distribution is the discrete probability distribution of
Chris@16 15 // the number (k) of successes, in a single Bernoulli trials.
Chris@16 16 // It is a version of the binomial distribution when n = 1.
Chris@16 17
Chris@16 18 // But note that the bernoulli distribution
Chris@16 19 // (like others including the poisson, binomial & negative binomial)
Chris@16 20 // is strictly defined as a discrete function: only integral values of k are envisaged.
Chris@16 21 // However because of the method of calculation using a continuous gamma function,
Chris@16 22 // it is convenient to treat it as if a continous function,
Chris@16 23 // and permit non-integral values of k.
Chris@16 24 // To enforce the strict mathematical model, users should use floor or ceil functions
Chris@16 25 // on k outside this function to ensure that k is integral.
Chris@16 26
Chris@16 27 #ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP
Chris@16 28 #define BOOST_MATH_SPECIAL_BERNOULLI_HPP
Chris@16 29
Chris@16 30 #include <boost/math/distributions/fwd.hpp>
Chris@16 31 #include <boost/math/tools/config.hpp>
Chris@16 32 #include <boost/math/distributions/complement.hpp> // complements
Chris@16 33 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
Chris@16 34 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
Chris@16 35
Chris@16 36 #include <utility>
Chris@16 37
Chris@16 38 namespace boost
Chris@16 39 {
Chris@16 40 namespace math
Chris@16 41 {
Chris@16 42 namespace bernoulli_detail
Chris@16 43 {
Chris@16 44 // Common error checking routines for bernoulli distribution functions:
Chris@16 45 template <class RealType, class Policy>
Chris@16 46 inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
Chris@16 47 {
Chris@16 48 if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
Chris@16 49 {
Chris@16 50 *result = policies::raise_domain_error<RealType>(
Chris@16 51 function,
Chris@16 52 "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy());
Chris@16 53 return false;
Chris@16 54 }
Chris@16 55 return true;
Chris@16 56 }
Chris@16 57 template <class RealType, class Policy>
Chris@16 58 inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const mpl::true_&)
Chris@16 59 {
Chris@16 60 return check_success_fraction(function, p, result, Policy());
Chris@16 61 }
Chris@16 62 template <class RealType, class Policy>
Chris@16 63 inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const mpl::false_&)
Chris@16 64 {
Chris@16 65 return true;
Chris@16 66 }
Chris@16 67 template <class RealType, class Policy>
Chris@16 68 inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
Chris@16 69 {
Chris@16 70 return check_dist(function, p, result, Policy(), typename policies::constructor_error_check<Policy>::type());
Chris@16 71 }
Chris@16 72
Chris@16 73 template <class RealType, class Policy>
Chris@16 74 inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol)
Chris@16 75 {
Chris@16 76 if(check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) == false)
Chris@16 77 {
Chris@16 78 return false;
Chris@16 79 }
Chris@16 80 if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1)))
Chris@16 81 {
Chris@16 82 *result = policies::raise_domain_error<RealType>(
Chris@16 83 function,
Chris@16 84 "Number of successes argument is %1%, but must be 0 or 1 !", k, pol);
Chris@16 85 return false;
Chris@16 86 }
Chris@16 87 return true;
Chris@16 88 }
Chris@16 89 template <class RealType, class Policy>
Chris@16 90 inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */)
Chris@16 91 {
Chris@16 92 if(check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) && detail::check_probability(function, prob, result, Policy()) == false)
Chris@16 93 {
Chris@16 94 return false;
Chris@16 95 }
Chris@16 96 return true;
Chris@16 97 }
Chris@16 98 } // namespace bernoulli_detail
Chris@16 99
Chris@16 100
Chris@16 101 template <class RealType = double, class Policy = policies::policy<> >
Chris@16 102 class bernoulli_distribution
Chris@16 103 {
Chris@16 104 public:
Chris@16 105 typedef RealType value_type;
Chris@16 106 typedef Policy policy_type;
Chris@16 107
Chris@16 108 bernoulli_distribution(RealType p = 0.5) : m_p(p)
Chris@16 109 { // Default probability = half suits 'fair' coin tossing
Chris@16 110 // where probability of heads == probability of tails.
Chris@16 111 RealType result; // of checks.
Chris@16 112 bernoulli_detail::check_dist(
Chris@16 113 "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution",
Chris@16 114 m_p,
Chris@16 115 &result, Policy());
Chris@16 116 } // bernoulli_distribution constructor.
Chris@16 117
Chris@16 118 RealType success_fraction() const
Chris@16 119 { // Probability.
Chris@16 120 return m_p;
Chris@16 121 }
Chris@16 122
Chris@16 123 private:
Chris@16 124 RealType m_p; // success_fraction
Chris@16 125 }; // template <class RealType> class bernoulli_distribution
Chris@16 126
Chris@16 127 typedef bernoulli_distribution<double> bernoulli;
Chris@16 128
Chris@16 129 template <class RealType, class Policy>
Chris@16 130 inline const std::pair<RealType, RealType> range(const bernoulli_distribution<RealType, Policy>& /* dist */)
Chris@16 131 { // Range of permissible values for random variable k = {0, 1}.
Chris@16 132 using boost::math::tools::max_value;
Chris@16 133 return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
Chris@16 134 }
Chris@16 135
Chris@16 136 template <class RealType, class Policy>
Chris@16 137 inline const std::pair<RealType, RealType> support(const bernoulli_distribution<RealType, Policy>& /* dist */)
Chris@16 138 { // Range of supported values for random variable k = {0, 1}.
Chris@16 139 // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
Chris@16 140 return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
Chris@16 141 }
Chris@16 142
Chris@16 143 template <class RealType, class Policy>
Chris@16 144 inline RealType mean(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 145 { // Mean of bernoulli distribution = p (n = 1).
Chris@16 146 return dist.success_fraction();
Chris@16 147 } // mean
Chris@16 148
Chris@16 149 // Rely on dereived_accessors quantile(half)
Chris@16 150 //template <class RealType>
Chris@16 151 //inline RealType median(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 152 //{ // Median of bernoulli distribution is not defined.
Chris@16 153 // return tools::domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
Chris@16 154 //} // median
Chris@16 155
Chris@16 156 template <class RealType, class Policy>
Chris@16 157 inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 158 { // Variance of bernoulli distribution =p * q.
Chris@16 159 return dist.success_fraction() * (1 - dist.success_fraction());
Chris@16 160 } // variance
Chris@16 161
Chris@16 162 template <class RealType, class Policy>
Chris@16 163 RealType pdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
Chris@16 164 { // Probability Density/Mass Function.
Chris@16 165 BOOST_FPU_EXCEPTION_GUARD
Chris@16 166 // Error check:
Chris@16 167 RealType result = 0; // of checks.
Chris@16 168 if(false == bernoulli_detail::check_dist_and_k(
Chris@16 169 "boost::math::pdf(bernoulli_distribution<%1%>, %1%)",
Chris@16 170 dist.success_fraction(), // 0 to 1
Chris@16 171 k, // 0 or 1
Chris@16 172 &result, Policy()))
Chris@16 173 {
Chris@16 174 return result;
Chris@16 175 }
Chris@16 176 // Assume k is integral.
Chris@16 177 if (k == 0)
Chris@16 178 {
Chris@16 179 return 1 - dist.success_fraction(); // 1 - p
Chris@16 180 }
Chris@16 181 else // k == 1
Chris@16 182 {
Chris@16 183 return dist.success_fraction(); // p
Chris@16 184 }
Chris@16 185 } // pdf
Chris@16 186
Chris@16 187 template <class RealType, class Policy>
Chris@16 188 inline RealType cdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
Chris@16 189 { // Cumulative Distribution Function Bernoulli.
Chris@16 190 RealType p = dist.success_fraction();
Chris@16 191 // Error check:
Chris@16 192 RealType result = 0;
Chris@16 193 if(false == bernoulli_detail::check_dist_and_k(
Chris@16 194 "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
Chris@16 195 p,
Chris@16 196 k,
Chris@16 197 &result, Policy()))
Chris@16 198 {
Chris@16 199 return result;
Chris@16 200 }
Chris@16 201 if (k == 0)
Chris@16 202 {
Chris@16 203 return 1 - p;
Chris@16 204 }
Chris@16 205 else
Chris@16 206 { // k == 1
Chris@16 207 return 1;
Chris@16 208 }
Chris@16 209 } // bernoulli cdf
Chris@16 210
Chris@16 211 template <class RealType, class Policy>
Chris@16 212 inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
Chris@16 213 { // Complemented Cumulative Distribution Function bernoulli.
Chris@16 214 RealType const& k = c.param;
Chris@16 215 bernoulli_distribution<RealType, Policy> const& dist = c.dist;
Chris@16 216 RealType p = dist.success_fraction();
Chris@16 217 // Error checks:
Chris@16 218 RealType result = 0;
Chris@16 219 if(false == bernoulli_detail::check_dist_and_k(
Chris@16 220 "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
Chris@16 221 p,
Chris@16 222 k,
Chris@16 223 &result, Policy()))
Chris@16 224 {
Chris@16 225 return result;
Chris@16 226 }
Chris@16 227 if (k == 0)
Chris@16 228 {
Chris@16 229 return p;
Chris@16 230 }
Chris@16 231 else
Chris@16 232 { // k == 1
Chris@16 233 return 0;
Chris@16 234 }
Chris@16 235 } // bernoulli cdf complement
Chris@16 236
Chris@16 237 template <class RealType, class Policy>
Chris@16 238 inline RealType quantile(const bernoulli_distribution<RealType, Policy>& dist, const RealType& p)
Chris@16 239 { // Quantile or Percent Point Bernoulli function.
Chris@16 240 // Return the number of expected successes k either 0 or 1.
Chris@16 241 // for a given probability p.
Chris@16 242
Chris@16 243 RealType result = 0; // of error checks:
Chris@16 244 if(false == bernoulli_detail::check_dist_and_prob(
Chris@16 245 "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
Chris@16 246 dist.success_fraction(),
Chris@16 247 p,
Chris@16 248 &result, Policy()))
Chris@16 249 {
Chris@16 250 return result;
Chris@16 251 }
Chris@16 252 if (p <= (1 - dist.success_fraction()))
Chris@16 253 { // p <= pdf(dist, 0) == cdf(dist, 0)
Chris@16 254 return 0;
Chris@16 255 }
Chris@16 256 else
Chris@16 257 {
Chris@16 258 return 1;
Chris@16 259 }
Chris@16 260 } // quantile
Chris@16 261
Chris@16 262 template <class RealType, class Policy>
Chris@16 263 inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
Chris@16 264 { // Quantile or Percent Point bernoulli function.
Chris@16 265 // Return the number of expected successes k for a given
Chris@16 266 // complement of the probability q.
Chris@16 267 //
Chris@16 268 // Error checks:
Chris@16 269 RealType q = c.param;
Chris@16 270 const bernoulli_distribution<RealType, Policy>& dist = c.dist;
Chris@16 271 RealType result = 0;
Chris@16 272 if(false == bernoulli_detail::check_dist_and_prob(
Chris@16 273 "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
Chris@16 274 dist.success_fraction(),
Chris@16 275 q,
Chris@16 276 &result, Policy()))
Chris@16 277 {
Chris@16 278 return result;
Chris@16 279 }
Chris@16 280
Chris@16 281 if (q <= 1 - dist.success_fraction())
Chris@16 282 { // // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
Chris@16 283 return 1;
Chris@16 284 }
Chris@16 285 else
Chris@16 286 {
Chris@16 287 return 0;
Chris@16 288 }
Chris@16 289 } // quantile complemented.
Chris@16 290
Chris@16 291 template <class RealType, class Policy>
Chris@16 292 inline RealType mode(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 293 {
Chris@16 294 return static_cast<RealType>((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1
Chris@16 295 }
Chris@16 296
Chris@16 297 template <class RealType, class Policy>
Chris@16 298 inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 299 {
Chris@16 300 BOOST_MATH_STD_USING; // Aid ADL for sqrt.
Chris@16 301 RealType p = dist.success_fraction();
Chris@16 302 return (1 - 2 * p) / sqrt(p * (1 - p));
Chris@16 303 }
Chris@16 304
Chris@16 305 template <class RealType, class Policy>
Chris@16 306 inline RealType kurtosis_excess(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 307 {
Chris@16 308 RealType p = dist.success_fraction();
Chris@16 309 // Note Wolfram says this is kurtosis in text, but gamma2 is the kurtosis excess,
Chris@16 310 // and Wikipedia also says this is the kurtosis excess formula.
Chris@16 311 // return (6 * p * p - 6 * p + 1) / (p * (1 - p));
Chris@16 312 // But Wolfram kurtosis article gives this simpler formula for kurtosis excess:
Chris@16 313 return 1 / (1 - p) + 1/p -6;
Chris@16 314 }
Chris@16 315
Chris@16 316 template <class RealType, class Policy>
Chris@16 317 inline RealType kurtosis(const bernoulli_distribution<RealType, Policy>& dist)
Chris@16 318 {
Chris@16 319 RealType p = dist.success_fraction();
Chris@16 320 return 1 / (1 - p) + 1/p -6 + 3;
Chris@16 321 // Simpler than:
Chris@16 322 // return (6 * p * p - 6 * p + 1) / (p * (1 - p)) + 3;
Chris@16 323 }
Chris@16 324
Chris@16 325 } // namespace math
Chris@16 326 } // namespace boost
Chris@16 327
Chris@16 328 // This include must be at the end, *after* the accessors
Chris@16 329 // for this distribution have been defined, in order to
Chris@16 330 // keep compilers that support two-phase lookup happy.
Chris@16 331 #include <boost/math/distributions/detail/derived_accessors.hpp>
Chris@16 332
Chris@16 333 #endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP
Chris@16 334
Chris@16 335
Chris@16 336