Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68424 - in trunk: boost/random libs/random/test
From: steven_at_[hidden]
Date: 2011-01-24 16:18:43


Author: steven_watanabe
Date: 2011-01-24 16:18:40 EST (Mon, 24 Jan 2011)
New Revision: 68424
URL: http://svn.boost.org/trac/boost/changeset/68424

Log:
Update lognormal_distribution to match C++0x.
Added:
   trunk/libs/random/test/test_lognormal.cpp (contents, props changed)
   trunk/libs/random/test/test_lognormal_distribution.cpp (contents, props changed)
Text files modified:
   trunk/boost/random/lognormal_distribution.hpp | 293 ++++++++++++++++++++++++++++-----------
   trunk/libs/random/test/Jamfile.v2 | 2
   2 files changed, 209 insertions(+), 86 deletions(-)

Modified: trunk/boost/random/lognormal_distribution.hpp
==============================================================================
--- trunk/boost/random/lognormal_distribution.hpp (original)
+++ trunk/boost/random/lognormal_distribution.hpp 2011-01-24 16:18:40 EST (Mon, 24 Jan 2011)
@@ -1,6 +1,7 @@
 /* boost random/lognormal_distribution.hpp header file
  *
  * Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
  * Distributed under the Boost Software License, Version 1.0. (See
  * accompanying file LICENSE_1_0.txt or copy at
  * http://www.boost.org/LICENSE_1_0.txt)
@@ -18,110 +19,230 @@
 
 #include <boost/config/no_tr1/cmath.hpp> // std::exp, std::sqrt
 #include <cassert>
-#include <iostream>
+#include <iosfwd>
+#include <istream>
 #include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
 #include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
 #include <boost/random/normal_distribution.hpp>
 
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std {
- using ::log;
- using ::sqrt;
-}
-#endif
-
 namespace boost {
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-// Special gcc workaround: gcc 2.95.x ignores using-declarations
-// in template classes (confirmed by gcc author Martin v. Loewis)
- using std::sqrt;
- using std::exp;
-#endif
+namespace random {
 
 /**
  * Instantiations of class template lognormal_distribution model a
  * \random_distribution. Such a distribution produces random numbers
- * with \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$
- * for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
- * \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$.
+ * with \f$\displaystyle p(x) = \frac{1}{x s \sqrt{2\pi}} e^{\frac{-\left(\log(x)-m\right)^2}{2s^2}}\f$
+ * for x > 0.
+ *
+ * @xmlwarning
+ * This distribution has been updated to match the C++ standard.
+ * Its behavior has changed from the original
+ * boost::lognormal_distribution. A backwards compatible
+ * version is provided in namespace boost.
+ * @endxmlwarning
  */
 template<class RealType = double>
 class lognormal_distribution
 {
 public:
- typedef typename normal_distribution<RealType>::input_type input_type;
- typedef RealType result_type;
+ typedef typename normal_distribution<RealType>::input_type input_type;
+ typedef RealType result_type;
 
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
-
- /**
- * Constructs a lognormal_distribution. @c mean and @c sigma are the
- * mean and standard deviation of the lognormal distribution.
- */
- explicit lognormal_distribution(result_type mean_arg = result_type(1.0),
- result_type sigma_arg = result_type(1.0))
- : _mean(mean_arg), _sigma(sigma_arg)
- {
- assert(_mean > result_type(0));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- RealType mean() const { return _mean; }
- RealType sigma() const { return _sigma; }
- void reset() { _normal.reset(); }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp;
-#endif
- return exp(_normal(eng) * _nsigma + _nmean);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const lognormal_distribution& ld)
- {
- os << ld._normal << " " << ld._mean << " " << ld._sigma;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, lognormal_distribution& ld)
- {
- is >> std::ws >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
- ld.init();
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef lognormal_distribution distribution_type;
+
+ /** Constructs the parameters of a lognormal_distribution. */
+ explicit param_type(RealType m_arg = RealType(0.0),
+ RealType s_arg = RealType(1.0))
+ : _m(m_arg), _s(s_arg) {}
+
+ /** Returns the "m" parameter of the distribution. */
+ RealType m() const { return _m; }
+
+ /** Returns the "s" parameter of the distribution. */
+ RealType s() const { return _s; }
+
+ /** Writes the parameters to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._m << " " << parm._s;
+ return os;
+ }
+
+ /** Reads the parameters from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._m >> std::ws >> parm._s;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._m == rhs._m && lhs._s == rhs._s; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _m;
+ RealType _s;
+ };
+
+ /**
+ * Constructs a lognormal_distribution. @c m and @c s are the
+ * parameters of the distribution.
+ */
+ explicit lognormal_distribution(RealType m_arg = RealType(0.0),
+ RealType s_arg = RealType(1.0))
+ : _normal(m_arg, s_arg) {}
+
+ /**
+ * Constructs a lognormal_distribution from its parameters.
+ */
+ explicit lognormal_distribution(const param_type& parm)
+ : _normal(parm.m(), parm.s()) {}
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the m parameter of the distribution. */
+ RealType m() const { return _normal.mean(); }
+ /** Returns the s parameter of the distribution. */
+ RealType s() const { return _normal.sigma(); }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return RealType(0); }
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::infinity)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(m(), s()); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ typedef normal_distribution<RealType> normal_type;
+ typename normal_type::param_type normal_param(parm.m(), parm.s());
+ _normal.param(normal_param);
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _normal.reset(); }
+
+ /**
+ * Returns a random variate distributed according to the
+ * lognormal distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
+ using std::exp;
+ return exp(_normal(eng));
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * lognormal distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm)
+ { return lognormal_distribution(parm)(eng); }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
+ {
+ os << ld._normal;
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
+ {
+ is >> ld._normal;
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lognormal_distribution, lhs, rhs)
+ { return lhs._normal == rhs._normal; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lognormal_distribution)
 
 private:
+ normal_distribution<result_type> _normal;
+};
+
+} // namespace random
 
- /// \cond hide_private_members
- void init()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp; using std::log; using std::sqrt;
-#endif
- _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
- _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
- }
- /// \endcond
-
- RealType _mean, _sigma;
- RealType _nmean, _nsigma;
- normal_distribution<result_type> _normal;
+/**
+ * Provided for backwards compatibility. This class is
+ * deprecated. It provides the old behavior of lognormal_distribution with
+ * \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$
+ * for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
+ * \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}.
+ */
+template<class RealType = double>
+class lognormal_distribution
+{
+public:
+ typedef typename normal_distribution<RealType>::input_type input_type;
+ typedef RealType result_type;
+
+ lognormal_distribution(RealType mean_arg = RealType(1.0),
+ RealType sigma_arg = RealType(1.0))
+ : _mean(mean_arg), _sigma(sigma_arg)
+ {
+ init();
+ }
+ RealType mean() const { return _mean; }
+ RealType sigma() const { return _sigma; }
+ void reset() { _normal.reset(); }
+ template<class Engine>
+ RealType operator()(Engine& eng)
+ {
+ using std::exp;
+ return exp(_normal(eng) * _nsigma + _nmean);
+ }
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
+ {
+ os << ld._normal << " " << ld._mean << " " << ld._sigma;
+ return os;
+ }
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
+ {
+ is >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
+ ld.init();
+ return is;
+ }
+private:
+ /// \cond
+ void init()
+ {
+ using std::log;
+ using std::sqrt;
+ _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
+ _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
+ }
+ RealType _mean;
+ RealType _sigma;
+ RealType _nmean;
+ RealType _nsigma;
+ normal_distribution<RealType> _normal;
+ /// \endcond
 };
 
 } // namespace boost

Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2 (original)
+++ trunk/libs/random/test/Jamfile.v2 2011-01-24 16:18:40 EST (Mon, 24 Jan 2011)
@@ -81,6 +81,8 @@
 run test_cauchy_distribution.cpp /boost//unit_test_framework ;
 run test_geometric.cpp ;
 run test_geometric_distribution.cpp /boost//unit_test_framework ;
