Chris@16: /* boost random/lognormal_distribution.hpp header file Chris@16: * Chris@16: * Copyright Jens Maurer 2000-2001 Chris@16: * Copyright Steven Watanabe 2011 Chris@16: * Distributed under the Boost Software License, Version 1.0. (See Chris@16: * accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: * See http://www.boost.org for most recent version including documentation. Chris@16: * Chris@101: * $Id$ Chris@16: * Chris@16: * Revision history Chris@16: * 2001-02-18 moved to individual header files Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP Chris@16: #define BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP Chris@16: Chris@16: #include // std::exp, std::sqrt Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace random { Chris@16: Chris@16: /** Chris@16: * Instantiations of class template lognormal_distribution model a Chris@16: * \random_distribution. Such a distribution produces random numbers Chris@16: * with \f$\displaystyle p(x) = \frac{1}{x s \sqrt{2\pi}} e^{\frac{-\left(\log(x)-m\right)^2}{2s^2}}\f$ Chris@16: * for x > 0. Chris@16: * Chris@16: * @xmlwarning Chris@16: * This distribution has been updated to match the C++ standard. Chris@16: * Its behavior has changed from the original Chris@16: * boost::lognormal_distribution. A backwards compatible Chris@16: * version is provided in namespace boost. Chris@16: * @endxmlwarning Chris@16: */ Chris@16: template Chris@16: class lognormal_distribution Chris@16: { Chris@16: public: Chris@16: typedef typename normal_distribution::input_type input_type; Chris@16: typedef RealType result_type; Chris@16: Chris@16: class param_type Chris@16: { Chris@16: public: Chris@16: Chris@16: typedef lognormal_distribution distribution_type; Chris@16: Chris@16: /** Constructs the parameters of a lognormal_distribution. */ Chris@16: explicit param_type(RealType m_arg = RealType(0.0), Chris@16: RealType s_arg = RealType(1.0)) Chris@16: : _m(m_arg), _s(s_arg) {} Chris@16: Chris@16: /** Returns the "m" parameter of the distribution. */ Chris@16: RealType m() const { return _m; } Chris@16: Chris@16: /** Returns the "s" parameter of the distribution. */ Chris@16: RealType s() const { return _s; } Chris@16: Chris@16: /** Writes the parameters to a std::ostream. */ Chris@16: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) Chris@16: { Chris@16: os << parm._m << " " << parm._s; Chris@16: return os; Chris@16: } Chris@16: Chris@16: /** Reads the parameters from a std::istream. */ Chris@16: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) Chris@16: { Chris@16: is >> parm._m >> std::ws >> parm._s; Chris@16: return is; Chris@16: } Chris@16: Chris@16: /** Returns true if the two sets of parameters are equal. */ Chris@16: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) Chris@16: { return lhs._m == rhs._m && lhs._s == rhs._s; } Chris@16: Chris@16: /** Returns true if the two sets of parameters are different. */ Chris@16: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) Chris@16: Chris@16: private: Chris@16: RealType _m; Chris@16: RealType _s; Chris@16: }; Chris@16: Chris@16: /** Chris@16: * Constructs a lognormal_distribution. @c m and @c s are the Chris@16: * parameters of the distribution. Chris@16: */ Chris@16: explicit lognormal_distribution(RealType m_arg = RealType(0.0), Chris@16: RealType s_arg = RealType(1.0)) Chris@16: : _normal(m_arg, s_arg) {} Chris@16: Chris@16: /** Chris@16: * Constructs a lognormal_distribution from its parameters. Chris@16: */ Chris@16: explicit lognormal_distribution(const param_type& parm) Chris@16: : _normal(parm.m(), parm.s()) {} Chris@16: Chris@16: // compiler-generated copy ctor and assignment operator are fine Chris@16: Chris@16: /** Returns the m parameter of the distribution. */ Chris@16: RealType m() const { return _normal.mean(); } Chris@16: /** Returns the s parameter of the distribution. */ Chris@16: RealType s() const { return _normal.sigma(); } Chris@16: Chris@16: /** Returns the smallest value that the distribution can produce. */ Chris@16: RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const Chris@16: { return RealType(0); } Chris@16: /** Returns the largest value that the distribution can produce. */ Chris@16: RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const Chris@16: { return (std::numeric_limits::infinity)(); } Chris@16: Chris@16: /** Returns the parameters of the distribution. */ Chris@16: param_type param() const { return param_type(m(), s()); } Chris@16: /** Sets the parameters of the distribution. */ Chris@16: void param(const param_type& parm) Chris@16: { Chris@16: typedef normal_distribution normal_type; Chris@16: typename normal_type::param_type normal_param(parm.m(), parm.s()); Chris@16: _normal.param(normal_param); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Effects: Subsequent uses of the distribution do not depend Chris@16: * on values produced by any engine prior to invoking reset. Chris@16: */ Chris@16: void reset() { _normal.reset(); } Chris@16: Chris@16: /** Chris@16: * Returns a random variate distributed according to the Chris@16: * lognormal distribution. Chris@16: */ Chris@16: template Chris@16: result_type operator()(Engine& eng) Chris@16: { Chris@16: using std::exp; Chris@16: return exp(_normal(eng)); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Returns a random variate distributed according to the Chris@16: * lognormal distribution with parameters specified by param. Chris@16: */ Chris@16: template Chris@16: result_type operator()(Engine& eng, const param_type& parm) Chris@16: { return lognormal_distribution(parm)(eng); } Chris@16: Chris@16: /** Writes the distribution to a @c std::ostream. */ Chris@16: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld) Chris@16: { Chris@16: os << ld._normal; Chris@16: return os; Chris@16: } Chris@16: Chris@16: /** Reads the distribution from a @c std::istream. */ Chris@16: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld) Chris@16: { Chris@16: is >> ld._normal; Chris@16: return is; Chris@16: } Chris@16: Chris@16: /** Chris@16: * Returns true if the two distributions will produce identical Chris@16: * sequences of values given equal generators. Chris@16: */ Chris@16: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lognormal_distribution, lhs, rhs) Chris@16: { return lhs._normal == rhs._normal; } Chris@16: Chris@16: /** Chris@16: * Returns true if the two distributions may produce different Chris@16: * sequences of values given equal generators. Chris@16: */ Chris@16: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lognormal_distribution) Chris@16: Chris@16: private: Chris@16: normal_distribution _normal; Chris@16: }; Chris@16: Chris@16: } // namespace random Chris@16: Chris@16: /// \cond show_deprecated Chris@16: Chris@16: /** Chris@16: * Provided for backwards compatibility. This class is Chris@16: * deprecated. It provides the old behavior of lognormal_distribution with Chris@16: * \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$ Chris@16: * for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and Chris@16: * \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$. Chris@16: */ Chris@16: template Chris@16: class lognormal_distribution Chris@16: { Chris@16: public: Chris@16: typedef typename normal_distribution::input_type input_type; Chris@16: typedef RealType result_type; Chris@16: Chris@16: lognormal_distribution(RealType mean_arg = RealType(1.0), Chris@16: RealType sigma_arg = RealType(1.0)) Chris@16: : _mean(mean_arg), _sigma(sigma_arg) Chris@16: { Chris@16: init(); Chris@16: } Chris@16: RealType mean() const { return _mean; } Chris@16: RealType sigma() const { return _sigma; } Chris@16: void reset() { _normal.reset(); } Chris@16: template Chris@16: RealType operator()(Engine& eng) Chris@16: { Chris@16: using std::exp; Chris@16: return exp(_normal(eng) * _nsigma + _nmean); Chris@16: } Chris@16: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld) Chris@16: { Chris@16: os << ld._normal << " " << ld._mean << " " << ld._sigma; Chris@16: return os; Chris@16: } Chris@16: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld) Chris@16: { Chris@16: is >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma; Chris@16: ld.init(); Chris@16: return is; Chris@16: } Chris@16: private: Chris@16: /// \cond show_private Chris@16: void init() Chris@16: { Chris@16: using std::log; Chris@16: using std::sqrt; Chris@16: _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean)); Chris@16: _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1))); Chris@16: } Chris@16: RealType _mean; Chris@16: RealType _sigma; Chris@16: RealType _nmean; Chris@16: RealType _nsigma; Chris@16: normal_distribution _normal; Chris@16: /// \endcond Chris@16: }; Chris@16: Chris@16: /// \endcond Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP