File indexing completed on 2025-10-15 08:37:04
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
0028 #ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP
0029 #define BOOST_MATH_SPECIAL_BERNOULLI_HPP
0030
0031 #include <boost/math/tools/config.hpp>
0032 #include <boost/math/tools/tuple.hpp>
0033 #include <boost/math/tools/type_traits.hpp>
0034 #include <boost/math/distributions/complement.hpp> // complements
0035 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
0036 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
0037 #include <boost/math/policies/policy.hpp>
0038 #include <boost/math/policies/error_handling.hpp>
0039
0040 #ifndef BOOST_MATH_HAS_NVRTC
0041 #include <utility>
0042 #include <boost/math/distributions/fwd.hpp>
0043 #endif
0044
0045 namespace boost
0046 {
0047 namespace math
0048 {
0049 namespace bernoulli_detail
0050 {
0051
0052 template <class RealType, class Policy>
0053 BOOST_MATH_GPU_ENABLED inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& )
0054 {
0055 if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
0056 {
0057 *result = policies::raise_domain_error<RealType>(
0058 function,
0059 "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy());
0060 return false;
0061 }
0062 return true;
0063 }
0064 template <class RealType, class Policy>
0065 BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& , const boost::math::true_type&)
0066 {
0067 return check_success_fraction(function, p, result, Policy());
0068 }
0069 template <class RealType, class Policy>
0070 BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* , const RealType& , RealType* , const Policy& , const boost::math::false_type&)
0071 {
0072 return true;
0073 }
0074 template <class RealType, class Policy>
0075 BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& )
0076 {
0077 return check_dist(function, p, result, Policy(), typename policies::constructor_error_check<Policy>::type());
0078 }
0079
0080 template <class RealType, class Policy>
0081 BOOST_MATH_GPU_ENABLED inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol)
0082 {
0083 if(check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) == false)
0084 {
0085 return false;
0086 }
0087 if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1)))
0088 {
0089 *result = policies::raise_domain_error<RealType>(
0090 function,
0091 "Number of successes argument is %1%, but must be 0 or 1 !", k, pol);
0092 return false;
0093 }
0094 return true;
0095 }
0096 template <class RealType, class Policy>
0097 BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& )
0098 {
0099 if((check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) && detail::check_probability(function, prob, result, Policy())) == false)
0100 {
0101 return false;
0102 }
0103 return true;
0104 }
0105 }
0106
0107
0108 template <class RealType = double, class Policy = policies::policy<> >
0109 class bernoulli_distribution
0110 {
0111 public:
0112 typedef RealType value_type;
0113 typedef Policy policy_type;
0114
0115 BOOST_MATH_GPU_ENABLED bernoulli_distribution(RealType p = 0.5) : m_p(p)
0116 {
0117
0118 RealType result;
0119 bernoulli_detail::check_dist(
0120 "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution",
0121 m_p,
0122 &result, Policy());
0123 }
0124
0125 BOOST_MATH_GPU_ENABLED RealType success_fraction() const
0126 {
0127 return m_p;
0128 }
0129
0130 private:
0131 RealType m_p;
0132 };
0133
0134 typedef bernoulli_distribution<double> bernoulli;
0135
0136 #ifdef __cpp_deduction_guides
0137 template <class RealType>
0138 bernoulli_distribution(RealType)->bernoulli_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0139 #endif
0140
0141 template <class RealType, class Policy>
0142 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const bernoulli_distribution<RealType, Policy>& )
0143 {
0144 using boost::math::tools::max_value;
0145 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0146 }
0147
0148 template <class RealType, class Policy>
0149 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const bernoulli_distribution<RealType, Policy>& )
0150 {
0151
0152 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0153 }
0154
0155 template <class RealType, class Policy>
0156 BOOST_MATH_GPU_ENABLED inline RealType mean(const bernoulli_distribution<RealType, Policy>& dist)
0157 {
0158 return dist.success_fraction();
0159 }
0160
0161
0162
0163
0164
0165
0166
0167
0168 template <class RealType, class Policy>
0169 BOOST_MATH_GPU_ENABLED inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
0170 {
0171 return dist.success_fraction() * (1 - dist.success_fraction());
0172 }
0173
0174 template <class RealType, class Policy>
0175 BOOST_MATH_GPU_ENABLED RealType pdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0176 {
0177 BOOST_FPU_EXCEPTION_GUARD
0178
0179 RealType result = 0;
0180 if(false == bernoulli_detail::check_dist_and_k(
0181 "boost::math::pdf(bernoulli_distribution<%1%>, %1%)",
0182 dist.success_fraction(),
0183 k,
0184 &result, Policy()))
0185 {
0186 return result;
0187 }
0188
0189 if (k == 0)
0190 {
0191 return 1 - dist.success_fraction();
0192 }
0193 else
0194 {
0195 return dist.success_fraction();
0196 }
0197 }
0198
0199 template <class RealType, class Policy>
0200 BOOST_MATH_GPU_ENABLED inline RealType cdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
0201 {
0202 RealType p = dist.success_fraction();
0203
0204 RealType result = 0;
0205 if(false == bernoulli_detail::check_dist_and_k(
0206 "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
0207 p,
0208 k,
0209 &result, Policy()))
0210 {
0211 return result;
0212 }
0213 if (k == 0)
0214 {
0215 return 1 - p;
0216 }
0217 else
0218 {
0219 return 1;
0220 }
0221 }
0222
0223 template <class RealType, class Policy>
0224 BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0225 {
0226 RealType const& k = c.param;
0227 bernoulli_distribution<RealType, Policy> const& dist = c.dist;
0228 RealType p = dist.success_fraction();
0229
0230 RealType result = 0;
0231 if(false == bernoulli_detail::check_dist_and_k(
0232 "boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
0233 p,
0234 k,
0235 &result, Policy()))
0236 {
0237 return result;
0238 }
0239 if (k == 0)
0240 {
0241 return p;
0242 }
0243 else
0244 {
0245 return 0;
0246 }
0247 }
0248
0249 template <class RealType, class Policy>
0250 BOOST_MATH_GPU_ENABLED inline RealType quantile(const bernoulli_distribution<RealType, Policy>& dist, const RealType& p)
0251 {
0252
0253
0254
0255 RealType result = 0;
0256 if(false == bernoulli_detail::check_dist_and_prob(
0257 "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
0258 dist.success_fraction(),
0259 p,
0260 &result, Policy()))
0261 {
0262 return result;
0263 }
0264 if (p <= (1 - dist.success_fraction()))
0265 {
0266 return 0;
0267 }
0268 else
0269 {
0270 return 1;
0271 }
0272 }
0273
0274 template <class RealType, class Policy>
0275 BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
0276 {
0277
0278
0279
0280
0281 RealType q = c.param;
0282 const bernoulli_distribution<RealType, Policy>& dist = c.dist;
0283 RealType result = 0;
0284 if(false == bernoulli_detail::check_dist_and_prob(
0285 "boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
0286 dist.success_fraction(),
0287 q,
0288 &result, Policy()))
0289 {
0290 return result;
0291 }
0292
0293 if (q <= 1 - dist.success_fraction())
0294 {
0295 return 1;
0296 }
0297 else
0298 {
0299 return 0;
0300 }
0301 }
0302
0303 template <class RealType, class Policy>
0304 BOOST_MATH_GPU_ENABLED inline RealType mode(const bernoulli_distribution<RealType, Policy>& dist)
0305 {
0306 return static_cast<RealType>((dist.success_fraction() <= 0.5) ? 0 : 1);
0307 }
0308
0309 template <class RealType, class Policy>
0310 BOOST_MATH_GPU_ENABLED inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
0311 {
0312 BOOST_MATH_STD_USING;
0313 RealType p = dist.success_fraction();
0314 return (1 - 2 * p) / sqrt(p * (1 - p));
0315 }
0316
0317 template <class RealType, class Policy>
0318 BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const bernoulli_distribution<RealType, Policy>& dist)
0319 {
0320 RealType p = dist.success_fraction();
0321
0322
0323
0324
0325 return 1 / (1 - p) + 1/p -6;
0326 }
0327
0328 template <class RealType, class Policy>
0329 BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const bernoulli_distribution<RealType, Policy>& dist)
0330 {
0331 RealType p = dist.success_fraction();
0332 return 1 / (1 - p) + 1/p -6 + 3;
0333
0334
0335 }
0336
0337 }
0338 }
0339
0340
0341
0342
0343 #include <boost/math/distributions/detail/derived_accessors.hpp>
0344
0345 #endif
0346
0347
0348