+run test_lognormal.cpp ;
+run test_lognormal_distribution.cpp /boost//unit_test_framework ;
 
 # run nondet_random_speed.cpp ;
 # run random_device.cpp ;

Added: trunk/libs/random/test/test_lognormal.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_lognormal.cpp 2011-01-24 16:18:40 EST (Mon, 24 Jan 2011)
@@ -0,0 +1,28 @@
+/* test_lognormal.cpp
+ *
+ * Copyright Steven Watanabe 2011
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * $Id$
+ *
+ */
+
+#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/lognormal.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::lognormal_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME lognormal
+#define BOOST_MATH_DISTRIBUTION boost::math::lognormal
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME m
+#define BOOST_RANDOM_ARG1_DEFAULT 10.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(-n, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME s
+#define BOOST_RANDOM_ARG2_DEFAULT 10.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.0001, n)
+
+#include "test_real_distribution.ipp"

Added: trunk/libs/random/test/test_lognormal_distribution.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_lognormal_distribution.cpp 2011-01-24 16:18:40 EST (Mon, 24 Jan 2011)
@@ -0,0 +1,36 @@
+/* test_lognormal_distribution.cpp
+ *
+ * Copyright Steven Watanabe 2011
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * $Id$
+ *
+ */
+
+#include <boost/random/lognormal_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::lognormal_distribution<>
+#define BOOST_RANDOM_ARG1 m
+#define BOOST_RANDOM_ARG2 s
+#define BOOST_RANDOM_ARG1_DEFAULT 0.0
+#define BOOST_RANDOM_ARG2_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE 7.5
+#define BOOST_RANDOM_ARG2_VALUE 0.25
+
+#define BOOST_RANDOM_DIST0_MIN 0.0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN 0.0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN 0.0
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS (-100.0)
+#define BOOST_RANDOM_TEST1_MAX 1
+
+#define BOOST_RANDOM_TEST2_PARAMS (100.0)
+#define BOOST_RANDOM_TEST2_MIN 1
+
+#include "test_distribution.ipp"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk