Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:42

0001 //  Copyright John Maddock 2006.
0002 //  Use, modification and distribution are subject to the
0003 //  Boost Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_STATS_LOGNORMAL_HPP
0007 #define BOOST_STATS_LOGNORMAL_HPP
0008 
0009 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm
0010 // http://mathworld.wolfram.com/LogNormalDistribution.html
0011 // http://en.wikipedia.org/wiki/Lognormal_distribution
0012 
0013 #include <boost/math/distributions/fwd.hpp>
0014 #include <boost/math/distributions/normal.hpp>
0015 #include <boost/math/special_functions/expm1.hpp>
0016 #include <boost/math/distributions/detail/common_error_handling.hpp>
0017 
0018 #include <utility>
0019 
0020 namespace boost{ namespace math
0021 {
0022 namespace detail
0023 {
0024 
0025   template <class RealType, class Policy>
0026   inline bool check_lognormal_x(
0027         const char* function,
0028         RealType const& x,
0029         RealType* result, const Policy& pol)
0030   {
0031      if((x < 0) || !(boost::math::isfinite)(x))
0032      {
0033         *result = policies::raise_domain_error<RealType>(
0034            function,
0035            "Random variate is %1% but must be >= 0 !", x, pol);
0036         return false;
0037      }
0038      return true;
0039   }
0040 
0041 } // namespace detail
0042 
0043 
0044 template <class RealType = double, class Policy = policies::policy<> >
0045 class lognormal_distribution
0046 {
0047 public:
0048    typedef RealType value_type;
0049    typedef Policy policy_type;
0050 
0051    lognormal_distribution(RealType l_location = 0, RealType l_scale = 1)
0052       : m_location(l_location), m_scale(l_scale)
0053    {
0054       RealType result;
0055       detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_scale, &result, Policy());
0056       detail::check_location("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_location, &result, Policy());
0057    }
0058 
0059    RealType location()const
0060    {
0061       return m_location;
0062    }
0063 
0064    RealType scale()const
0065    {
0066       return m_scale;
0067    }
0068 private:
0069    //
0070    // Data members:
0071    //
0072    RealType m_location;  // distribution location.
0073    RealType m_scale;     // distribution scale.
0074 };
0075 
0076 typedef lognormal_distribution<double> lognormal;
0077 
0078 #ifdef __cpp_deduction_guides
0079 template <class RealType>
0080 lognormal_distribution(RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0081 template <class RealType>
0082 lognormal_distribution(RealType,RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0083 #endif
0084 
0085 template <class RealType, class Policy>
0086 inline const std::pair<RealType, RealType> range(const lognormal_distribution<RealType, Policy>& /*dist*/)
0087 { // Range of permissible values for random variable x is >0 to +infinity.
0088    using boost::math::tools::max_value;
0089    return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
0090 }
0091 
0092 template <class RealType, class Policy>
0093 inline const std::pair<RealType, RealType> support(const lognormal_distribution<RealType, Policy>& /*dist*/)
0094 { // Range of supported values for random variable x.
0095    // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
0096    using boost::math::tools::max_value;
0097    return std::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>());
0098 }
0099 
0100 template <class RealType, class Policy>
0101 RealType pdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
0102 {
0103    BOOST_MATH_STD_USING  // for ADL of std functions
0104 
0105    RealType mu = dist.location();
0106    RealType sigma = dist.scale();
0107 
0108    static const char* function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)";
0109 
0110    RealType result = 0;
0111    if(0 == detail::check_scale(function, sigma, &result, Policy()))
0112       return result;
0113    if(0 == detail::check_location(function, mu, &result, Policy()))
0114       return result;
0115    if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
0116       return result;
0117 
0118    if(x == 0)
0119       return 0;
0120 
0121    RealType exponent = log(x) - mu;
0122    exponent *= -exponent;
0123    exponent /= 2 * sigma * sigma;
0124 
0125    result = exp(exponent);
0126    result /= sigma * sqrt(2 * constants::pi<RealType>()) * x;
0127 
0128    return result;
0129 }
0130 
0131 template <class RealType, class Policy>
0132 inline RealType cdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
0133 {
0134    BOOST_MATH_STD_USING  // for ADL of std functions
0135 
0136    static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
0137 
0138    RealType result = 0;
0139    if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
0140       return result;
0141    if(0 == detail::check_location(function, dist.location(), &result, Policy()))
0142       return result;
0143    if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
0144       return result;
0145 
0146    if(x == 0)
0147       return 0;
0148 
0149    normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
0150    return cdf(norm, log(x));
0151 }
0152 
0153 template <class RealType, class Policy>
0154 inline RealType quantile(const lognormal_distribution<RealType, Policy>& dist, const RealType& p)
0155 {
0156    BOOST_MATH_STD_USING  // for ADL of std functions
0157 
0158    static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
0159 
0160    RealType result = 0;
0161    if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
0162       return result;
0163    if(0 == detail::check_location(function, dist.location(), &result, Policy()))
0164       return result;
0165    if(0 == detail::check_probability(function, p, &result, Policy()))
0166       return result;
0167 
0168    if(p == 0)
0169       return 0;
0170    if(p == 1)
0171       return policies::raise_overflow_error<RealType>(function, 0, Policy());
0172 
0173    normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
0174    return exp(quantile(norm, p));
0175 }
0176 
0177 template <class RealType, class Policy>
0178 inline RealType cdf(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
0179 {
0180    BOOST_MATH_STD_USING  // for ADL of std functions
0181 
0182    static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
0183 
0184    RealType result = 0;
0185    if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
0186       return result;
0187    if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
0188       return result;
0189    if(0 == detail::check_lognormal_x(function, c.param, &result, Policy()))
0190       return result;
0191 
0192    if(c.param == 0)
0193       return 1;
0194 
0195    normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
0196    return cdf(complement(norm, log(c.param)));
0197 }
0198 
0199 template <class RealType, class Policy>
0200 inline RealType quantile(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
0201 {
0202    BOOST_MATH_STD_USING  // for ADL of std functions
0203 
0204    static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
0205 
0206    RealType result = 0;
0207    if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
0208       return result;
0209    if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
0210       return result;
0211    if(0 == detail::check_probability(function, c.param, &result, Policy()))
0212       return result;
0213 
0214    if(c.param == 1)
0215       return 0;
0216    if(c.param == 0)
0217       return policies::raise_overflow_error<RealType>(function, 0, Policy());
0218 
0219    normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
0220    return exp(quantile(complement(norm, c.param)));
0221 }
0222 
0223 template <class RealType, class Policy>
0224 inline RealType mean(const lognormal_distribution<RealType, Policy>& dist)
0225 {
0226    BOOST_MATH_STD_USING  // for ADL of std functions
0227 
0228    RealType mu = dist.location();
0229    RealType sigma = dist.scale();
0230 
0231    RealType result = 0;
0232    if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0233       return result;
0234    if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
0235       return result;
0236 
0237    return exp(mu + sigma * sigma / 2);
0238 }
0239 
0240 template <class RealType, class Policy>
0241 inline RealType variance(const lognormal_distribution<RealType, Policy>& dist)
0242 {
0243    BOOST_MATH_STD_USING  // for ADL of std functions
0244 
0245    RealType mu = dist.location();
0246    RealType sigma = dist.scale();
0247 
0248    RealType result = 0;
0249    if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0250       return result;
0251    if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
0252       return result;
0253 
0254    return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma);
0255 }
0256 
0257 template <class RealType, class Policy>
0258 inline RealType mode(const lognormal_distribution<RealType, Policy>& dist)
0259 {
0260    BOOST_MATH_STD_USING  // for ADL of std functions
0261 
0262    RealType mu = dist.location();
0263    RealType sigma = dist.scale();
0264 
0265    RealType result = 0;
0266    if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0267       return result;
0268    if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
0269       return result;
0270 
0271    return exp(mu - sigma * sigma);
0272 }
0273 
0274 template <class RealType, class Policy>
0275 inline RealType median(const lognormal_distribution<RealType, Policy>& dist)
0276 {
0277    BOOST_MATH_STD_USING  // for ADL of std functions
0278    RealType mu = dist.location();
0279    return exp(mu); // e^mu
0280 }
0281 
0282 template <class RealType, class Policy>
0283 inline RealType skewness(const lognormal_distribution<RealType, Policy>& dist)
0284 {
0285    BOOST_MATH_STD_USING  // for ADL of std functions
0286 
0287    //RealType mu = dist.location();
0288    RealType sigma = dist.scale();
0289 
0290    RealType ss = sigma * sigma;
0291    RealType ess = exp(ss);
0292 
0293    RealType result = 0;
0294    if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0295       return result;
0296    if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
0297       return result;
0298 
0299    return (ess + 2) * sqrt(boost::math::expm1(ss, Policy()));
0300 }
0301 
0302 template <class RealType, class Policy>
0303 inline RealType kurtosis(const lognormal_distribution<RealType, Policy>& dist)
0304 {
0305    BOOST_MATH_STD_USING  // for ADL of std functions
0306 
0307    //RealType mu = dist.location();
0308    RealType sigma = dist.scale();
0309    RealType ss = sigma * sigma;
0310 
0311    RealType result = 0;
0312    if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0313       return result;
0314    if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
0315       return result;
0316 
0317    return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3;
0318 }
0319 
0320 template <class RealType, class Policy>
0321 inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>& dist)
0322 {
0323    BOOST_MATH_STD_USING  // for ADL of std functions
0324 
0325    // RealType mu = dist.location();
0326    RealType sigma = dist.scale();
0327    RealType ss = sigma * sigma;
0328 
0329    RealType result = 0;
0330    if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
0331       return result;
0332    if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
0333       return result;
0334 
0335    return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;
0336 }
0337 
0338 template <class RealType, class Policy>
0339 inline RealType entropy(const lognormal_distribution<RealType, Policy>& dist)
0340 {
0341    using std::log;
0342    RealType mu = dist.location();
0343    RealType sigma = dist.scale();
0344    return mu + log(constants::two_pi<RealType>()*constants::e<RealType>()*sigma*sigma)/2;
0345 }
0346 
0347 } // namespace math
0348 } // namespace boost
0349 
0350 // This include must be at the end, *after* the accessors
0351 // for this distribution have been defined, in order to
0352 // keep compilers that support two-phase lookup happy.
0353 #include <boost/math/distributions/detail/derived_accessors.hpp>
0354 
0355 #endif // BOOST_STATS_STUDENTS_T_HPP
0356 
0357