To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / any / include / boost / math / distributions / lognormal.hpp @ 160:cff480c41f97

History | View | Annotate | Download (11.5 KB)

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

    
20
namespace boost{ namespace math
21
{
22
namespace 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

    
44
template <class RealType = double, class Policy = policies::policy<> >
45
class lognormal_distribution
46
{
47
public:
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
   }
68
private:
69
   //
70
   // Data members:
71
   //
72
   RealType m_location;  // distribution location.
73
   RealType m_scale;     // distribution scale.
74
};
75

    
76
typedef lognormal_distribution<double> lognormal;
77

    
78
template <class RealType, class Policy>
79
inline const std::pair<RealType, RealType> range(const lognormal_distribution<RealType, Policy>& /*dist*/)
80
{ // Range of permissible values for random variable x is >0 to +infinity.
81
   using boost::math::tools::max_value;
82
   return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
83
}
84

    
85
template <class RealType, class Policy>
86
inline const std::pair<RealType, RealType> support(const lognormal_distribution<RealType, Policy>& /*dist*/)
87
{ // Range of supported values for random variable x.
88
   // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
89
   using boost::math::tools::max_value;
90
   return std::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>());
91
}
92

    
93
template <class RealType, class Policy>
94
RealType pdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
95
{
96
   BOOST_MATH_STD_USING  // for ADL of std functions
97

    
98
   RealType mu = dist.location();
99
   RealType sigma = dist.scale();
100

    
101
   static const char* function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)";
102

    
103
   RealType result = 0;
104
   if(0 == detail::check_scale(function, sigma, &result, Policy()))
105
      return result;
106
   if(0 == detail::check_location(function, mu, &result, Policy()))
107
      return result;
108
   if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
109
      return result;
110

    
111
   if(x == 0)
112
      return 0;
113

    
114
   RealType exponent = log(x) - mu;
115
   exponent *= -exponent;
116
   exponent /= 2 * sigma * sigma;
117

    
118
   result = exp(exponent);
119
   result /= sigma * sqrt(2 * constants::pi<RealType>()) * x;
120

    
121
   return result;
122
}
123

    
124
template <class RealType, class Policy>
125
inline RealType cdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
126
{
127
   BOOST_MATH_STD_USING  // for ADL of std functions
128

    
129
   static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
130

    
131
   RealType result = 0;
132
   if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
133
      return result;
134
   if(0 == detail::check_location(function, dist.location(), &result, Policy()))
135
      return result;
136
   if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
137
      return result;
138

    
139
   if(x == 0)
140
      return 0;
141

    
142
   normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
143
   return cdf(norm, log(x));
144
}
145

    
146
template <class RealType, class Policy>
147
inline RealType quantile(const lognormal_distribution<RealType, Policy>& dist, const RealType& p)
148
{
149
   BOOST_MATH_STD_USING  // for ADL of std functions
150

    
151
   static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
152

    
153
   RealType result = 0;
154
   if(0 == detail::check_scale(function, dist.scale(), &result, Policy()))
155
      return result;
156
   if(0 == detail::check_location(function, dist.location(), &result, Policy()))
157
      return result;
158
   if(0 == detail::check_probability(function, p, &result, Policy()))
159
      return result;
160

    
161
   if(p == 0)
162
      return 0;
163
   if(p == 1)
164
      return policies::raise_overflow_error<RealType>(function, 0, Policy());
165

    
166
   normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
167
   return exp(quantile(norm, p));
168
}
169

    
170
template <class RealType, class Policy>
171
inline RealType cdf(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
172
{
173
   BOOST_MATH_STD_USING  // for ADL of std functions
174

    
175
   static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
176

    
177
   RealType result = 0;
178
   if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
179
      return result;
180
   if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
181
      return result;
182
   if(0 == detail::check_lognormal_x(function, c.param, &result, Policy()))
183
      return result;
184

    
185
   if(c.param == 0)
186
      return 1;
187

    
188
   normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
189
   return cdf(complement(norm, log(c.param)));
190
}
191

    
192
template <class RealType, class Policy>
193
inline RealType quantile(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
194
{
195
   BOOST_MATH_STD_USING  // for ADL of std functions
196

    
197
   static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
198

    
199
   RealType result = 0;
200
   if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy()))
201
      return result;
202
   if(0 == detail::check_location(function, c.dist.location(), &result, Policy()))
203
      return result;
204
   if(0 == detail::check_probability(function, c.param, &result, Policy()))
205
      return result;
206

    
207
   if(c.param == 1)
208
      return 0;
209
   if(c.param == 0)
210
      return policies::raise_overflow_error<RealType>(function, 0, Policy());
211

    
212
   normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
213
   return exp(quantile(complement(norm, c.param)));
214
}
215

    
216
template <class RealType, class Policy>
217
inline RealType mean(const lognormal_distribution<RealType, Policy>& dist)
218
{
219
   BOOST_MATH_STD_USING  // for ADL of std functions
220

    
221
   RealType mu = dist.location();
222
   RealType sigma = dist.scale();
223

    
224
   RealType result = 0;
225
   if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
226
      return result;
227
   if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
228
      return result;
229

    
230
   return exp(mu + sigma * sigma / 2);
231
}
232

    
233
template <class RealType, class Policy>
234
inline RealType variance(const lognormal_distribution<RealType, Policy>& dist)
235
{
236
   BOOST_MATH_STD_USING  // for ADL of std functions
237

    
238
   RealType mu = dist.location();
239
   RealType sigma = dist.scale();
240

    
241
   RealType result = 0;
242
   if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
243
      return result;
244
   if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
245
      return result;
246

    
247
   return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma);
