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