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