PageRenderTime 31ms CodeModel.GetById 14ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/random/lognormal_distribution.hpp

http://hadesmem.googlecode.com/
C++ Header | 254 lines | 137 code | 35 blank | 82 comment | 4 complexity | 6f0d23370dd9fa2164eb5f133a5a43ad MD5 | raw file
  1/* boost random/lognormal_distribution.hpp header file
  2 *
  3 * Copyright Jens Maurer 2000-2001
  4 * Copyright Steven Watanabe 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: lognormal_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_LOGNORMAL_DISTRIBUTION_HPP
 18#define BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
 19
 20#include <boost/config/no_tr1/cmath.hpp>      // std::exp, std::sqrt
 21#include <cassert>
 22#include <iosfwd>
 23#include <istream>
 24#include <boost/limits.hpp>
 25#include <boost/random/detail/config.hpp>
 26#include <boost/random/detail/operators.hpp>
 27#include <boost/random/normal_distribution.hpp>
 28
 29namespace boost {
 30namespace random {
 31
 32/**
 33 * Instantiations of class template lognormal_distribution model a
 34 * \random_distribution. Such a distribution produces random numbers
 35 * with \f$\displaystyle p(x) = \frac{1}{x s \sqrt{2\pi}} e^{\frac{-\left(\log(x)-m\right)^2}{2s^2}}\f$
 36 * for x > 0.
 37 *
 38 * @xmlwarning
 39 * This distribution has been updated to match the C++ standard.
 40 * Its behavior has changed from the original
 41 * boost::lognormal_distribution.  A backwards compatible
 42 * version is provided in namespace boost.
 43 * @endxmlwarning
 44 */
 45template<class RealType = double>
 46class lognormal_distribution
 47{
 48public:
 49    typedef typename normal_distribution<RealType>::input_type input_type;
 50    typedef RealType result_type;
 51
 52    class param_type
 53    {
 54    public:
 55
 56        typedef lognormal_distribution distribution_type;
 57
 58        /** Constructs the parameters of a lognormal_distribution. */
 59        explicit param_type(RealType m_arg = RealType(0.0),
 60                            RealType s_arg = RealType(1.0))
 61          : _m(m_arg), _s(s_arg) {}
 62
 63        /** Returns the "m" parameter of the distribution. */
 64        RealType m() const { return _m; }
 65
 66        /** Returns the "s" parameter of the distribution. */
 67        RealType s() const { return _s; }
 68
 69        /** Writes the parameters to a std::ostream. */
 70        BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
 71        {
 72            os << parm._m << " " << parm._s;
 73            return os;
 74        }
 75
 76        /** Reads the parameters from a std::istream. */
 77        BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
 78        {
 79            is >> parm._m >> std::ws >> parm._s;
 80            return is;
 81        }
 82
 83        /** Returns true if the two sets of parameters are equal. */
 84        BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
 85        { return lhs._m == rhs._m && lhs._s == rhs._s; }
 86
 87        /** Returns true if the two sets of parameters are different. */
 88        BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
 89
 90    private:
 91        RealType _m;
 92        RealType _s;
 93    };
 94
 95    /**
 96     * Constructs a lognormal_distribution. @c m and @c s are the
 97     * parameters of the distribution.
 98     */
 99    explicit lognormal_distribution(RealType m_arg = RealType(0.0),
100                                    RealType s_arg = RealType(1.0))
101      : _normal(m_arg, s_arg) {}
102
103    /**
104     * Constructs a lognormal_distribution from its parameters.
105     */
106    explicit lognormal_distribution(const param_type& parm)
107      : _normal(parm.m(), parm.s()) {}
108
109    // compiler-generated copy ctor and assignment operator are fine
110
111    /** Returns the m parameter of the distribution. */
112    RealType m() const { return _normal.mean(); }
113    /** Returns the s parameter of the distribution. */
114    RealType s() const { return _normal.sigma(); }
115
116    /** Returns the smallest value that the distribution can produce. */
117    RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
118    { return RealType(0); }
119    /** Returns the largest value that the distribution can produce. */
120    RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
121    { return (std::numeric_limits<RealType>::infinity)(); }
122
123    /** Returns the parameters of the distribution. */
124    param_type param() const { return param_type(m(), s()); }
125    /** Sets the parameters of the distribution. */
126    void param(const param_type& parm)
127    {
128        typedef normal_distribution<RealType> normal_type;
129        typename normal_type::param_type normal_param(parm.m(), parm.s());
130        _normal.param(normal_param);
131    }
132    
133    /**
134     * Effects: Subsequent uses of the distribution do not depend
135     * on values produced by any engine prior to invoking reset.
136     */
137    void reset() { _normal.reset(); }
138
139    /**
140     * Returns a random variate distributed according to the
141     * lognormal distribution.
142     */
143    template<class Engine>
144    result_type operator()(Engine& eng)
145    {
146        using std::exp;
147        return exp(_normal(eng));
148    }
149
150    /**
151     * Returns a random variate distributed according to the
152     * lognormal distribution with parameters specified by param.
153     */
154    template<class Engine>
155    result_type operator()(Engine& eng, const param_type& parm)
156    { return lognormal_distribution(parm)(eng); }
157
158    /** Writes the distribution to a @c std::ostream. */
159    BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
160    {
161        os << ld._normal;
162        return os;
163    }
164
165    /** Reads the distribution from a @c std::istream. */
166    BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
167    {
168        is >> ld._normal;
169        return is;
170    }
171
172    /**
173     * Returns true if the two distributions will produce identical
174     * sequences of values given equal generators.
175     */
176    BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lognormal_distribution, lhs, rhs)
177    { return lhs._normal == rhs._normal; }
178
179    /**
180     * Returns true if the two distributions may produce different
181     * sequences of values given equal generators.
182     */
183    BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lognormal_distribution)
184
185private:
186    normal_distribution<result_type> _normal;
187};
188
189} // namespace random
190
191/// \cond show_deprecated
192
193/**
194 * Provided for backwards compatibility.  This class is
195 * deprecated.  It provides the old behavior of lognormal_distribution with
196 * \f$\displaystyle p(x) = \frac{1}{x \sigma_N \sqrt{2\pi}} e^{\frac{-\left(\log(x)-\mu_N\right)^2}{2\sigma_N^2}}\f$
197 * for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
198 * \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$.
199 */
200template<class RealType = double>
201class lognormal_distribution
202{
203public:
204    typedef typename normal_distribution<RealType>::input_type input_type;
205    typedef RealType result_type;
206
207    lognormal_distribution(RealType mean_arg = RealType(1.0),
208                           RealType sigma_arg = RealType(1.0))
209      : _mean(mean_arg), _sigma(sigma_arg)
210    {
211        init();
212    }
213    RealType mean() const { return _mean; }
214    RealType sigma() const { return _sigma; }
215    void reset() { _normal.reset(); }
216    template<class Engine>
217    RealType operator()(Engine& eng)
218    {
219        using std::exp;
220        return exp(_normal(eng) * _nsigma + _nmean);
221    }
222    BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
223    {
224        os << ld._normal << " " << ld._mean << " " << ld._sigma;
225        return os;
226    }
227    BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
228    {
229        is >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
230        ld.init();
231        return is;
232    }
233private:
234    /// \cond show_private
235    void init()
236    {
237        using std::log;
238        using std::sqrt;
239        _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
240        _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
241    }
242    RealType _mean;
243    RealType _sigma;
244    RealType _nmean;
245    RealType _nsigma;
246    normal_distribution<RealType> _normal;
247    /// \endcond
248};
249
250/// \endcond
251
252} // namespace boost
253
254#endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP