Chris@16
|
1 // Copyright Thijs van den Berg, 2008.
|
Chris@16
|
2 // Copyright John Maddock 2008.
|
Chris@16
|
3 // Copyright Paul A. Bristow 2008.
|
Chris@16
|
4
|
Chris@16
|
5 // Use, modification and distribution are subject to the
|
Chris@16
|
6 // Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 // This module implements the Laplace distribution.
|
Chris@16
|
10 // Weisstein, Eric W. "Laplace Distribution." From MathWorld--A Wolfram Web Resource.
|
Chris@16
|
11 // http://mathworld.wolfram.com/LaplaceDistribution.html
|
Chris@16
|
12 // http://en.wikipedia.org/wiki/Laplace_distribution
|
Chris@16
|
13 //
|
Chris@16
|
14 // Abramowitz and Stegun 1972, p 930
|
Chris@16
|
15 // http://www.math.sfu.ca/~cbm/aands/page_930.htm
|
Chris@16
|
16
|
Chris@16
|
17 #ifndef BOOST_STATS_LAPLACE_HPP
|
Chris@16
|
18 #define BOOST_STATS_LAPLACE_HPP
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/math/distributions/detail/common_error_handling.hpp>
|
Chris@16
|
21 #include <boost/math/distributions/complement.hpp>
|
Chris@16
|
22 #include <boost/math/constants/constants.hpp>
|
Chris@16
|
23 #include <limits>
|
Chris@16
|
24
|
Chris@16
|
25 namespace boost{ namespace math{
|
Chris@16
|
26
|
Chris@16
|
27 template <class RealType = double, class Policy = policies::policy<> >
|
Chris@16
|
28 class laplace_distribution
|
Chris@16
|
29 {
|
Chris@16
|
30 public:
|
Chris@16
|
31 // ----------------------------------
|
Chris@16
|
32 // public Types
|
Chris@16
|
33 // ----------------------------------
|
Chris@16
|
34 typedef RealType value_type;
|
Chris@16
|
35 typedef Policy policy_type;
|
Chris@16
|
36
|
Chris@16
|
37 // ----------------------------------
|
Chris@16
|
38 // Constructor(s)
|
Chris@16
|
39 // ----------------------------------
|
Chris@16
|
40 laplace_distribution(RealType l_location = 0, RealType l_scale = 1)
|
Chris@16
|
41 : m_location(l_location), m_scale(l_scale)
|
Chris@16
|
42 {
|
Chris@16
|
43 RealType result;
|
Chris@16
|
44 check_parameters("boost::math::laplace_distribution<%1%>::laplace_distribution()", &result);
|
Chris@16
|
45 }
|
Chris@16
|
46
|
Chris@16
|
47
|
Chris@16
|
48 // ----------------------------------
|
Chris@16
|
49 // Public functions
|
Chris@16
|
50 // ----------------------------------
|
Chris@16
|
51
|
Chris@16
|
52 RealType location() const
|
Chris@16
|
53 {
|
Chris@16
|
54 return m_location;
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 RealType scale() const
|
Chris@16
|
58 {
|
Chris@16
|
59 return m_scale;
|
Chris@16
|
60 }
|
Chris@16
|
61
|
Chris@16
|
62 bool check_parameters(const char* function, RealType* result) const
|
Chris@16
|
63 {
|
Chris@16
|
64 if(false == detail::check_scale(function, m_scale, result, Policy())) return false;
|
Chris@16
|
65 if(false == detail::check_location(function, m_location, result, Policy())) return false;
|
Chris@16
|
66 return true;
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 private:
|
Chris@16
|
70 RealType m_location;
|
Chris@16
|
71 RealType m_scale;
|
Chris@16
|
72 }; // class laplace_distribution
|
Chris@16
|
73
|
Chris@16
|
74 //
|
Chris@16
|
75 // Convenient type synonym for double
|
Chris@16
|
76 typedef laplace_distribution<double> laplace;
|
Chris@16
|
77
|
Chris@16
|
78 //
|
Chris@16
|
79 // Non member functions
|
Chris@16
|
80 template <class RealType, class Policy>
|
Chris@16
|
81 inline const std::pair<RealType, RealType> range(const laplace_distribution<RealType, Policy>&)
|
Chris@16
|
82 {
|
Chris@16
|
83 using boost::math::tools::max_value;
|
Chris@16
|
84 return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 template <class RealType, class Policy>
|
Chris@16
|
88 inline const std::pair<RealType, RealType> support(const laplace_distribution<RealType, Policy>&)
|
Chris@16
|
89 {
|
Chris@16
|
90 using boost::math::tools::max_value;
|
Chris@16
|
91 return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 template <class RealType, class Policy>
|
Chris@16
|
95 inline RealType pdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
Chris@16
|
96 {
|
Chris@16
|
97 BOOST_MATH_STD_USING // for ADL of std functions
|
Chris@16
|
98
|
Chris@16
|
99 // Checking function argument
|
Chris@16
|
100 RealType result = 0;
|
Chris@16
|
101 const char* function = "boost::math::pdf(const laplace_distribution<%1%>&, %1%))";
|
Chris@16
|
102 if (false == dist.check_parameters(function, &result)) return result;
|
Chris@16
|
103 if (false == detail::check_x(function, x, &result, Policy())) return result;
|
Chris@16
|
104
|
Chris@16
|
105 // Special pdf values
|
Chris@16
|
106 if((boost::math::isinf)(x))
|
Chris@16
|
107 return 0; // pdf + and - infinity is zero.
|
Chris@16
|
108
|
Chris@16
|
109 // General case
|
Chris@16
|
110 RealType scale( dist.scale() );
|
Chris@16
|
111 RealType location( dist.location() );
|
Chris@16
|
112
|
Chris@16
|
113 RealType exponent = x - location;
|
Chris@16
|
114 if (exponent>0) exponent = -exponent;
|
Chris@16
|
115 exponent /= scale;
|
Chris@16
|
116
|
Chris@16
|
117 result = exp(exponent);
|
Chris@16
|
118 result /= 2 * scale;
|
Chris@16
|
119
|
Chris@16
|
120 return result;
|
Chris@16
|
121 } // pdf
|
Chris@16
|
122
|
Chris@16
|
123 template <class RealType, class Policy>
|
Chris@16
|
124 inline RealType cdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
Chris@16
|
125 {
|
Chris@16
|
126 BOOST_MATH_STD_USING // for ADL of std functions
|
Chris@16
|
127
|
Chris@16
|
128 // Checking function argument
|
Chris@16
|
129 RealType result = 0;
|
Chris@16
|
130 const char* function = "boost::math::cdf(const laplace_distribution<%1%>&, %1%)";
|
Chris@16
|
131 if (false == dist.check_parameters(function, &result)) return result;
|
Chris@16
|
132 if (false == detail::check_x(function, x, &result, Policy())) return result;
|
Chris@16
|
133
|
Chris@16
|
134 // Special cdf values:
|
Chris@16
|
135 if((boost::math::isinf)(x))
|
Chris@16
|
136 {
|
Chris@16
|
137 if(x < 0) return 0; // -infinity
|
Chris@16
|
138 return 1; // + infinity
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 // General cdf values
|
Chris@16
|
142 RealType scale( dist.scale() );
|
Chris@16
|
143 RealType location( dist.location() );
|
Chris@16
|
144
|
Chris@16
|
145 if (x < location)
|
Chris@16
|
146 {
|
Chris@16
|
147 result = exp( (x-location)/scale )/2;
|
Chris@16
|
148 }
|
Chris@16
|
149 else
|
Chris@16
|
150 {
|
Chris@16
|
151 result = 1 - exp( (location-x)/scale )/2;
|
Chris@16
|
152 }
|
Chris@16
|
153 return result;
|
Chris@16
|
154 } // cdf
|
Chris@16
|
155
|
Chris@16
|
156
|
Chris@16
|
157 template <class RealType, class Policy>
|
Chris@16
|
158 inline RealType quantile(const laplace_distribution<RealType, Policy>& dist, const RealType& p)
|
Chris@16
|
159 {
|
Chris@16
|
160 BOOST_MATH_STD_USING // for ADL of std functions.
|
Chris@16
|
161
|
Chris@16
|
162 // Checking function argument
|
Chris@16
|
163 RealType result = 0;
|
Chris@16
|
164 const char* function = "boost::math::quantile(const laplace_distribution<%1%>&, %1%)";
|
Chris@16
|
165 if (false == dist.check_parameters(function, &result)) return result;
|
Chris@16
|
166 if(false == detail::check_probability(function, p, &result, Policy())) return result;
|
Chris@16
|
167
|
Chris@16
|
168 // Extreme values of p:
|
Chris@16
|
169 if(p == 0)
|
Chris@16
|
170 {
|
Chris@16
|
171 result = policies::raise_overflow_error<RealType>(function,
|
Chris@16
|
172 "probability parameter is 0, but must be > 0!", Policy());
|
Chris@16
|
173 return -result; // -std::numeric_limits<RealType>::infinity();
|
Chris@16
|
174 }
|
Chris@16
|
175
|
Chris@16
|
176 if(p == 1)
|
Chris@16
|
177 {
|
Chris@16
|
178 result = policies::raise_overflow_error<RealType>(function,
|
Chris@16
|
179 "probability parameter is 1, but must be < 1!", Policy());
|
Chris@16
|
180 return result; // std::numeric_limits<RealType>::infinity();
|
Chris@16
|
181 }
|
Chris@16
|
182 // Calculate Quantile
|
Chris@16
|
183 RealType scale( dist.scale() );
|
Chris@16
|
184 RealType location( dist.location() );
|
Chris@16
|
185
|
Chris@16
|
186 if (p - 0.5 < 0.0)
|
Chris@16
|
187 result = location + scale*log( static_cast<RealType>(p*2) );
|
Chris@16
|
188 else
|
Chris@16
|
189 result = location - scale*log( static_cast<RealType>(-p*2 + 2) );
|
Chris@16
|
190
|
Chris@16
|
191 return result;
|
Chris@16
|
192 } // quantile
|
Chris@16
|
193
|
Chris@16
|
194
|
Chris@16
|
195 template <class RealType, class Policy>
|
Chris@16
|
196 inline RealType cdf(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
Chris@16
|
197 {
|
Chris@16
|
198 BOOST_MATH_STD_USING // for ADL of std functions
|
Chris@16
|
199
|
Chris@16
|
200 RealType scale = c.dist.scale();
|
Chris@16
|
201 RealType location = c.dist.location();
|
Chris@16
|
202 RealType x = c.param;
|
Chris@16
|
203
|
Chris@16
|
204 // Checking function argument
|
Chris@16
|
205 RealType result = 0;
|
Chris@16
|
206 const char* function = "boost::math::cdf(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
Chris@16
|
207 if(false == detail::check_x(function, x, &result, Policy()))return result;
|
Chris@16
|
208
|
Chris@16
|
209 // Calculate complement of cdf.
|
Chris@16
|
210
|
Chris@16
|
211 // Special cdf value
|
Chris@16
|
212 if((boost::math::isinf)(x))
|
Chris@16
|
213 {
|
Chris@16
|
214 if(x < 0) return 1; // cdf complement -infinity is unity.
|
Chris@16
|
215 return 0; // cdf complement +infinity is zero.
|
Chris@16
|
216 }
|
Chris@16
|
217
|
Chris@16
|
218 // Cdf interval value.
|
Chris@16
|
219 if (-x < -location)
|
Chris@16
|
220 {
|
Chris@16
|
221 result = exp( (-x+location)/scale )/2;
|
Chris@16
|
222 }
|
Chris@16
|
223 else
|
Chris@16
|
224 {
|
Chris@16
|
225 result = 1 - exp( (-location+x)/scale )/2;
|
Chris@16
|
226 }
|
Chris@16
|
227 return result;
|
Chris@16
|
228 } // cdf complement
|
Chris@16
|
229
|
Chris@16
|
230
|
Chris@16
|
231 template <class RealType, class Policy>
|
Chris@16
|
232 inline RealType quantile(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
Chris@16
|
233 {
|
Chris@16
|
234 BOOST_MATH_STD_USING // for ADL of std functions.
|
Chris@16
|
235
|
Chris@16
|
236 // Calculate quantile.
|
Chris@16
|
237 RealType scale = c.dist.scale();
|
Chris@16
|
238 RealType location = c.dist.location();
|
Chris@16
|
239 RealType q = c.param;
|
Chris@16
|
240
|
Chris@16
|
241 // Checking function argument.
|
Chris@16
|
242 RealType result = 0;
|
Chris@16
|
243 const char* function = "quantile(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
Chris@16
|
244 if(false == detail::check_probability(function, q, &result, Policy())) return result;
|
Chris@16
|
245
|
Chris@16
|
246
|
Chris@16
|
247 // extreme values
|
Chris@16
|
248 if(q == 0) return std::numeric_limits<RealType>::infinity();
|
Chris@16
|
249 if(q == 1) return -std::numeric_limits<RealType>::infinity();
|
Chris@16
|
250
|
Chris@16
|
251 if (0.5 - q < 0.0)
|
Chris@16
|
252 result = location + scale*log( static_cast<RealType>(-q*2 + 2) );
|
Chris@16
|
253 else
|
Chris@16
|
254 result = location - scale*log( static_cast<RealType>(q*2) );
|
Chris@16
|
255
|
Chris@16
|
256
|
Chris@16
|
257 return result;
|
Chris@16
|
258 } // quantile
|
Chris@16
|
259
|
Chris@16
|
260 template <class RealType, class Policy>
|
Chris@16
|
261 inline RealType mean(const laplace_distribution<RealType, Policy>& dist)
|
Chris@16
|
262 {
|
Chris@16
|
263 return dist.location();
|
Chris@16
|
264 }
|
Chris@16
|
265
|
Chris@16
|
266 template <class RealType, class Policy>
|
Chris@16
|
267 inline RealType standard_deviation(const laplace_distribution<RealType, Policy>& dist)
|
Chris@16
|
268 {
|
Chris@16
|
269 return constants::root_two<RealType>() * dist.scale();
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 template <class RealType, class Policy>
|
Chris@16
|
273 inline RealType mode(const laplace_distribution<RealType, Policy>& dist)
|
Chris@16
|
274 {
|
Chris@16
|
275 return dist.location();
|
Chris@16
|
276 }
|
Chris@16
|
277
|
Chris@16
|
278 template <class RealType, class Policy>
|
Chris@16
|
279 inline RealType median(const laplace_distribution<RealType, Policy>& dist)
|
Chris@16
|
280 {
|
Chris@16
|
281 return dist.location();
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 template <class RealType, class Policy>
|
Chris@16
|
285 inline RealType skewness(const laplace_distribution<RealType, Policy>& /*dist*/)
|
Chris@16
|
286 {
|
Chris@16
|
287 return 0;
|
Chris@16
|
288 }
|
Chris@16
|
289
|
Chris@16
|
290 template <class RealType, class Policy>
|
Chris@16
|
291 inline RealType kurtosis(const laplace_distribution<RealType, Policy>& /*dist*/)
|
Chris@16
|
292 {
|
Chris@16
|
293 return 6;
|
Chris@16
|
294 }
|
Chris@16
|
295
|
Chris@16
|
296 template <class RealType, class Policy>
|
Chris@16
|
297 inline RealType kurtosis_excess(const laplace_distribution<RealType, Policy>& /*dist*/)
|
Chris@16
|
298 {
|
Chris@16
|
299 return 3;
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 } // namespace math
|
Chris@16
|
303 } // namespace boost
|
Chris@16
|
304
|
Chris@16
|
305 // This include must be at the end, *after* the accessors
|
Chris@16
|
306 // for this distribution have been defined, in order to
|
Chris@16
|
307 // keep compilers that support two-phase lookup happy.
|
Chris@16
|
308 #include <boost/math/distributions/detail/derived_accessors.hpp>
|
Chris@16
|
309
|
Chris@16
|
310 #endif // BOOST_STATS_LAPLACE_HPP
|
Chris@16
|
311
|
Chris@16
|
312
|