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