]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/math/distributions/lognormal.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / math / distributions / lognormal.hpp
CommitLineData
7c673cae
FG
1// Copyright John Maddock 2006.
2// Use, modification and distribution are subject to the
3// Boost Software License, Version 1.0. (See accompanying file
4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_STATS_LOGNORMAL_HPP
7#define BOOST_STATS_LOGNORMAL_HPP
8
9// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm
10// http://mathworld.wolfram.com/LogNormalDistribution.html
11// http://en.wikipedia.org/wiki/Lognormal_distribution
12
13#include <boost/math/distributions/fwd.hpp>
14#include <boost/math/distributions/normal.hpp>
15#include <boost/math/special_functions/expm1.hpp>
16#include <boost/math/distributions/detail/common_error_handling.hpp>
17
18#include <utility>
19
20namespace boost{ namespace math
21{
22namespace detail
23{
24
25 template <class RealType, class Policy>
26 inline bool check_lognormal_x(
27 const char* function,
28 RealType const& x,
29 RealType* result, const Policy& pol)
30 {
31 if((x < 0) || !(boost::math::isfinite)(x))
32 {
33 *result = policies::raise_domain_error<RealType>(
34 function,
35 "Random variate is %1% but must be >= 0 !", x, pol);
36 return false;
37 }
38 return true;
39 }
40
41} // namespace detail
42
43
44template <class RealType = double, class Policy = policies::policy<> >
45class lognormal_distribution
46{
47public:
48 typedef RealType value_type;
49 typedef Policy policy_type;
50
51 lognormal_distribution(RealType l_location = 0, RealType l_scale = 1)
52 : m_location(l_location), m_scale(l_scale)
53 {
54 RealType result;
55 detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_scale, &result, Policy());
56 detail::check_location("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_location, &result, Policy());
57 }
58
59 RealType location()const
60 {
61 return m_location;
62 }
63
64 RealType scale()const
65 {
66 return m_scale;
67 }
68private:
69 //
70 // Data members:
71 //
72 RealType m_location; // distribution location.
73 RealType m_scale; // distribution scale.
74};
75
76typedef lognormal_distribution<double> lognormal;
77
1e59de90
TL
78#ifdef __cpp_deduction_guides
79template <class RealType>
80lognormal_distribution(RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
81template <class RealType>
82lognormal_distribution(RealType,RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
83#endif
84
7c673cae
FG
85template <class RealType, class Policy>
86inline const std::pair<RealType, RealType> range(const lognormal_distribution<RealType, Policy>& /*dist*/)
87{ // Range of permissible values for random variable x is >0 to +infinity.
88 using boost::math::tools::max_value;
89 return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
90}
91
92template <class RealType, class Policy>
93inline const std::pair<RealType, RealType> support(const lognormal_distribution<RealType, Policy>& /*dist*/)
94{ // Range of supported values for random variable x.
95 // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
96 using boost::math::tools::max_value;
97 return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
98}
99
100template <class RealType, class Policy>
101RealType pdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
102{
103 BOOST_MATH_STD_USING // for ADL of std functions
104
105 RealType mu = dist.location();
106 RealType sigma = dist.scale();
107
108 static const char* function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)";
109
110 RealType result = 0;
111 if(0 == detail::check_scale(function, sigma, &result, Policy()))
112 return result;
113 if(0 == detail::check_location(function, mu, &result, Policy()))
114 return result;
115 if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
116 return result;
117
118 if(x == 0)
119 return 0;
120
121 RealType exponent = log(x) - mu;
122 exponent *= -exponent;
123 exponent /= 2 * sigma * sigma;
124
125 result = exp(exponent);
126 result /= sigma * sqrt(2 * constants::pi<RealType>()) * x;
127
128 return result;
129}
130
131template <class RealType, class Policy>
132inline RealType cdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
133{
134 BOOST_MATH_STD_USING // for ADL of std functions
135
136 static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
137
138 RealType result = 0;
139 if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
140 return result;
141 if(0 == detail::check_location(function, dist.location(), &result, Policy()))
142 return result;
143 if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
144 return result;
145
146 if(x == 0)
147 return 0;
148
149 normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
150 return cdf(norm, log(x));
151}
152
153template <class RealType, class Policy>
154inline RealType quantile(const lognormal_distribution<RealType, Policy>& dist, const RealType& p)
155{
156 BOOST_MATH_STD_USING // for ADL of std functions
157
158 static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
159
160 RealType result = 0;
161 if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
162 return result;
163 if(0 == detail::check_location(function, dist.location(), &result, Policy()))
164 return result;
165 if(0 == detail::check_probability(function, p, &result, Policy()))
166 return result;
167
168 if(p == 0)
169 return 0;
170 if(p == 1)
171 return policies::raise_overflow_error<RealType>(function, 0, Policy());
172
173 normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
174 return exp(quantile(norm, p));
175}
176
177template <class RealType, class Policy>
178inline RealType cdf(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
179{
180 BOOST_MATH_STD_USING // for ADL of std functions
181
182 static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
183
184 RealType result = 0;
185 if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
186 return result;
187 if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
188 return result;
189 if(0 == detail::check_lognormal_x(function, c.param, &result, Policy()))
190 return result;
191
192 if(c.param == 0)
193 return 1;
194
195 normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
196 return cdf(complement(norm, log(c.param)));
197}
198
199template <class RealType, class Policy>
200inline RealType quantile(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
201{
202 BOOST_MATH_STD_USING // for ADL of std functions
203
204 static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
205
206 RealType result = 0;
207 if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
208 return result;
209 if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
210 return result;
211 if(0 == detail::check_probability(function, c.param, &result, Policy()))
212 return result;
213
214 if(c.param == 1)
215 return 0;
216 if(c.param == 0)
217 return policies::raise_overflow_error<RealType>(function, 0, Policy());
218
219 normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
220 return exp(quantile(complement(norm, c.param)));
221}
222
223template <class RealType, class Policy>
224inline RealType mean(const lognormal_distribution<RealType, Policy>& dist)
225{
226 BOOST_MATH_STD_USING // for ADL of std functions
227
228 RealType mu = dist.location();
229 RealType sigma = dist.scale();
230
231 RealType result = 0;
232 if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
233 return result;
234 if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
235 return result;
236
237 return exp(mu + sigma * sigma / 2);
238}
239
240template <class RealType, class Policy>
241inline RealType variance(const lognormal_distribution<RealType, Policy>& dist)
242{
243 BOOST_MATH_STD_USING // for ADL of std functions
244
245 RealType mu = dist.location();
246 RealType sigma = dist.scale();
247
248 RealType result = 0;
249 if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
250 return result;
251 if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
252 return result;
253
254 return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma);
255}
256
257template <class RealType, class Policy>
258inline RealType mode(const lognormal_distribution<RealType, Policy>& dist)
259{
260 BOOST_MATH_STD_USING // for ADL of std functions
261
262 RealType mu = dist.location();
263 RealType sigma = dist.scale();
264
265 RealType result = 0;
266 if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
267 return result;
268 if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
269 return result;
270
271 return exp(mu - sigma * sigma);
272}
273
274template <class RealType, class Policy>
275inline RealType median(const lognormal_distribution<RealType, Policy>& dist)
276{
277 BOOST_MATH_STD_USING // for ADL of std functions
278 RealType mu = dist.location();
279 return exp(mu); // e^mu
280}
281
282template <class RealType, class Policy>
283inline RealType skewness(const lognormal_distribution<RealType, Policy>& dist)
284{
285 BOOST_MATH_STD_USING // for ADL of std functions
286
287 //RealType mu = dist.location();
288 RealType sigma = dist.scale();
289
290 RealType ss = sigma * sigma;
291 RealType ess = exp(ss);
292
293 RealType result = 0;
294 if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
295 return result;
296 if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
297 return result;
298
299 return (ess + 2) * sqrt(boost::math::expm1(ss, Policy()));
300}
301
302template <class RealType, class Policy>
303inline RealType kurtosis(const lognormal_distribution<RealType, Policy>& dist)
304{
305 BOOST_MATH_STD_USING // for ADL of std functions
306
307 //RealType mu = dist.location();
308 RealType sigma = dist.scale();
309 RealType ss = sigma * sigma;
310
311 RealType result = 0;
312 if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
313 return result;
314 if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
315 return result;
316
317 return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3;
318}
319
320template <class RealType, class Policy>
321inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>& dist)
322{
323 BOOST_MATH_STD_USING // for ADL of std functions
324
325 // RealType mu = dist.location();
326 RealType sigma = dist.scale();
327 RealType ss = sigma * sigma;
328
329 RealType result = 0;
330 if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
331 return result;
332 if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
333 return result;
334
335 return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;
336}
337
f67539c2
TL
338template <class RealType, class Policy>
339inline RealType entropy(const lognormal_distribution<RealType, Policy>& dist)
340{
341 using std::log;
342 RealType mu = dist.location();
343 RealType sigma = dist.scale();
344 return mu + log(constants::two_pi<RealType>()*constants::e<RealType>()*sigma*sigma)/2;
345}
346
7c673cae
FG
347} // namespace math
348} // namespace boost
349
350// This include must be at the end, *after* the accessors
351// for this distribution have been defined, in order to
352// keep compilers that support two-phase lookup happy.
353#include <boost/math/distributions/detail/derived_accessors.hpp>
354
355#endif // BOOST_STATS_STUDENTS_T_HPP
356
357