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