248
}
249

    
250
template <class RealType, class Policy>
251
inline RealType mode(const lognormal_distribution<RealType, Policy>& dist)
252
{
253
   BOOST_MATH_STD_USING  // for ADL of std functions
254

    
255
   RealType mu = dist.location();
256
   RealType sigma = dist.scale();
257

    
258
   RealType result = 0;
259
   if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
260
      return result;
261
   if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy()))
262
      return result;
263

    
264
   return exp(mu - sigma * sigma);
265
}
266

    
267
template <class RealType, class Policy>
268
inline RealType median(const lognormal_distribution<RealType, Policy>& dist)
269
{
270
   BOOST_MATH_STD_USING  // for ADL of std functions
271
   RealType mu = dist.location();
272
   return exp(mu); // e^mu
273
}
274

    
275
template <class RealType, class Policy>
276
inline RealType skewness(const lognormal_distribution<RealType, Policy>& dist)
277
{
278
   BOOST_MATH_STD_USING  // for ADL of std functions
279

    
280
   //RealType mu = dist.location();
281
   RealType sigma = dist.scale();
282

    
283
   RealType ss = sigma * sigma;
284
   RealType ess = exp(ss);
285

    
286
   RealType result = 0;
287
   if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
288
      return result;
289
   if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
290
      return result;
291

    
292
   return (ess + 2) * sqrt(boost::math::expm1(ss, Policy()));
293
}
294

    
295
template <class RealType, class Policy>
296
inline RealType kurtosis(const lognormal_distribution<RealType, Policy>& dist)
297
{
298
   BOOST_MATH_STD_USING  // for ADL of std functions
299

    
300
   //RealType mu = dist.location();
301
   RealType sigma = dist.scale();
302
   RealType ss = sigma * sigma;
303

    
304
   RealType result = 0;
305
   if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
306
      return result;
307
   if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
308
      return result;
309

    
310
   return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3;
311
}
312

    
313
template <class RealType, class Policy>
314
inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>& dist)
315
{
316
   BOOST_MATH_STD_USING  // for ADL of std functions
317

    
318
   // RealType mu = dist.location();
319
   RealType sigma = dist.scale();
320
   RealType ss = sigma * sigma;
321

    
322
   RealType result = 0;
323
   if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
324
      return result;
325
   if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy()))
326
      return result;
327

    
328
   return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;
329
}
330

    
331
} // namespace math
332
} // namespace boost
333

    
334
// This include must be at the end, *after* the accessors
335
// for this distribution have been defined, in order to
336
// keep compilers that support two-phase lookup happy.
337
#include <boost/math/distributions/detail/derived_accessors.hpp>
338

    
339
#endif // BOOST_STATS_STUDENTS_T_HPP
340

    
341