File indexing completed on 2025-01-18 09:39:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
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
0045 template <class RealType, class Policy>
0046 inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& )
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& , 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& , 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& )
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& )
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 }
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 {
0110
0111 RealType result;
0112 bernoulli_detail::check_dist(
0113 "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution",
0114 m_p,
0115 &result, Policy());
0116 }
0117
0118 RealType success_fraction() const
0119 {
0120 return m_p;
0121 }
0122
0123 private:
0124 RealType m_p;
0125 };
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>& )
0136 {
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>& )
0143 {
0144
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 {
0151 return dist.success_fraction();
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161 template <class RealType, class Policy>
0162 inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
0163 {
0164 return dist.success_fraction() * (1 - dist.success_fraction());
0165 }
0166
0167 template <class RealType, class Policy>
0168 RealType pdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0169 {
0170 BOOST_FPU_EXCEPTION_GUARD
0171
0172 RealType result = 0;
0173 if(false == bernoulli_detail::check_dist_and_k(
0174 "boost::math::pdf(bernoulli_distribution<%1%>, %1%)",
0175 dist.success_fraction(),
0176 k,
0177 &result, Policy()))
0178 {
0179 return result;
0180 }
0181
0182 if (k == 0)
0183 {
0184 return 1 - dist.success_fraction();
0185 }
0186 else
0187 {
0188 return dist.success_fraction();
0189 }
0190 }
0191
0192 template <class RealType, class Policy>
0193 inline RealType cdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0194 {
0195 RealType p = dist.success_fraction();
0196
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 {
0212 return 1;
0213 }
0214 }
0215
0216 template <class RealType, class Policy>
0217 inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0218 {
0219 RealType const& k = c.param;
0220 bernoulli_distribution<RealType, Policy> const& dist = c.dist;
0221 RealType p = dist.success_fraction();
0222
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 {
0238 return 0;
0239 }
0240 }
0241
0242 template <class RealType, class Policy>
0243 inline RealType quantile(const bernoulli_distribution<RealType, Policy>& dist, const RealType& p)
0244 {
0245
0246
0247
0248 RealType result = 0;
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 {
0259 return 0;
0260 }
0261 else
0262 {
0263 return 1;
0264 }
0265 }
0266
0267 template <class RealType, class Policy>
0268 inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0269 {
0270
0271
0272
0273
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 {
0288 return 1;
0289 }
0290 else
0291 {
0292 return 0;
0293 }
0294 }
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);
0300 }
0301
0302 template <class RealType, class Policy>
0303 inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
0304 {
0305 BOOST_MATH_STD_USING;
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
0315
0316
0317
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
0327
0328 }
0329
0330 }
0331 }
0332
0333
0334
0335
0336 #include <boost/math/distributions/detail/derived_accessors.hpp>
0337
0338 #endif
0339
0340
0341