File indexing completed on 2025-09-17 08:35:23
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 #ifndef BOOST_MATH_DIST_BETA_HPP
0026 #define BOOST_MATH_DIST_BETA_HPP
0027
0028 #include <boost/math/tools/config.hpp>
0029 #include <boost/math/tools/tuple.hpp>
0030 #include <boost/math/distributions/fwd.hpp>
0031 #include <boost/math/special_functions/beta.hpp> // for beta.
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 #include <boost/math/tools/roots.hpp> // for root finding.
0036 #include <boost/math/policies/error_handling.hpp>
0037
0038 #if defined (BOOST_MSVC)
0039 # pragma warning(push)
0040 # pragma warning(disable: 4702)
0041
0042 #endif
0043
0044 namespace boost
0045 {
0046 namespace math
0047 {
0048 namespace beta_detail
0049 {
0050
0051 template <class RealType, class Policy>
0052 BOOST_MATH_GPU_ENABLED inline bool check_alpha(const char* function, const RealType& alpha, RealType* result, const Policy& pol)
0053 {
0054 if(!(boost::math::isfinite)(alpha) || (alpha <= 0))
0055 {
0056 *result = policies::raise_domain_error<RealType>(
0057 function,
0058 "Alpha argument is %1%, but must be > 0 !", alpha, pol);
0059 return false;
0060 }
0061 return true;
0062 }
0063
0064 template <class RealType, class Policy>
0065 BOOST_MATH_GPU_ENABLED inline bool check_beta(const char* function, const RealType& beta, RealType* result, const Policy& pol)
0066 {
0067 if(!(boost::math::isfinite)(beta) || (beta <= 0))
0068 {
0069 *result = policies::raise_domain_error<RealType>(
0070 function,
0071 "Beta argument is %1%, but must be > 0 !", beta, pol);
0072 return false;
0073 }
0074 return true;
0075 }
0076
0077 template <class RealType, class Policy>
0078 BOOST_MATH_GPU_ENABLED inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol)
0079 {
0080 if((p < 0) || (p > 1) || !(boost::math::isfinite)(p))
0081 {
0082 *result = policies::raise_domain_error<RealType>(
0083 function,
0084 "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
0085 return false;
0086 }
0087 return true;
0088 }
0089
0090 template <class RealType, class Policy>
0091 BOOST_MATH_GPU_ENABLED inline bool check_x(const char* function, const RealType& x, RealType* result, const Policy& pol)
0092 {
0093 if(!(boost::math::isfinite)(x) || (x < 0) || (x > 1))
0094 {
0095 *result = policies::raise_domain_error<RealType>(
0096 function,
0097 "x argument is %1%, but must be >= 0 and <= 1 !", x, pol);
0098 return false;
0099 }
0100 return true;
0101 }
0102
0103 template <class RealType, class Policy>
0104 BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& alpha, const RealType& beta, RealType* result, const Policy& pol)
0105 {
0106 return check_alpha(function, alpha, result, pol)
0107 && check_beta(function, beta, result, pol);
0108 }
0109
0110 template <class RealType, class Policy>
0111 BOOST_MATH_GPU_ENABLED inline bool check_dist_and_x(const char* function, const RealType& alpha, const RealType& beta, RealType x, RealType* result, const Policy& pol)
0112 {
0113 return check_dist(function, alpha, beta, result, pol)
0114 && beta_detail::check_x(function, x, result, pol);
0115 }
0116
0117 template <class RealType, class Policy>
0118 BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, const RealType& alpha, const RealType& beta, RealType p, RealType* result, const Policy& pol)
0119 {
0120 return check_dist(function, alpha, beta, result, pol)
0121 && check_prob(function, p, result, pol);
0122 }
0123
0124 template <class RealType, class Policy>
0125 BOOST_MATH_GPU_ENABLED inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol)
0126 {
0127 if(!(boost::math::isfinite)(mean) || (mean <= 0))
0128 {
0129 *result = policies::raise_domain_error<RealType>(
0130 function,
0131 "mean argument is %1%, but must be > 0 !", mean, pol);
0132 return false;
0133 }
0134 return true;
0135 }
0136 template <class RealType, class Policy>
0137 BOOST_MATH_GPU_ENABLED inline bool check_variance(const char* function, const RealType& variance, RealType* result, const Policy& pol)
0138 {
0139 if(!(boost::math::isfinite)(variance) || (variance <= 0))
0140 {
0141 *result = policies::raise_domain_error<RealType>(
0142 function,
0143 "variance argument is %1%, but must be > 0 !", variance, pol);
0144 return false;
0145 }
0146 return true;
0147 }
0148 }
0149
0150
0151
0152
0153
0154 template <class RealType = double, class Policy = policies::policy<> >
0155 class beta_distribution
0156 {
0157 public:
0158 typedef RealType value_type;
0159 typedef Policy policy_type;
0160
0161 BOOST_MATH_GPU_ENABLED beta_distribution(RealType l_alpha = 1, RealType l_beta = 1) : m_alpha(l_alpha), m_beta(l_beta)
0162 {
0163 RealType result;
0164 beta_detail::check_dist(
0165 "boost::math::beta_distribution<%1%>::beta_distribution",
0166 m_alpha,
0167 m_beta,
0168 &result, Policy());
0169 }
0170
0171 BOOST_MATH_GPU_ENABLED RealType alpha() const
0172 {
0173 return m_alpha;
0174 }
0175 BOOST_MATH_GPU_ENABLED RealType beta() const
0176 {
0177 return m_beta;
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187 BOOST_MATH_GPU_ENABLED static RealType find_alpha(
0188 RealType mean,
0189 RealType variance)
0190 {
0191 constexpr auto function = "boost::math::beta_distribution<%1%>::find_alpha";
0192 RealType result = 0;
0193 if(false ==
0194 (
0195 beta_detail::check_mean(function, mean, &result, Policy())
0196 && beta_detail::check_variance(function, variance, &result, Policy())
0197 )
0198 )
0199 {
0200 return result;
0201 }
0202 return mean * (( (mean * (1 - mean)) / variance)- 1);
0203 }
0204
0205 BOOST_MATH_GPU_ENABLED static RealType find_beta(
0206 RealType mean,
0207 RealType variance)
0208 {
0209 constexpr auto function = "boost::math::beta_distribution<%1%>::find_beta";
0210 RealType result = 0;
0211 if(false ==
0212 (
0213 beta_detail::check_mean(function, mean, &result, Policy())
0214 &&
0215 beta_detail::check_variance(function, variance, &result, Policy())
0216 )
0217 )
0218 {
0219 return result;
0220 }
0221 return (1 - mean) * (((mean * (1 - mean)) /variance)-1);
0222 }
0223
0224
0225
0226
0227 BOOST_MATH_GPU_ENABLED static RealType find_alpha(
0228 RealType beta,
0229 RealType x,
0230 RealType probability)
0231 {
0232 constexpr auto function = "boost::math::beta_distribution<%1%>::find_alpha";
0233 RealType result = 0;
0234 if(false ==
0235 (
0236 beta_detail::check_prob(function, probability, &result, Policy())
0237 &&
0238 beta_detail::check_beta(function, beta, &result, Policy())
0239 &&
0240 beta_detail::check_x(function, x, &result, Policy())
0241 )
0242 )
0243 {
0244 return result;
0245 }
0246 return static_cast<RealType>(ibeta_inva(beta, x, probability, Policy()));
0247 }
0248
0249 BOOST_MATH_GPU_ENABLED static RealType find_beta(
0250
0251 RealType alpha,
0252 RealType x,
0253 RealType probability)
0254 {
0255 constexpr auto function = "boost::math::beta_distribution<%1%>::find_beta";
0256 RealType result = 0;
0257 if(false ==
0258 (
0259 beta_detail::check_prob(function, probability, &result, Policy())
0260 &&
0261 beta_detail::check_alpha(function, alpha, &result, Policy())
0262 &&
0263 beta_detail::check_x(function, x, &result, Policy())
0264 )
0265 )
0266 {
0267 return result;
0268 }
0269 return static_cast<RealType>(ibeta_invb(alpha, x, probability, Policy()));
0270 }
0271
0272 private:
0273 RealType m_alpha;
0274 RealType m_beta;
0275 };
0276
0277 #ifdef __cpp_deduction_guides
0278 template <class RealType>
0279 beta_distribution(RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0280 template <class RealType>
0281 beta_distribution(RealType, RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0282 #endif
0283
0284 template <class RealType, class Policy>
0285 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const beta_distribution<RealType, Policy>& )
0286 {
0287 using boost::math::tools::max_value;
0288 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0289 }
0290
0291 template <class RealType, class Policy>
0292 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const beta_distribution<RealType, Policy>& )
0293 {
0294
0295 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
0296 }
0297
0298 template <class RealType, class Policy>
0299 BOOST_MATH_GPU_ENABLED inline RealType mean(const beta_distribution<RealType, Policy>& dist)
0300 {
0301 return dist.alpha() / (dist.alpha() + dist.beta());
0302 }
0303
0304 template <class RealType, class Policy>
0305 BOOST_MATH_GPU_ENABLED inline RealType variance(const beta_distribution<RealType, Policy>& dist)
0306 {
0307 RealType a = dist.alpha();
0308 RealType b = dist.beta();
0309 return (a * b) / ((a + b ) * (a + b) * (a + b + 1));
0310 }
0311
0312 template <class RealType, class Policy>
0313 BOOST_MATH_GPU_ENABLED inline RealType mode(const beta_distribution<RealType, Policy>& dist)
0314 {
0315 constexpr auto function = "boost::math::mode(beta_distribution<%1%> const&)";
0316
0317 RealType result;
0318 if ((dist.alpha() <= 1))
0319 {
0320 result = policies::raise_domain_error<RealType>(
0321 function,
0322 "mode undefined for alpha = %1%, must be > 1!", dist.alpha(), Policy());
0323 return result;
0324 }
0325
0326 if ((dist.beta() <= 1))
0327 {
0328 result = policies::raise_domain_error<RealType>(
0329 function,
0330 "mode undefined for beta = %1%, must be > 1!", dist.beta(), Policy());
0331 return result;
0332 }
0333 RealType a = dist.alpha();
0334 RealType b = dist.beta();
0335 return (a-1) / (a + b - 2);
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 template <class RealType, class Policy>
0347 BOOST_MATH_GPU_ENABLED inline RealType skewness(const beta_distribution<RealType, Policy>& dist)
0348 {
0349 BOOST_MATH_STD_USING
0350 RealType a = dist.alpha();
0351 RealType b = dist.beta();
0352 return (2 * (b-a) * sqrt(a + b + 1)) / ((a + b + 2) * sqrt(a * b));
0353 }
0354
0355 template <class RealType, class Policy>
0356 BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const beta_distribution<RealType, Policy>& dist)
0357 {
0358 RealType a = dist.alpha();
0359 RealType b = dist.beta();
0360 RealType a_2 = a * a;
0361 RealType n = 6 * (a_2 * a - a_2 * (2 * b - 1) + b * b * (b + 1) - 2 * a * b * (b + 2));
0362 RealType d = a * b * (a + b + 2) * (a + b + 3);
0363 return n / d;
0364 }
0365
0366 template <class RealType, class Policy>
0367 BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const beta_distribution<RealType, Policy>& dist)
0368 {
0369 return 3 + kurtosis_excess(dist);
0370 }
0371
0372 template <class RealType, class Policy>
0373 BOOST_MATH_GPU_ENABLED inline RealType pdf(const beta_distribution<RealType, Policy>& dist, const RealType& x)
0374 {
0375 BOOST_FPU_EXCEPTION_GUARD
0376
0377 constexpr auto function = "boost::math::pdf(beta_distribution<%1%> const&, %1%)";
0378
0379 BOOST_MATH_STD_USING
0380
0381 RealType a = dist.alpha();
0382 RealType b = dist.beta();
0383
0384
0385 RealType result = 0;
0386 if(false == beta_detail::check_dist_and_x(
0387 function,
0388 a, b, x,
0389 &result, Policy()))
0390 {
0391 return result;
0392 }
0393 using boost::math::beta;
0394
0395
0396
0397 if(x == 0)
0398 {
0399 if (a == 1)
0400 {
0401 return static_cast<RealType>(1 / beta(a, b));
0402 }
0403 else if (a < 1)
0404 {
0405 policies::raise_overflow_error<RealType>(function, nullptr, Policy());
0406 }
0407 else
0408 {
0409 return RealType(0);
0410 }
0411 }
0412 else if (x == 1)
0413 {
0414 if (b == 1)
0415 {
0416 return static_cast<RealType>(1 / beta(a, b));
0417 }
0418 else if (b < 1)
0419 {
0420 policies::raise_overflow_error<RealType>(function, nullptr, Policy());
0421 }
0422 else
0423 {
0424 return RealType(0);
0425 }
0426 }
0427
0428 return static_cast<RealType>(ibeta_derivative(a, b, x, Policy()));
0429 }
0430
0431 template <class RealType, class Policy>
0432 BOOST_MATH_GPU_ENABLED inline RealType cdf(const beta_distribution<RealType, Policy>& dist, const RealType& x)
0433 {
0434 BOOST_MATH_STD_USING
0435
0436 constexpr auto function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)";
0437
0438 RealType a = dist.alpha();
0439 RealType b = dist.beta();
0440
0441
0442 RealType result = 0;
0443 if(false == beta_detail::check_dist_and_x(
0444 function,
0445 a, b, x,
0446 &result, Policy()))
0447 {
0448 return result;
0449 }
0450
0451 if (x == 0)
0452 {
0453 return 0;
0454 }
0455 else if (x == 1)
0456 {
0457 return 1;
0458 }
0459 return static_cast<RealType>(ibeta(a, b, x, Policy()));
0460 }
0461
0462 template <class RealType, class Policy>
0463 BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<beta_distribution<RealType, Policy>, RealType>& c)
0464 {
0465
0466 BOOST_MATH_STD_USING
0467
0468 constexpr auto function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)";
0469
0470 RealType const& x = c.param;
0471 beta_distribution<RealType, Policy> const& dist = c.dist;
0472 RealType a = dist.alpha();
0473 RealType b = dist.beta();
0474
0475
0476 RealType result = 0;
0477 if(false == beta_detail::check_dist_and_x(
0478 function,
0479 a, b, x,
0480 &result, Policy()))
0481 {
0482 return result;
0483 }
0484 if (x == 0)
0485 {
0486 return RealType(1);
0487 }
0488 else if (x == 1)
0489 {
0490 return RealType(0);
0491 }
0492
0493
0494
0495 return static_cast<RealType>(ibetac(a, b, x, Policy()));
0496 }
0497
0498 template <class RealType, class Policy>
0499 BOOST_MATH_GPU_ENABLED inline RealType quantile(const beta_distribution<RealType, Policy>& dist, const RealType& p)
0500 {
0501
0502
0503
0504
0505
0506
0507
0508
0509 constexpr auto function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)";
0510
0511 RealType result = 0;
0512 RealType a = dist.alpha();
0513 RealType b = dist.beta();
0514 if(false == beta_detail::check_dist_and_prob(
0515 function,
0516 a, b, p,
0517 &result, Policy()))
0518 {
0519 return result;
0520 }
0521
0522 if (p == 0)
0523 {
0524 return RealType(0);
0525 }
0526 if (p == 1)
0527 {
0528 return RealType(1);
0529 }
0530 return static_cast<RealType>(ibeta_inv(a, b, p, static_cast<RealType*>(nullptr), Policy()));
0531 }
0532
0533 template <class RealType, class Policy>
0534 BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<beta_distribution<RealType, Policy>, RealType>& c)
0535 {
0536
0537
0538
0539 constexpr auto function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)";
0540
0541
0542
0543 RealType q = c.param;
0544 const beta_distribution<RealType, Policy>& dist = c.dist;
0545 RealType result = 0;
0546 RealType a = dist.alpha();
0547 RealType b = dist.beta();
0548 if(false == beta_detail::check_dist_and_prob(
0549 function,
0550 a,
0551 b,
0552 q,
0553 &result, Policy()))
0554 {
0555 return result;
0556 }
0557
0558 if(q == 1)
0559 {
0560 return RealType(0);
0561 }
0562 if(q == 0)
0563 {
0564 return RealType(1);
0565 }
0566
0567 return static_cast<RealType>(ibetac_inv(a, b, q, static_cast<RealType*>(nullptr), Policy()));
0568 }
0569
0570 }
0571 }
0572
0573
0574
0575
0576 #include <boost/math/distributions/detail/derived_accessors.hpp>
0577
0578 #if defined (BOOST_MSVC)
0579 # pragma warning(pop)
0580 #endif
0581
0582 #endif
0583
0584