brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.4 KiB · dfc3e4b Raw
362 lines · plain
1//  Copyright John Maddock 2006.2//  Copyright Matt Borland 2024.3//  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_LOGNORMAL_HPP8#define BOOST_STATS_LOGNORMAL_HPP9 10// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm11// http://mathworld.wolfram.com/LogNormalDistribution.html12// http://en.wikipedia.org/wiki/Lognormal_distribution13 14#include <boost/math/tools/config.hpp>15#include <boost/math/tools/tuple.hpp>16#include <boost/math/tools/promotion.hpp>17#include <boost/math/distributions/fwd.hpp>18#include <boost/math/distributions/normal.hpp>19#include <boost/math/special_functions/expm1.hpp>20#include <boost/math/distributions/detail/common_error_handling.hpp>21#include <boost/math/policies/error_handling.hpp>22#include <boost/math/constants/constants.hpp>23 24namespace boost{ namespace math25{26namespace detail27{28 29  template <class RealType, class Policy>30  BOOST_MATH_GPU_ENABLED inline bool check_lognormal_x(31        const char* function,32        RealType const& x,33        RealType* result, const Policy& pol)34  {35     if((x < 0) || !(boost::math::isfinite)(x))36     {37        *result = policies::raise_domain_error<RealType>(38           function,39           "Random variate is %1% but must be >= 0 !", x, pol);40        return false;41     }42     return true;43  }44 45} // namespace detail46 47 48template <class RealType = double, class Policy = policies::policy<> >49class lognormal_distribution50{51public:52   typedef RealType value_type;53   typedef Policy policy_type;54 55   BOOST_MATH_GPU_ENABLED lognormal_distribution(RealType l_location = 0, RealType l_scale = 1)56      : m_location(l_location), m_scale(l_scale)57   {58      RealType result;59      detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_scale, &result, Policy());60      detail::check_location("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_location, &result, Policy());61   }62 63   BOOST_MATH_GPU_ENABLED RealType location()const64   {65      return m_location;66   }67 68   BOOST_MATH_GPU_ENABLED RealType scale()const69   {70      return m_scale;71   }72private:73   //74   // Data members:75   //76   RealType m_location;  // distribution location.77   RealType m_scale;     // distribution scale.78};79 80typedef lognormal_distribution<double> lognormal;81 82#ifdef __cpp_deduction_guides83template <class RealType>84lognormal_distribution(RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;85template <class RealType>86lognormal_distribution(RealType,RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;87#endif88 89template <class RealType, class Policy>90BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const lognormal_distribution<RealType, Policy>& /*dist*/)91{ // Range of permissible values for random variable x is >0 to +infinity.92   using boost::math::tools::max_value;93   return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());94}95 96template <class RealType, class Policy>97BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const lognormal_distribution<RealType, Policy>& /*dist*/)98{ // Range of supported values for random variable x.99   // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.100   using boost::math::tools::max_value;101   return boost::math::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>());102}103 104template <class RealType, class Policy>105BOOST_MATH_GPU_ENABLED RealType pdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)106{107   BOOST_MATH_STD_USING  // for ADL of std functions108 109   RealType mu = dist.location();110   RealType sigma = dist.scale();111 112   constexpr auto function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)";113 114   RealType result = 0;115   if(0 == detail::check_scale(function, sigma, &result, Policy()))116      return result;117   if(0 == detail::check_location(function, mu, &result, Policy()))118      return result;119   if(0 == detail::check_lognormal_x(function, x, &result, Policy()))120      return result;121 122   if(x == 0)123      return 0;124 125   RealType exponent = log(x) - mu;126   exponent *= -exponent;127   exponent /= 2 * sigma * sigma;128 129   result = exp(exponent);130   result /= sigma * sqrt(2 * constants::pi<RealType>()) * x;131 132   return result;133}134 135template <class RealType, class Policy>136BOOST_MATH_GPU_ENABLED inline RealType cdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)137{138   BOOST_MATH_STD_USING  // for ADL of std functions139 140   constexpr auto function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";141 142   RealType result = 0;143   if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))144      return result;145   if(0 == detail::check_location(function, dist.location(), &result, Policy()))146      return result;147   if(0 == detail::check_lognormal_x(function, x, &result, Policy()))148      return result;149 150   if(x == 0)151      return 0;152 153   normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());154   return cdf(norm, log(x));155}156 157template <class RealType, class Policy>158BOOST_MATH_GPU_ENABLED inline RealType quantile(const lognormal_distribution<RealType, Policy>& dist, const RealType& p)159{160   BOOST_MATH_STD_USING  // for ADL of std functions161 162   constexpr auto function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";163 164   RealType result = 0;165   if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))166      return result;167   if(0 == detail::check_location(function, dist.location(), &result, Policy()))168      return result;169   if(0 == detail::check_probability(function, p, &result, Policy()))170      return result;171 172   if(p == 0)173      return 0;174   if(p == 1)175      return policies::raise_overflow_error<RealType>(function, 0, Policy());176 177   normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());178   return exp(quantile(norm, p));179}180 181template <class RealType, class Policy>182BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)183{184   BOOST_MATH_STD_USING  // for ADL of std functions185 186   constexpr auto function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";187 188   RealType result = 0;189   if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))190      return result;191   if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))192      return result;193   if(0 == detail::check_lognormal_x(function, c.param, &result, Policy()))194      return result;195 196   if(c.param == 0)197      return 1;198 199   normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());200   return cdf(complement(norm, log(c.param)));201}202 203template <class RealType, class Policy>204BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)205{206   BOOST_MATH_STD_USING  // for ADL of std functions207 208   constexpr auto function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";209 210   RealType result = 0;211   if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))212      return result;213   if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))214      return result;215   if(0 == detail::check_probability(function, c.param, &result, Policy()))216      return result;217 218   if(c.param == 1)219      return 0;220   if(c.param == 0)221      return policies::raise_overflow_error<RealType>(function, 0, Policy());222 223   normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());224   return exp(quantile(complement(norm, c.param)));225}226 227template <class RealType, class Policy>228BOOST_MATH_GPU_ENABLED inline RealType mean(const lognormal_distribution<RealType, Policy>& dist)229{230   BOOST_MATH_STD_USING  // for ADL of std functions231 232   RealType mu = dist.location();233   RealType sigma = dist.scale();234 235   RealType result = 0;236   if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))237      return result;238   if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy()))239      return result;240 241   return exp(mu + sigma * sigma / 2);242}243 244template <class RealType, class Policy>245BOOST_MATH_GPU_ENABLED inline RealType variance(const lognormal_distribution<RealType, Policy>& dist)246{247   BOOST_MATH_STD_USING  // for ADL of std functions248 249   RealType mu = dist.location();250   RealType sigma = dist.scale();251 252   RealType result = 0;253   if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))254      return result;255   if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy()))256      return result;257 258   return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma);259}260 261template <class RealType, class Policy>262BOOST_MATH_GPU_ENABLED inline RealType mode(const lognormal_distribution<RealType, Policy>& dist)263{264   BOOST_MATH_STD_USING  // for ADL of std functions265 266   RealType mu = dist.location();267   RealType sigma = dist.scale();268 269   RealType result = 0;270   if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))271      return result;272   if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy()))273      return result;274 275   return exp(mu - sigma * sigma);276}277 278template <class RealType, class Policy>279BOOST_MATH_GPU_ENABLED inline RealType median(const lognormal_distribution<RealType, Policy>& dist)280{281   BOOST_MATH_STD_USING  // for ADL of std functions282   RealType mu = dist.location();283   return exp(mu); // e^mu284}285 286template <class RealType, class Policy>287BOOST_MATH_GPU_ENABLED inline RealType skewness(const lognormal_distribution<RealType, Policy>& dist)288{289   BOOST_MATH_STD_USING  // for ADL of std functions290 291   //RealType mu = dist.location();292   RealType sigma = dist.scale();293 294   RealType ss = sigma * sigma;295   RealType ess = exp(ss);296 297   RealType result = 0;298   if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))299      return result;300   if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))301      return result;302 303   return (ess + 2) * sqrt(boost::math::expm1(ss, Policy()));304}305 306template <class RealType, class Policy>307BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const lognormal_distribution<RealType, Policy>& dist)308{309   BOOST_MATH_STD_USING  // for ADL of std functions310 311   //RealType mu = dist.location();312   RealType sigma = dist.scale();313   RealType ss = sigma * sigma;314 315   RealType result = 0;316   if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))317      return result;318   if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))319      return result;320 321   return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3;322}323 324template <class RealType, class Policy>325BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>& dist)326{327   BOOST_MATH_STD_USING  // for ADL of std functions328 329   // RealType mu = dist.location();330   RealType sigma = dist.scale();331   RealType ss = sigma * sigma;332 333   RealType result = 0;334   if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))335      return result;336   if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))337      return result;338 339   return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;340}341 342template <class RealType, class Policy>343BOOST_MATH_GPU_ENABLED inline RealType entropy(const lognormal_distribution<RealType, Policy>& dist)344{345   BOOST_MATH_STD_USING346   RealType mu = dist.location();347   RealType sigma = dist.scale();348   return mu + log(constants::two_pi<RealType>()*constants::e<RealType>()*sigma*sigma)/2;349}350 351} // namespace math352} // namespace boost353 354// This include must be at the end, *after* the accessors355// for this distribution have been defined, in order to356// keep compilers that support two-phase lookup happy.357#include <boost/math/distributions/detail/derived_accessors.hpp>358 359#endif // BOOST_STATS_STUDENTS_T_HPP360 361 362