]> git.donarmstrong.com Git - rsem.git/blob - boost/random/normal_distribution.hpp
Updated boost to v1.55.0
[rsem.git] / boost / random / normal_distribution.hpp
1 /* boost random/normal_distribution.hpp header file
2  *
3  * Copyright Jens Maurer 2000-2001
4  * Copyright Steven Watanabe 2010-2011
5  * Distributed under the Boost Software License, Version 1.0. (See
6  * accompanying file LICENSE_1_0.txt or copy at
7  * http://www.boost.org/LICENSE_1_0.txt)
8  *
9  * See http://www.boost.org for most recent version including documentation.
10  *
11  * $Id: normal_distribution.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
12  *
13  * Revision history
14  *  2001-02-18  moved to individual header files
15  */
16
17 #ifndef BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
18 #define BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
19
20 #include <boost/config/no_tr1/cmath.hpp>
21 #include <istream>
22 #include <iosfwd>
23 #include <boost/assert.hpp>
24 #include <boost/limits.hpp>
25 #include <boost/static_assert.hpp>
26 #include <boost/random/detail/config.hpp>
27 #include <boost/random/detail/operators.hpp>
28 #include <boost/random/uniform_01.hpp>
29
30 namespace boost {
31 namespace random {
32
33 // deterministic Box-Muller method, uses trigonometric functions
34
35 /**
36  * Instantiations of class template normal_distribution model a
37  * \random_distribution. Such a distribution produces random numbers
38  * @c x distributed with probability density function
39  * \f$\displaystyle p(x) =
40  *   \frac{1}{\sqrt{2\pi\sigma}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
41  * \f$,
42  * where mean and sigma are the parameters of the distribution.
43  */
44 template<class RealType = double>
45 class normal_distribution
46 {
47 public:
48     typedef RealType input_type;
49     typedef RealType result_type;
50
51     class param_type {
52     public:
53         typedef normal_distribution distribution_type;
54
55         /**
56          * Constructs a @c param_type with a given mean and
57          * standard deviation.
58          *
59          * Requires: sigma >= 0
60          */
61         explicit param_type(RealType mean_arg = RealType(0.0),
62                             RealType sigma_arg = RealType(1.0))
63           : _mean(mean_arg),
64             _sigma(sigma_arg)
65         {}
66
67         /** Returns the mean of the distribution. */
68         RealType mean() const { return _mean; }
69
70         /** Returns the standand deviation of the distribution. */
71         RealType sigma() const { return _sigma; }
72
73         /** Writes a @c param_type to a @c std::ostream. */
74         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
75         { os << parm._mean << " " << parm._sigma ; return os; }
76
77         /** Reads a @c param_type from a @c std::istream. */
78         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
79         { is >> parm._mean >> std::ws >> parm._sigma; return is; }
80
81         /** Returns true if the two sets of parameters are the same. */
82         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
83         { return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
84         
85         /** Returns true if the two sets of parameters are the different. */
86         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
87
88     private:
89         RealType _mean;
90         RealType _sigma;
91     };
92
93     /**
94      * Constructs a @c normal_distribution object. @c mean and @c sigma are
95      * the parameters for the distribution.
96      *
97      * Requires: sigma >= 0
98      */
99     explicit normal_distribution(const RealType& mean_arg = RealType(0.0),
100                                  const RealType& sigma_arg = RealType(1.0))
101       : _mean(mean_arg), _sigma(sigma_arg),
102         _r1(0), _r2(0), _cached_rho(0), _valid(false)
103     {
104         BOOST_ASSERT(_sigma >= RealType(0));
105     }
106
107     /**
108      * Constructs a @c normal_distribution object from its parameters.
109      */
110     explicit normal_distribution(const param_type& parm)
111       : _mean(parm.mean()), _sigma(parm.sigma()),
112         _r1(0), _r2(0), _cached_rho(0), _valid(false)
113     {}
114
115     /**  Returns the mean of the distribution. */
116     RealType mean() const { return _mean; }
117     /** Returns the standard deviation of the distribution. */
118     RealType sigma() const { return _sigma; }
119
120     /** Returns the smallest value that the distribution can produce. */
121     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
122     { return -std::numeric_limits<RealType>::infinity(); }
123     /** Returns the largest value that the distribution can produce. */
124     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
125     { return std::numeric_limits<RealType>::infinity(); }
126
127     /** Returns the parameters of the distribution. */
128     param_type param() const { return param_type(_mean, _sigma); }
129     /** Sets the parameters of the distribution. */
130     void param(const param_type& parm)
131     {
132         _mean = parm.mean();
133         _sigma = parm.sigma();
134         _valid = false;
135     }
136
137     /**
138      * Effects: Subsequent uses of the distribution do not depend
139      * on values produced by any engine prior to invoking reset.
140      */
141     void reset() { _valid = false; }
142
143     /**  Returns a normal variate. */
144     template<class Engine>
145     result_type operator()(Engine& eng)
146     {
147         using std::sqrt;
148         using std::log;
149         using std::sin;
150         using std::cos;
151
152         if(!_valid) {
153             _r1 = boost::uniform_01<RealType>()(eng);
154             _r2 = boost::uniform_01<RealType>()(eng);
155             _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2));
156             _valid = true;
157         } else {
158             _valid = false;
159         }
160         // Can we have a boost::mathconst please?
161         const result_type pi = result_type(3.14159265358979323846);
162
163         return _cached_rho * (_valid ?
164                               cos(result_type(2)*pi*_r1) :
165                               sin(result_type(2)*pi*_r1))
166             * _sigma + _mean;
167     }
168
169     /** Returns a normal variate with parameters specified by @c param. */
170     template<class URNG>
171     result_type operator()(URNG& urng, const param_type& parm)
172     {
173         return normal_distribution(parm)(urng);
174     }
175
176     /** Writes a @c normal_distribution to a @c std::ostream. */
177     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution, nd)
178     {
179         os << nd._mean << " " << nd._sigma << " "
180            << nd._valid << " " << nd._cached_rho << " " << nd._r1;
181         return os;
182     }
183
184     /** Reads a @c normal_distribution from a @c std::istream. */
185     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution, nd)
186     {
187         is >> std::ws >> nd._mean >> std::ws >> nd._sigma
188            >> std::ws >> nd._valid >> std::ws >> nd._cached_rho
189            >> std::ws >> nd._r1;
190         return is;
191     }
192
193     /**
194      * Returns true if the two instances of @c normal_distribution will
195      * return identical sequences of values given equal generators.
196      */
197     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution, lhs, rhs)
198     {
199         return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma
200             && lhs._valid == rhs._valid
201             && (!lhs._valid || (lhs._r1 == rhs._r1 && lhs._r2 == rhs._r2));
202     }
203
204     /**
205      * Returns true if the two instances of @c normal_distribution will
206      * return different sequences of values given equal generators.
207      */
208     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(normal_distribution)
209
210 private:
211     RealType _mean, _sigma;
212     RealType _r1, _r2, _cached_rho;
213     bool _valid;
214
215 };
216
217 } // namespace random
218
219 using random::normal_distribution;
220
221 } // namespace boost
222
223 #endif // BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP