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