File indexing completed on 2025-09-17 08:35:33
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_STATS_PARETO_HPP
0009 #define BOOST_STATS_PARETO_HPP
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <boost/math/tools/config.hpp>
0021 #include <boost/math/tools/tuple.hpp>
0022 #include <boost/math/tools/numeric_limits.hpp>
0023 #include <boost/math/distributions/fwd.hpp>
0024 #include <boost/math/distributions/complement.hpp>
0025 #include <boost/math/distributions/detail/common_error_handling.hpp>
0026 #include <boost/math/special_functions/powm1.hpp>
0027 #include <boost/math/special_functions/log1p.hpp>
0028
0029 namespace boost
0030 {
0031 namespace math
0032 {
0033 namespace detail
0034 {
0035 template <class RealType, class Policy>
0036 BOOST_MATH_GPU_ENABLED inline bool check_pareto_scale(
0037 const char* function,
0038 RealType scale,
0039 RealType* result, const Policy& pol)
0040 {
0041 if((boost::math::isfinite)(scale))
0042 {
0043 if (scale > 0)
0044 {
0045 return true;
0046 }
0047 else
0048 {
0049 *result = policies::raise_domain_error<RealType>(
0050 function,
0051 "Scale parameter is %1%, but must be > 0!", scale, pol);
0052 return false;
0053 }
0054 }
0055 else
0056 {
0057 *result = policies::raise_domain_error<RealType>(
0058 function,
0059 "Scale parameter is %1%, but must be finite!", scale, pol);
0060 return false;
0061 }
0062 }
0063
0064 template <class RealType, class Policy>
0065 BOOST_MATH_GPU_ENABLED inline bool check_pareto_shape(
0066 const char* function,
0067 RealType shape,
0068 RealType* result, const Policy& pol)
0069 {
0070 if((boost::math::isfinite)(shape))
0071 {
0072 if (shape > 0)
0073 {
0074 return true;
0075 }
0076 else
0077 {
0078 *result = policies::raise_domain_error<RealType>(
0079 function,
0080 "Shape parameter is %1%, but must be > 0!", shape, pol);
0081 return false;
0082 }
0083 }
0084 else
0085 {
0086 *result = policies::raise_domain_error<RealType>(
0087 function,
0088 "Shape parameter is %1%, but must be finite!", shape, pol);
0089 return false;
0090 }
0091 }
0092
0093 template <class RealType, class Policy>
0094 BOOST_MATH_GPU_ENABLED inline bool check_pareto_x(
0095 const char* function,
0096 RealType const& x,
0097 RealType* result, const Policy& pol)
0098 {
0099 if((boost::math::isfinite)(x))
0100 {
0101 if (x > 0)
0102 {
0103 return true;
0104 }
0105 else
0106 {
0107 *result = policies::raise_domain_error<RealType>(
0108 function,
0109 "x parameter is %1%, but must be > 0 !", x, pol);
0110 return false;
0111 }
0112 }
0113 else
0114 {
0115 *result = policies::raise_domain_error<RealType>(
0116 function,
0117 "x parameter is %1%, but must be finite!", x, pol);
0118 return false;
0119 }
0120 }
0121
0122 template <class RealType, class Policy>
0123 BOOST_MATH_GPU_ENABLED inline bool check_pareto(
0124 const char* function,
0125 RealType scale,
0126 RealType shape,
0127 RealType* result, const Policy& pol)
0128 {
0129 return check_pareto_scale(function, scale, result, pol)
0130 && check_pareto_shape(function, shape, result, pol);
0131 }
0132
0133 }
0134
0135 template <class RealType = double, class Policy = policies::policy<> >
0136 class pareto_distribution
0137 {
0138 public:
0139 typedef RealType value_type;
0140 typedef Policy policy_type;
0141
0142 BOOST_MATH_GPU_ENABLED pareto_distribution(RealType l_scale = 1, RealType l_shape = 1)
0143 : m_scale(l_scale), m_shape(l_shape)
0144 {
0145 RealType result = 0;
0146 detail::check_pareto("boost::math::pareto_distribution<%1%>::pareto_distribution", l_scale, l_shape, &result, Policy());
0147 }
0148
0149 BOOST_MATH_GPU_ENABLED RealType scale()const
0150 {
0151 return m_scale;
0152 }
0153
0154 BOOST_MATH_GPU_ENABLED RealType shape()const
0155 {
0156 return m_shape;
0157 }
0158 private:
0159
0160 RealType m_scale;
0161 RealType m_shape;
0162 };
0163
0164 typedef pareto_distribution<double> pareto;
0165
0166 #ifdef __cpp_deduction_guides
0167 template <class RealType>
0168 pareto_distribution(RealType)->pareto_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0169 template <class RealType>
0170 pareto_distribution(RealType,RealType)->pareto_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0171 #endif
0172
0173
0174 template <class RealType, class Policy>
0175 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const pareto_distribution<RealType, Policy>& )
0176 {
0177 using boost::math::tools::max_value;
0178 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
0179 }
0180
0181 template <class RealType, class Policy>
0182 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const pareto_distribution<RealType, Policy>& dist)
0183 {
0184
0185 using boost::math::tools::max_value;
0186 return boost::math::pair<RealType, RealType>(dist.scale(), max_value<RealType>() );
0187 }
0188
0189 template <class RealType, class Policy>
0190 BOOST_MATH_GPU_ENABLED inline RealType pdf(const pareto_distribution<RealType, Policy>& dist, const RealType& x)
0191 {
0192 BOOST_MATH_STD_USING
0193 constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
0194 RealType scale = dist.scale();
0195 RealType shape = dist.shape();
0196 RealType result = 0;
0197 if(false == (detail::check_pareto_x(function, x, &result, Policy())
0198 && detail::check_pareto(function, scale, shape, &result, Policy())))
0199 return result;
0200 if (x < scale)
0201 {
0202 return 0;
0203 }
0204 result = shape * pow(scale, shape) / pow(x, shape+1);
0205 return result;
0206 }
0207
0208 template <class RealType, class Policy>
0209 BOOST_MATH_GPU_ENABLED inline RealType cdf(const pareto_distribution<RealType, Policy>& dist, const RealType& x)
0210 {
0211 BOOST_MATH_STD_USING
0212 constexpr auto function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)";
0213 RealType scale = dist.scale();
0214 RealType shape = dist.shape();
0215 RealType result = 0;
0216
0217 if(false == (detail::check_pareto_x(function, x, &result, Policy())
0218 && detail::check_pareto(function, scale, shape, &result, Policy())))
0219 return result;
0220
0221 if (x <= scale)
0222 {
0223 return 0;
0224 }
0225
0226
0227 result = -boost::math::powm1(scale/x, shape, Policy());
0228 return result;
0229 }
0230
0231 template <class RealType, class Policy>
0232 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const pareto_distribution<RealType, Policy>& dist, const RealType& x)
0233 {
0234 BOOST_MATH_STD_USING
0235 constexpr auto function = "boost::math::logcdf(const pareto_distribution<%1%>&, %1%)";
0236 RealType scale = dist.scale();
0237 RealType shape = dist.shape();
0238 RealType result = 0;
0239
0240 if(false == (detail::check_pareto_x(function, x, &result, Policy())
0241 && detail::check_pareto(function, scale, shape, &result, Policy())))
0242 return result;
0243
0244 if (x <= scale)
0245 {
0246 return -boost::math::numeric_limits<RealType>::infinity();
0247 }
0248
0249 result = log1p(-pow(scale/x, shape), Policy());
0250 return result;
0251 }
0252
0253 template <class RealType, class Policy>
0254 BOOST_MATH_GPU_ENABLED inline RealType quantile(const pareto_distribution<RealType, Policy>& dist, const RealType& p)
0255 {
0256 BOOST_MATH_STD_USING
0257 constexpr auto function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)";
0258 RealType result = 0;
0259 RealType scale = dist.scale();
0260 RealType shape = dist.shape();
0261 if(false == (detail::check_probability(function, p, &result, Policy())
0262 && detail::check_pareto(function, scale, shape, &result, Policy())))
0263 {
0264 return result;
0265 }
0266 if (p == 0)
0267 {
0268 return scale;
0269 }
0270 if (p == 1)
0271 {
0272 return policies::raise_overflow_error<RealType>(function, 0, Policy());
0273 }
0274 result = scale /
0275 (pow((1 - p), 1 / shape));
0276
0277 return result;
0278 }
0279
0280 template <class RealType, class Policy>
0281 BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
0282 {
0283 BOOST_MATH_STD_USING
0284 constexpr auto function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)";
0285 RealType result = 0;
0286 RealType x = c.param;
0287 RealType scale = c.dist.scale();
0288 RealType shape = c.dist.shape();
0289 if(false == (detail::check_pareto_x(function, x, &result, Policy())
0290 && detail::check_pareto(function, scale, shape, &result, Policy())))
0291 return result;
0292
0293 if (x <= scale)
0294 {
0295 return 1;
0296 }
0297 result = pow((scale/x), shape);
0298
0299 return result;
0300 }
0301
0302 template <class RealType, class Policy>
0303 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
0304 {
0305 BOOST_MATH_STD_USING
0306 constexpr auto function = "boost::math::logcdf(const pareto_distribution<%1%>&, %1%)";
0307 RealType result = 0;
0308 RealType x = c.param;
0309 RealType scale = c.dist.scale();
0310 RealType shape = c.dist.shape();
0311 if(false == (detail::check_pareto_x(function, x, &result, Policy())
0312 && detail::check_pareto(function, scale, shape, &result, Policy())))
0313 return result;
0314
0315 if (x <= scale)
0316 {
0317 return 0;
0318 }
0319 result = log(pow((scale/x), shape));
0320
0321 return result;
0322 }
0323
0324 template <class RealType, class Policy>
0325 BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
0326 {
0327 BOOST_MATH_STD_USING
0328 constexpr auto function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)";
0329 RealType result = 0;
0330 RealType q = c.param;
0331 RealType scale = c.dist.scale();
0332 RealType shape = c.dist.shape();
0333 if(false == (detail::check_probability(function, q, &result, Policy())
0334 && detail::check_pareto(function, scale, shape, &result, Policy())))
0335 {
0336 return result;
0337 }
0338 if (q == 1)
0339 {
0340 return scale;
0341 }
0342 if (q == 0)
0343 {
0344 return policies::raise_overflow_error<RealType>(function, 0, Policy());
0345 }
0346 result = scale / (pow(q, 1 / shape));
0347
0348 return result;
0349 }
0350
0351 template <class RealType, class Policy>
0352 BOOST_MATH_GPU_ENABLED inline RealType mean(const pareto_distribution<RealType, Policy>& dist)
0353 {
0354 RealType result = 0;
0355 constexpr auto function = "boost::math::mean(const pareto_distribution<%1%>&, %1%)";
0356 if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy()))
0357 {
0358 return result;
0359 }
0360 if (dist.shape() > RealType(1))
0361 {
0362 return dist.shape() * dist.scale() / (dist.shape() - 1);
0363 }
0364 else
0365 {
0366 using boost::math::tools::max_value;
0367 return max_value<RealType>();
0368 }
0369 }
0370
0371 template <class RealType, class Policy>
0372 BOOST_MATH_GPU_ENABLED inline RealType mode(const pareto_distribution<RealType, Policy>& dist)
0373 {
0374 return dist.scale();
0375 }
0376
0377 template <class RealType, class Policy>
0378 BOOST_MATH_GPU_ENABLED inline RealType median(const pareto_distribution<RealType, Policy>& dist)
0379 {
0380 RealType result = 0;
0381 constexpr auto function = "boost::math::median(const pareto_distribution<%1%>&, %1%)";
0382 if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy()))
0383 {
0384 return result;
0385 }
0386 BOOST_MATH_STD_USING
0387 return dist.scale() * pow(RealType(2), (1/dist.shape()));
0388 }
0389
0390 template <class RealType, class Policy>
0391 BOOST_MATH_GPU_ENABLED inline RealType variance(const pareto_distribution<RealType, Policy>& dist)
0392 {
0393 RealType result = 0;
0394 RealType scale = dist.scale();
0395 RealType shape = dist.shape();
0396 constexpr auto function = "boost::math::variance(const pareto_distribution<%1%>&, %1%)";
0397 if(false == detail::check_pareto(function, scale, shape, &result, Policy()))
0398 {
0399 return result;
0400 }
0401 if (shape > 2)
0402 {
0403 result = (scale * scale * shape) /
0404 ((shape - 1) * (shape - 1) * (shape - 2));
0405 }
0406 else
0407 {
0408 result = policies::raise_domain_error<RealType>(
0409 function,
0410 "variance is undefined for shape <= 2, but got %1%.", dist.shape(), Policy());
0411 }
0412 return result;
0413 }
0414
0415 template <class RealType, class Policy>
0416 BOOST_MATH_GPU_ENABLED inline RealType skewness(const pareto_distribution<RealType, Policy>& dist)
0417 {
0418 BOOST_MATH_STD_USING
0419 RealType result = 0;
0420 RealType shape = dist.shape();
0421 constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
0422 if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
0423 {
0424 return result;
0425 }
0426 if (shape > 3)
0427 {
0428 result = sqrt((shape - 2) / shape) *
0429 2 * (shape + 1) /
0430 (shape - 3);
0431 }
0432 else
0433 {
0434 result = policies::raise_domain_error<RealType>(
0435 function,
0436 "skewness is undefined for shape <= 3, but got %1%.", dist.shape(), Policy());
0437 }
0438 return result;
0439 }
0440
0441 template <class RealType, class Policy>
0442 BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const pareto_distribution<RealType, Policy>& dist)
0443 {
0444 RealType result = 0;
0445 RealType shape = dist.shape();
0446 constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
0447 if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
0448 {
0449 return result;
0450 }
0451 if (shape > 4)
0452 {
0453 result = 3 * ((shape - 2) * (3 * shape * shape + shape + 2)) /
0454 (shape * (shape - 3) * (shape - 4));
0455 }
0456 else
0457 {
0458 result = policies::raise_domain_error<RealType>(
0459 function,
0460 "kurtosis_excess is undefined for shape <= 4, but got %1%.", shape, Policy());
0461 }
0462 return result;
0463 }
0464
0465 template <class RealType, class Policy>
0466 BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const pareto_distribution<RealType, Policy>& dist)
0467 {
0468 RealType result = 0;
0469 RealType shape = dist.shape();
0470 constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
0471 if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
0472 {
0473 return result;
0474 }
0475 if (shape > 4)
0476 {
0477 result = 6 * ((shape * shape * shape) + (shape * shape) - 6 * shape - 2) /
0478 (shape * (shape - 3) * (shape - 4));
0479 }
0480 else
0481 {
0482 result = policies::raise_domain_error<RealType>(
0483 function,
0484 "kurtosis_excess is undefined for shape <= 4, but got %1%.", dist.shape(), Policy());
0485 }
0486 return result;
0487 }
0488
0489 template <class RealType, class Policy>
0490 BOOST_MATH_GPU_ENABLED inline RealType entropy(const pareto_distribution<RealType, Policy>& dist)
0491 {
0492 BOOST_MATH_STD_USING
0493 RealType xm = dist.scale();
0494 RealType alpha = dist.shape();
0495 return log(xm/alpha) + 1 + 1/alpha;
0496 }
0497
0498 }
0499 }
0500
0501
0502
0503
0504 #include <boost/math/distributions/detail/derived_accessors.hpp>
0505
0506 #endif
0507
0508