Ticket #6804: laplace_distribution.hpp

File laplace_distribution.hpp, 5.9 KB (added by Yan Zhou <zhouyan@…>, 11 years ago)
Line 
1#ifndef BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP
2#define BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP
3
4#include <boost/config/no_tr1/cmath.hpp>
5#include <istream>
6#include <iosfwd>
7#include <boost/assert.hpp>
8#include <boost/limits.hpp>
9#include <boost/static_assert.hpp>
10#include <boost/math/special_functions/log1p.hpp>
11#include <boost/random/detail/config.hpp>
12#include <boost/random/detail/operators.hpp>
13#include <boost/random/uniform_01.hpp>
14
15namespace boost { namespace random {
16
17/**
18 * Instantiations of class template laplace_distribution model a
19 * \random_distribiton. Such a distribution produces random numbers @c x
20 * distributed with probability density function
21 * \f$\displaystyle p(x) =
22 * \frac{1}{2b}\exp(-|x-\mu|/b)
23 * \f$,
24 * where location and scale are the paramters of the distributions.
25 */
26template <typename RealType = double>
27class laplace_distribution
28{
29 public :
30
31 typedef RealType input_type;
32 typedef RealType result_type;
33
34 class param_type
35 {
36 public :
37
38 typedef laplace_distribution distribution_type;
39
40 /**
41 * Constructs a @c param_type with a given location and scale.
42 *
43 * Requires: scale >= 0
44 */
45 explicit param_type (
46 RealType location_arg = RealType(0.0),
47 RealType scale_arg = RealType(1.0)) :
48 _location(location_arg), _scale(scale_arg) {}
49
50 /** Returns the location of the distribution. */
51 RealType location () const {return _location;}
52
53 /** Returns the scale of the distribution. */
54 RealType scale () const {return _scale;}
55
56 /** Writes a @c param_type to a @c std::ostream. */
57 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
58 { os << parm._location << " " << parm._scale ; return os; }
59
60 /** Reads a @c param_type from a @c std::istream. */
61 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
62 { is >> parm._location >> std::ws >> parm._scale; return is; }
63
64 /** Returns true if the two sets of parameters are the same. */
65 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
66 { return lhs._location == rhs._location && lhs._scale == rhs._scale; }
67
68 /** Returns true if the two sets of parameters are the different. */
69 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
70 private :
71
72 RealType _location;
73 RealType _scale;
74 }; // class param_type
75
76 /**
77 * Constructs a @c laplace_distribution objet. @c location and @c scale
78 * are the parameters for the distribution.
79 *
80 * Requires: scale > 0
81 */
82 explicit laplace_distribution (
83 const RealType &location_arg = RealType(1.0),
84 const RealType &scale_arg = RealType(1.0)) :
85 _location(location_arg), _scale(scale_arg)
86 {
87 BOOST_ASSERT(_scale >= RealType(0.0));
88 }
89
90 /**
91 * Constructs a @c laplace_distribution object from its parameters.
92 */
93 explicit laplace_distribution (const param_type &parm) :
94 _location(parm.location()), _scale(parm.scale())
95 {
96 BOOST_ASSERT(_scale > RealType(0.0));
97 }
98
99 /** Returns the location of the distribution. */
100 RealType location () const {return _location;}
101
102 /** Returns the scale of the distribution. */
103 RealType scale () const {return _scale;}
104
105 /** Returns the smallest value that the distribution can produce. */
106 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
107 {return -std::numeric_limits<RealType>::infinity();}
108
109 /** Returns the largest value that the distribution can produce. */
110 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
111 {return std::numeric_limits<RealType>::infinity();}
112
113 /** Returns the parameters of the distribution. */
114 param_type param () const {return param_type(_location, _scale);}
115
116 /** Sets the parameters of the distribution. */
117 void param (const param_type &parm)
118 {
119 _location = parm.location();
120 _scale = parm.scale();
121 }
122
123 /**
124 * Effects: Subsequent uses of the distribution do not depend
125 * on values produced by any engine prior to invoking reset.
126 */
127 void reset () {}
128
129 /** Returns a laplace variate. */
130 template <typename Engine>
131 result_type operator() (Engine &eng)
132 {
133 using std::abs;
134
135 RealType u = boost::random::uniform_01<RealType>()(eng) - 0.5;
136 RealType r = -2 * std::abs(u);
137
138 r = boost::math::log1p(r);
139 r = u > 0 ? r : -r;
140
141 return _location - _scale * r;
142 }
143
144 /** Returns a laplace variate with parameters specified by @c param. */
145 template <typename URNG>
146 result_type operator() (URNG &urng, const param_type &parm)
147 {
148 return laplace_distribution(parm)(urng);
149 }
150
151 /** Writes a @c laplace_distribution to a @c std::ostream. */
152 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, laplace_distribution, nd)
153 {
154 os << nd._location << " " << nd._scale << " ";
155 return os;
156 }
157
158 /** Reads a @c laplace_distribution from a @c std::istream. */
159 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, laplace_distribution, nd)
160 {
161 is >> std::ws >> nd._location >> std::ws >> nd._scale;
162 return is;
163 }
164
165 /**
166 * Returns true if the two instances of @c laplace_distribution will
167 * return identical sequences of values given equal generators.
168 */
169 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(laplace_distribution, lhs, rhs)
170 {
171 return lhs._location == rhs._location && lhs._scale == rhs._scale;
172 }
173
174 /**
175 * Returns true if the two instances of @c laplace_distribution will
176 * return different sequences of values given equal generators.
177 */
178 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(laplace_distribution)
179
180 private :
181
182 RealType _location;
183 RealType _scale;
184}; // class laplace_distribution
185
186} // namespace random
187
188using random::laplace_distribution;
189
190} // namespace boost
191
192#endif // BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP