File indexing completed on 2025-09-18 08:48:21
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_STATS_EXPONENTIAL_HPP
0008 #define BOOST_STATS_EXPONENTIAL_HPP
0009
0010 #include <boost/math/tools/config.hpp>
0011 #include <boost/math/tools/tuple.hpp>
0012 #include <boost/math/tools/numeric_limits.hpp>
0013 #include <boost/math/constants/constants.hpp>
0014 #include <boost/math/special_functions/log1p.hpp>
0015 #include <boost/math/special_functions/expm1.hpp>
0016 #include <boost/math/distributions/complement.hpp>
0017 #include <boost/math/distributions/detail/common_error_handling.hpp>
0018 #include <boost/math/policies/policy.hpp>
0019 #include <boost/math/policies/error_handling.hpp>
0020
0021 #ifdef _MSC_VER
0022 # pragma warning(push)
0023 # pragma warning(disable: 4127)
0024 # pragma warning(disable: 4702)
0025 #endif
0026
0027 #ifndef BOOST_MATH_HAS_NVRTC
0028 #include <boost/math/distributions/fwd.hpp>
0029 #include <utility>
0030 #include <cmath>
0031 #endif
0032
0033 namespace boost{ namespace math{
0034
0035 namespace detail{
0036
0037
0038
0039 template <class RealType, class Policy>
0040 BOOST_MATH_GPU_ENABLED inline bool verify_lambda(const char* function, RealType l, RealType* presult, const Policy& pol)
0041 {
0042 if((l <= 0) || !(boost::math::isfinite)(l))
0043 {
0044 *presult = policies::raise_domain_error<RealType>(
0045 function,
0046 "The scale parameter \"lambda\" must be > 0, but was: %1%.", l, pol);
0047 return false;
0048 }
0049 return true;
0050 }
0051
0052 template <class RealType, class Policy>
0053 BOOST_MATH_GPU_ENABLED inline bool verify_exp_x(const char* function, RealType x, RealType* presult, const Policy& pol)
0054 {
0055 if((x < 0) || (boost::math::isnan)(x))
0056 {
0057 *presult = policies::raise_domain_error<RealType>(
0058 function,
0059 "The random variable must be >= 0, but was: %1%.", x, pol);
0060 return false;
0061 }
0062 return true;
0063 }
0064
0065 }
0066
0067 template <class RealType = double, class Policy = policies::policy<> >
0068 class exponential_distribution
0069 {
0070 public:
0071 using value_type = RealType;
0072 using policy_type = Policy;
0073
0074 BOOST_MATH_GPU_ENABLED explicit exponential_distribution(RealType l_lambda = 1)
0075 : m_lambda(l_lambda)
0076 {
0077 RealType err;
0078 detail::verify_lambda("boost::math::exponential_distribution<%1%>::exponential_distribution", l_lambda, &err, Policy());
0079 }
0080
0081 BOOST_MATH_GPU_ENABLED RealType lambda()const { return m_lambda; }
0082
0083 private:
0084 RealType m_lambda;
0085 };
0086
0087 using exponential = exponential_distribution<double>;
0088
0089 #ifdef __cpp_deduction_guides
0090 template <class RealType>
0091 exponential_distribution(RealType)->exponential_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0092 #endif
0093
0094 template <class RealType, class Policy>
0095 BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& )
0096 {
0097 BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
0098 {
0099 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity());
0100 }
0101 else
0102 {
0103 using boost::math::tools::max_value;
0104 return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
0105 }
0106 }
0107
0108 template <class RealType, class Policy>
0109 BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& )
0110 {
0111
0112 using boost::math::tools::max_value;
0113 using boost::math::tools::min_value;
0114 return boost::math::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
0115
0116 }
0117
0118 template <class RealType, class Policy>
0119 BOOST_MATH_GPU_ENABLED inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
0120 {
0121 BOOST_MATH_STD_USING
0122
0123 constexpr auto function = "boost::math::pdf(const exponential_distribution<%1%>&, %1%)";
0124
0125 RealType lambda = dist.lambda();
0126 RealType result = 0;
0127 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0128 return result;
0129 if(0 == detail::verify_exp_x(function, x, &result, Policy()))
0130 return result;
0131
0132 if ((boost::math::isinf)(x))
0133 return 0;
0134 result = lambda * exp(-lambda * x);
0135 return result;
0136 }
0137
0138 template <class RealType, class Policy>
0139 BOOST_MATH_GPU_ENABLED inline RealType logpdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
0140 {
0141 BOOST_MATH_STD_USING
0142
0143 constexpr auto function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)";
0144
0145 RealType lambda = dist.lambda();
0146 RealType result = -boost::math::numeric_limits<RealType>::infinity();
0147 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0148 return result;
0149 if(0 == detail::verify_exp_x(function, x, &result, Policy()))
0150 return result;
0151
0152 result = log(lambda) - lambda * x;
0153 return result;
0154 }
0155
0156 template <class RealType, class Policy>
0157 BOOST_MATH_GPU_ENABLED inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
0158 {
0159 BOOST_MATH_STD_USING
0160
0161 constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";
0162
0163 RealType result = 0;
0164 RealType lambda = dist.lambda();
0165 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0166 return result;
0167 if(0 == detail::verify_exp_x(function, x, &result, Policy()))
0168 return result;
0169 result = -boost::math::expm1(-x * lambda, Policy());
0170
0171 return result;
0172 }
0173
0174 template <class RealType, class Policy>
0175 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
0176 {
0177 BOOST_MATH_STD_USING
0178
0179 constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)";
0180
0181 RealType result = 0;
0182 RealType lambda = dist.lambda();
0183 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0184 return result;
0185 if(0 == detail::verify_exp_x(function, x, &result, Policy()))
0186 return result;
0187 result = boost::math::log1p(-exp(-x * lambda), Policy());
0188
0189 return result;
0190 }
0191
0192 template <class RealType, class Policy>
0193 BOOST_MATH_GPU_ENABLED inline RealType quantile(const exponential_distribution<RealType, Policy>& dist, const RealType& p)
0194 {
0195 BOOST_MATH_STD_USING
0196
0197 constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";
0198
0199 RealType result = 0;
0200 RealType lambda = dist.lambda();
0201 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0202 return result;
0203 if(0 == detail::check_probability(function, p, &result, Policy()))
0204 return result;
0205
0206 if(p == 0)
0207 return 0;
0208 if(p == 1)
0209 return policies::raise_overflow_error<RealType>(function, 0, Policy());
0210
0211 result = -boost::math::log1p(-p, Policy()) / lambda;
0212 return result;
0213 }
0214
0215 template <class RealType, class Policy>
0216 BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
0217 {
0218 BOOST_MATH_STD_USING
0219
0220 constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";
0221
0222 RealType result = 0;
0223 RealType lambda = c.dist.lambda();
0224 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0225 return result;
0226 if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))
0227 return result;
0228
0229 if (c.param >= tools::max_value<RealType>())
0230 return 0;
0231 result = exp(-c.param * lambda);
0232
0233 return result;
0234 }
0235
0236 template <class RealType, class Policy>
0237 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
0238 {
0239 BOOST_MATH_STD_USING
0240
0241 constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)";
0242
0243 RealType result = 0;
0244 RealType lambda = c.dist.lambda();
0245 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0246 return result;
0247 if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))
0248 return result;
0249
0250 if (c.param >= tools::max_value<RealType>())
0251 return 0;
0252 result = -c.param * lambda;
0253
0254 return result;
0255 }
0256
0257 template <class RealType, class Policy>
0258 BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
0259 {
0260 BOOST_MATH_STD_USING
0261
0262 constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";
0263
0264 RealType result = 0;
0265 RealType lambda = c.dist.lambda();
0266 if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
0267 return result;
0268
0269 RealType q = c.param;
0270 if(0 == detail::check_probability(function, q, &result, Policy()))
0271 return result;
0272
0273 if(q == 1)
0274 return 0;
0275 if(q == 0)
0276 return policies::raise_overflow_error<RealType>(function, 0, Policy());
0277
0278 result = -log(q) / lambda;
0279 return result;
0280 }
0281
0282 template <class RealType, class Policy>
0283 BOOST_MATH_GPU_ENABLED inline RealType mean(const exponential_distribution<RealType, Policy>& dist)
0284 {
0285 RealType result = 0;
0286 RealType lambda = dist.lambda();
0287 if(0 == detail::verify_lambda("boost::math::mean(const exponential_distribution<%1%>&)", lambda, &result, Policy()))
0288 return result;
0289 return 1 / lambda;
0290 }
0291
0292 template <class RealType, class Policy>
0293 BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const exponential_distribution<RealType, Policy>& dist)
0294 {
0295 RealType result = 0;
0296 RealType lambda = dist.lambda();
0297 if(0 == detail::verify_lambda("boost::math::standard_deviation(const exponential_distribution<%1%>&)", lambda, &result, Policy()))
0298 return result;
0299 return 1 / lambda;
0300 }
0301
0302 template <class RealType, class Policy>
0303 BOOST_MATH_GPU_ENABLED inline RealType mode(const exponential_distribution<RealType, Policy>& )
0304 {
0305 return 0;
0306 }
0307
0308 template <class RealType, class Policy>
0309 BOOST_MATH_GPU_ENABLED inline RealType median(const exponential_distribution<RealType, Policy>& dist)
0310 {
0311 using boost::math::constants::ln_two;
0312 return ln_two<RealType>() / dist.lambda();
0313 }
0314
0315 template <class RealType, class Policy>
0316 BOOST_MATH_GPU_ENABLED inline RealType skewness(const exponential_distribution<RealType, Policy>& )
0317 {
0318 return 2;
0319 }
0320
0321 template <class RealType, class Policy>
0322 BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const exponential_distribution<RealType, Policy>& )
0323 {
0324 return 9;
0325 }
0326
0327 template <class RealType, class Policy>
0328 BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const exponential_distribution<RealType, Policy>& )
0329 {
0330 return 6;
0331 }
0332
0333 template <class RealType, class Policy>
0334 BOOST_MATH_GPU_ENABLED inline RealType entropy(const exponential_distribution<RealType, Policy>& dist)
0335 {
0336 using std::log;
0337 return 1 - log(dist.lambda());
0338 }
0339
0340 }
0341 }
0342
0343 #ifdef _MSC_VER
0344 # pragma warning(pop)
0345 #endif
0346
0347
0348
0349
0350 #include <boost/math/distributions/detail/derived_accessors.hpp>
0351
0352 #endif