brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 9d45ac4 Raw
353 lines · plain
1//  Copyright John Maddock 2006.2//  Copyright Matt Borland 20243//  Use, modification and distribution are subject to the4//  Boost Software License, Version 1.0. (See accompanying file5//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)6 7#ifndef BOOST_STATS_EXPONENTIAL_HPP8#define BOOST_STATS_EXPONENTIAL_HPP9 10#include <boost/math/tools/config.hpp>11#include <boost/math/tools/tuple.hpp>12#include <boost/math/tools/numeric_limits.hpp>13#include <boost/math/constants/constants.hpp>14#include <boost/math/special_functions/log1p.hpp>15#include <boost/math/special_functions/expm1.hpp>16#include <boost/math/distributions/complement.hpp>17#include <boost/math/distributions/detail/common_error_handling.hpp>18#include <boost/math/policies/policy.hpp>19#include <boost/math/policies/error_handling.hpp>20 21#ifdef _MSC_VER22# pragma warning(push)23# pragma warning(disable: 4127) // conditional expression is constant24# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).25#endif26 27#ifndef BOOST_MATH_HAS_NVRTC28#include <boost/math/distributions/fwd.hpp>29#include <utility>30#include <cmath>31#endif32 33namespace boost{ namespace math{34 35namespace detail{36//37// Error check:38//39template <class RealType, class Policy>40BOOST_MATH_GPU_ENABLED inline bool verify_lambda(const char* function, RealType l, RealType* presult, const Policy& pol)41{42   if((l <= 0) || !(boost::math::isfinite)(l))43   {44      *presult = policies::raise_domain_error<RealType>(45         function,46         "The scale parameter \"lambda\" must be > 0, but was: %1%.", l, pol);47      return false;48   }49   return true;50}51 52template <class RealType, class Policy>53BOOST_MATH_GPU_ENABLED inline bool verify_exp_x(const char* function, RealType x, RealType* presult, const Policy& pol)54{55   if((x < 0) || (boost::math::isnan)(x))56   {57      *presult = policies::raise_domain_error<RealType>(58         function,59         "The random variable must be >= 0, but was: %1%.", x, pol);60      return false;61   }62   return true;63}64 65} // namespace detail66 67template <class RealType = double, class Policy = policies::policy<> >68class exponential_distribution69{70public:71   using value_type = RealType;72   using policy_type = Policy;73 74   BOOST_MATH_GPU_ENABLED explicit exponential_distribution(RealType l_lambda = 1)75      : m_lambda(l_lambda)76   {77      RealType err;78      detail::verify_lambda("boost::math::exponential_distribution<%1%>::exponential_distribution", l_lambda, &err, Policy());79   } // exponential_distribution80 81   BOOST_MATH_GPU_ENABLED RealType lambda()const { return m_lambda; }82 83private:84   RealType m_lambda;85};86 87using exponential = exponential_distribution<double>;88 89#ifdef __cpp_deduction_guides90template <class RealType>91exponential_distribution(RealType)->exponential_distribution<typename boost::math::tools::promote_args<RealType>::type>;92#endif93 94template <class RealType, class Policy>95BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)96{ // Range of permissible values for random variable x.97  BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)98  { 99    return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity()); // 0 to + infinity.100  }101  else102  {103   using boost::math::tools::max_value;104   return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + max105  }106}107 108template <class RealType, class Policy>109BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& /*dist*/)110{ // Range of supported values for random variable x.111   // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.112   using boost::math::tools::max_value;113   using boost::math::tools::min_value;114   return boost::math::pair<RealType, RealType>(min_value<RealType>(),  max_value<RealType>());115   // min_value<RealType>() to avoid a discontinuity at x = 0.116}117 118template <class RealType, class Policy>119BOOST_MATH_GPU_ENABLED inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)120{121   BOOST_MATH_STD_USING // for ADL of std functions122 123   constexpr auto function = "boost::math::pdf(const exponential_distribution<%1%>&, %1%)";124 125   RealType lambda = dist.lambda();126   RealType result = 0;127   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))128      return result;129   if(0 == detail::verify_exp_x(function, x, &result, Policy()))130      return result;131   // Workaround for VC11/12 bug:132   if ((boost::math::isinf)(x))133      return 0;134   result = lambda * exp(-lambda * x);135   return result;136} // pdf137 138template <class RealType, class Policy>139BOOST_MATH_GPU_ENABLED inline RealType logpdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)140{141   BOOST_MATH_STD_USING // for ADL of std functions142 143   constexpr auto function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)";144 145   RealType lambda = dist.lambda();146   RealType result = -boost::math::numeric_limits<RealType>::infinity();147   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))148      return result;149   if(0 == detail::verify_exp_x(function, x, &result, Policy()))150      return result;151   152   result = log(lambda) - lambda * x;153   return result;154} // logpdf155 156template <class RealType, class Policy>157BOOST_MATH_GPU_ENABLED inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)158{159   BOOST_MATH_STD_USING // for ADL of std functions160 161   constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";162 163   RealType result = 0;164   RealType lambda = dist.lambda();165   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))166      return result;167   if(0 == detail::verify_exp_x(function, x, &result, Policy()))168      return result;169   result = -boost::math::expm1(-x * lambda, Policy());170 171   return result;172} // cdf173 174template <class RealType, class Policy>175BOOST_MATH_GPU_ENABLED inline RealType logcdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)176{177   BOOST_MATH_STD_USING // for ADL of std functions178 179   constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)";180 181   RealType result = 0;182   RealType lambda = dist.lambda();183   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))184      return result;185   if(0 == detail::verify_exp_x(function, x, &result, Policy()))186      return result;187   result = boost::math::log1p(-exp(-x * lambda), Policy());188 189   return result;190} // cdf191 192template <class RealType, class Policy>193BOOST_MATH_GPU_ENABLED inline RealType quantile(const exponential_distribution<RealType, Policy>& dist, const RealType& p)194{195   BOOST_MATH_STD_USING // for ADL of std functions196 197   constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";198 199   RealType result = 0;200   RealType lambda = dist.lambda();201   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))202      return result;203   if(0 == detail::check_probability(function, p, &result, Policy()))204      return result;205 206   if(p == 0)207      return 0;208   if(p == 1)209      return policies::raise_overflow_error<RealType>(function, 0, Policy());210 211   result = -boost::math::log1p(-p, Policy()) / lambda;212   return result;213} // quantile214 215template <class RealType, class Policy>216BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)217{218   BOOST_MATH_STD_USING // for ADL of std functions219 220   constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";221 222   RealType result = 0;223   RealType lambda = c.dist.lambda();224   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))225      return result;226   if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))227      return result;228   // Workaround for VC11/12 bug:229   if (c.param >= tools::max_value<RealType>())230      return 0;231   result = exp(-c.param * lambda);232 233   return result;234}235 236template <class RealType, class Policy>237BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)238{239   BOOST_MATH_STD_USING // for ADL of std functions240 241   constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)";242 243   RealType result = 0;244   RealType lambda = c.dist.lambda();245   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))246      return result;247   if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))248      return result;249   // Workaround for VC11/12 bug:250   if (c.param >= tools::max_value<RealType>())251      return 0;252   result = -c.param * lambda;253 254   return result;255}256 257template <class RealType, class Policy>258BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)259{260   BOOST_MATH_STD_USING // for ADL of std functions261 262   constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";263 264   RealType result = 0;265   RealType lambda = c.dist.lambda();266   if(0 == detail::verify_lambda(function, lambda, &result, Policy()))267      return result;268 269   RealType q = c.param;270   if(0 == detail::check_probability(function, q, &result, Policy()))271      return result;272 273   if(q == 1)274      return 0;275   if(q == 0)276      return policies::raise_overflow_error<RealType>(function, 0, Policy());277 278   result = -log(q) / lambda;279   return result;280}281 282template <class RealType, class Policy>283BOOST_MATH_GPU_ENABLED inline RealType mean(const exponential_distribution<RealType, Policy>& dist)284{285   RealType result = 0;286   RealType lambda = dist.lambda();287   if(0 == detail::verify_lambda("boost::math::mean(const exponential_distribution<%1%>&)", lambda, &result, Policy()))288      return result;289   return 1 / lambda;290}291 292template <class RealType, class Policy>293BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const exponential_distribution<RealType, Policy>& dist)294{295   RealType result = 0;296   RealType lambda = dist.lambda();297   if(0 == detail::verify_lambda("boost::math::standard_deviation(const exponential_distribution<%1%>&)", lambda, &result, Policy()))298      return result;299   return 1 / lambda;300}301 302template <class RealType, class Policy>303BOOST_MATH_GPU_ENABLED inline RealType mode(const exponential_distribution<RealType, Policy>& /*dist*/)304{305   return 0;306}307 308template <class RealType, class Policy>309BOOST_MATH_GPU_ENABLED inline RealType median(const exponential_distribution<RealType, Policy>& dist)310{311   using boost::math::constants::ln_two;312   return ln_two<RealType>() / dist.lambda(); // ln(2) / lambda313}314 315template <class RealType, class Policy>316BOOST_MATH_GPU_ENABLED inline RealType skewness(const exponential_distribution<RealType, Policy>& /*dist*/)317{318   return 2;319}320 321template <class RealType, class Policy>322BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const exponential_distribution<RealType, Policy>& /*dist*/)323{324   return 9;325}326 327template <class RealType, class Policy>328BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const exponential_distribution<RealType, Policy>& /*dist*/)329{330   return 6;331}332 333template <class RealType, class Policy>334BOOST_MATH_GPU_ENABLED inline RealType entropy(const exponential_distribution<RealType, Policy>& dist)335{336   using std::log;337   return 1 - log(dist.lambda());338}339 340} // namespace math341} // namespace boost342 343#ifdef _MSC_VER344# pragma warning(pop)345#endif346 347// This include must be at the end, *after* the accessors348// for this distribution have been defined, in order to349// keep compilers that support two-phase lookup happy.350#include <boost/math/distributions/detail/derived_accessors.hpp>351 352#endif // BOOST_STATS_EXPONENTIAL_HPP353