annotate DEPENDENCIES/generic/include/boost/random/normal_distribution.hpp @ 16:2665513ce2d3

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