Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63247 - in trunk: boost/random libs/random/doc libs/random/example libs/random/test
From: steven_at_[hidden]
Date: 2010-06-22 16:22:42


Author: steven_watanabe
Date: 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
New Revision: 63247
URL: http://svn.boost.org/trac/boost/changeset/63247

Log:
Sync gamma_distribution with C++0x. Fixes #3888.
Added:
   trunk/libs/random/test/test_gamma.cpp (contents, props changed)
   trunk/libs/random/test/test_gamma_distribution.cpp (contents, props changed)
Text files modified:
   trunk/boost/random/exponential_distribution.hpp | 10 +
   trunk/boost/random/gamma_distribution.hpp | 327 ++++++++++++++++++++++++++++-----------
   trunk/libs/random/doc/Jamfile.v2 | 4
   trunk/libs/random/doc/generators.qbk | 1
   trunk/libs/random/doc/random.qbk | 11
   trunk/libs/random/example/die.cpp | 8
   trunk/libs/random/test/Jamfile.v2 | 2
   7 files changed, 261 insertions(+), 102 deletions(-)

Modified: trunk/boost/random/exponential_distribution.hpp
==============================================================================
--- trunk/boost/random/exponential_distribution.hpp (original)
+++ trunk/boost/random/exponential_distribution.hpp 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -22,6 +22,7 @@
 #include <boost/limits.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/random/detail/config.hpp>
+#include <boost/random/uniform_01.hpp>
 
 namespace boost {
 
@@ -56,7 +57,8 @@
 #ifndef BOOST_NO_STDC_NAMESPACE
     using std::log;
 #endif
- return -result_type(1) / _lambda * log(result_type(1)-eng());
+ return -result_type(1) /
+ _lambda * log(result_type(1)-uniform_01<RealType>()(eng));
   }
 
 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
@@ -77,6 +79,12 @@
   }
 #endif
 
+ friend bool operator==(const exponential_distribution& lhs,
+ const exponential_distribution& rhs)
+ {
+ return lhs._lambda == rhs._lambda;
+ }
+
 private:
   result_type _lambda;
 };

Modified: trunk/boost/random/gamma_distribution.hpp
==============================================================================
--- trunk/boost/random/gamma_distribution.hpp (original)
+++ trunk/boost/random/gamma_distribution.hpp 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -1,6 +1,7 @@
 /* boost random/gamma_distribution.hpp header file
  *
  * Copyright Jens Maurer 2002
+ * Copyright Steven Watanabe 2010
  * 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)
@@ -22,122 +23,268 @@
 #include <boost/random/exponential_distribution.hpp>
 
 namespace boost {
+namespace random {
 
 // The algorithm is taken from Knuth
 
 /**
- * The gamma distribution is a continuous distribution with a single
- * parameter alpha.
+ * The gamma distribution is a continuous distribution with two
+ * parameters alpha and beta. It produces values > 0.
  *
- * It has \f$p(x) = x^{\alpha-1}\frac{e^{-x}}{\Gamma(\alpha)}\f$.
+ * It has
+ * \f$p(x) = x^{\alpha-1}\frac{e^{-x/\beta}}{\beta^\alpha\Gamma(\alpha)}\f$.
  */
 template<class RealType = double>
 class gamma_distribution
 {
 public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
+
+ class param_type
+ {
+ public:
+ typedef gamma_distribution distribution_type;
+
+ /**
+ * Constructs a @c param_type object from the "alpha" and "beta"
+ * parameters.
+ *
+ * Requires: alpha > 0 && beta > 0
+ */
+ param_type(const RealType& alpha_arg = RealType(1),
+ const RealType& beta_arg = RealType(1))
+ : _alpha(alpha_arg), _beta(beta_arg)
+ {
+ }
+
+ /** Returns the "alpha" parameter of the distribution. */
+ RealType alpha() const { return _alpha; }
+ /** Returns the "beta" parameter of the distribution. */
+ RealType beta() const { return _beta; }
+
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os,
+ const param_type& parm)
+ {
+ os << parm._alpha << ' ' << parm._beta;
+ return os;
+ }
+
+ /** Reads the parameters from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
+ {
+ is >> parm._alpha >> std::ws >> parm._beta;
+ return is;
+ }
+#endif
+
+ /** Returns true if the two sets of parameters are the same. */
+ friend bool operator==(const param_type& lhs, const param_type& rhs)
+ {
+ return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta;
+ }
+ /** Returns true if the two sets fo parameters are different. */
+ friend bool operator!=(const param_type& lhs, const param_type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ private:
+ RealType _alpha;
+ RealType _beta;
+ };
 
 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
+ BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
 #endif
 
- explicit gamma_distribution(const result_type& alpha_arg = result_type(1))
- : _exp(result_type(1)), _alpha(alpha_arg)
- {
- assert(_alpha > result_type(0));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- RealType alpha() const { return _alpha; }
-
- void reset() { _exp.reset(); }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
+ /**
+ * Creates a new gamma_distribution with parameters "alpha" and "beta".
+ *
+ * Requires: alpha > 0 && beta > 0
+ */
+ explicit gamma_distribution(const result_type& alpha_arg = result_type(1),
+ const result_type& beta_arg = result_type(1))
+ : _exp(result_type(1)), _alpha(alpha_arg), _beta(beta_arg)
+ {
+ assert(_alpha > result_type(0));
+ assert(_beta > result_type(0));
+ init();
+ }
+
+ /** Constructs a @c gamma_distribution from its parameters. */
+ explicit gamma_distribution(const param_type& parm)
+ : _exp(result_type(1)), _alpha(parm.alpha()), _beta(parm.beta())
+ {
+ init();
+ }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the "alpha" paramter of the distribution. */
+ RealType alpha() const { return _alpha; }
+ /** Returns the "beta" parameter of the distribution. */
+ RealType beta() const { return _beta; }
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
+ /* Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::max)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_alpha, _beta); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _alpha = parm.alpha();
+ _beta = parm.beta();
+ init();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _exp.reset(); }
+
+ /**
+ * Returns a random variate distributed according to
+ * the gamma distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
 #ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::tan; using std::sqrt; using std::exp; using std::log;
- using std::pow;
+ // allow for Koenig lookup
+ using std::tan; using std::sqrt; using std::exp; using std::log;
+ using std::pow;
 #endif
- if(_alpha == result_type(1)) {
- return _exp(eng);
- } else if(_alpha > result_type(1)) {
- // Can we have a boost::mathconst please?
- const result_type pi = result_type(3.14159265358979323846);
- for(;;) {
- result_type y = tan(pi * eng());
- result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
- + _alpha-result_type(1);
- if(x <= result_type(0))
- continue;
- if(eng() >
- (result_type(1)+y*y) * exp((_alpha-result_type(1))
- *log(x/(_alpha-result_type(1)))
- - sqrt(result_type(2)*_alpha
- -result_type(1))*y))
- continue;
- return x;
- }
- } else /* alpha < 1.0 */ {
- for(;;) {
- result_type u = eng();
- result_type y = _exp(eng);
- result_type x, q;
- if(u < _p) {
- x = exp(-y/_alpha);
- q = _p*exp(-x);
- } else {
- x = result_type(1)+y;
- q = _p + (result_type(1)-_p) * pow(x, _alpha-result_type(1));
- }
- if(u >= q)
- continue;
- return x;
- }
+ if(_alpha == result_type(1)) {
+ return _exp(eng) * _beta;
+ } else if(_alpha > result_type(1)) {
+ // Can we have a boost::mathconst please?
+ const result_type pi = result_type(3.14159265358979323846);
+ for(;;) {
+ result_type y = tan(pi * uniform_01<RealType>()(eng));
+ result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
+ + _alpha-result_type(1);
+ if(x <= result_type(0))
+ continue;
+ if(uniform_01<RealType>()(eng) >
+ (result_type(1)+y*y) * exp((_alpha-result_type(1))
+ *log(x/(_alpha-result_type(1)))
+ - sqrt(result_type(2)*_alpha
+ -result_type(1))*y))
+ continue;
+ return x * _beta;
+ }
+ } else /* alpha < 1.0 */ {
+ for(;;) {
+ result_type u = uniform_01<RealType>()(eng);
+ result_type y = _exp(eng);
+ result_type x, q;
+ if(u < _p) {
+ x = exp(-y/_alpha);
+ q = _p*exp(-x);
+ } else {
+ x = result_type(1)+y;
+ q = _p + (result_type(1)-_p) * pow(x,_alpha-result_type(1));
+ }
+ if(u >= q)
+ continue;
+ return x * _beta;
+ }
+ }
+ }
+
+ template<class URNG>
+ RealType operator()(URNG& urng, const param_type& parm) const
+ {
+ return gamma_distribution(parm)(urng);
     }
- }
 
 #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 gamma_distribution& gd)
- {
- os << gd._alpha;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
- {
- is >> std::ws >> gd._alpha;
- gd.init();
- return is;
- }
+ /** Writes a @c gamma_distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const gamma_distribution& gd)
+ {
+ os << gd.param();
+ return os;
+ }
+
+ /** Reads a @c gamma_distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
+ {
+ gd.read(is);
+ return is;
+ }
 #endif
 
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of random variates given equal generators.
+ */
+ friend bool operator==(const gamma_distribution& lhs,
+ const gamma_distribution& rhs)
+ {
+ return lhs._alpha == rhs._alpha
+ && lhs._beta == rhs._beta
+ && lhs._exp == rhs._exp;
+ }
+
+ /**
+ * Returns true if the two distributions can produce different
+ * sequences of random variates, given equal generators.
+ */
+ friend bool operator!=(const gamma_distribution& lhs,
+ const gamma_distribution& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
 private:
- /// \cond hide_private_members
- void init()
- {
+ /// \cond hide_private_members
+
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is)
+ {
+ param_type parm;
+ if(is >> parm) {
+ param(parm);
+ }
+ }
+
+ void init()
+ {
 #ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp;
+ // allow for Koenig lookup
+ using std::exp;
 #endif
- _p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
- }
- /// \endcond
-
- exponential_distribution<RealType> _exp;
- result_type _alpha;
- // some data precomputed from the parameters
- result_type _p;
+ _p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
+ }
+ /// \endcond
+
+ exponential_distribution<RealType> _exp;
+ result_type _alpha;
+ result_type _beta;
+ // some data precomputed from the parameters
+ result_type _p;
 };
 
+
+} // namespace random
+
+using random::gamma_distribution;
+
 } // namespace boost
 
 #endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP

Modified: trunk/libs/random/doc/Jamfile.v2
==============================================================================
--- trunk/libs/random/doc/Jamfile.v2 (original)
+++ trunk/libs/random/doc/Jamfile.v2 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -83,8 +83,8 @@
         minstd_rand=\"@xmlonly <classname alt=\\\"boost::minstd_rand\\\">minstd_rand</classname> @endxmlonly\" \\
         minstd_rand0=\"@xmlonly <classname alt=\\\"boost::minstd_rand0\\\">minstd_rand0</classname> @endxmlonly\" \\
         rand48=\"@xmlonly <classname alt=\\\"boost::rand48\\\">rand48</classname> @endxmlonly\" \\
- mt11213b=\"@xmlonly <classname alt=\\\"boost::mt11213b\\\">mt11213b</classname> @endxmlonly\" \\
- mt19937=\"@xmlonly <classname alt=\\\"boost::mt19937\\\">mt19937</classname> @endxmlonly\" \\
+ mt11213b=\"@xmlonly <classname alt=\\\"boost::random::mt11213b\\\">mt11213b</classname> @endxmlonly\" \\
+ mt19937=\"@xmlonly <classname alt=\\\"boost::random::mt19937\\\">mt19937</classname> @endxmlonly\" \\
         ecuyer1988=\"@xmlonly <classname alt=\\\"boost::ecuyer1988\\\">ecuyer1988</classname> @endxmlonly\" \\
         lagged_fibonacci607=\"@xmlonly <classname alt=\\\"boost::lagged_fibonacci607\\\">lagged_fibonacci607</classname> @endxmlonly\" \\
         lagged_fibonacci44497=\"@xmlonly <classname alt=\\\"boost::lagged_fibonacci44497\\\">lagged_fibonacci44497</classname> @endxmlonly\" \\

Modified: trunk/libs/random/doc/generators.qbk
==============================================================================
--- trunk/libs/random/doc/generators.qbk (original)
+++ trunk/libs/random/doc/generators.qbk 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -52,6 +52,7 @@
   [[__hellekalek1995] [2[sup 31]-1] [`sizeof(int32_t)`] [[hellekalek1995__inversive__speed]] [good uniform distribution in several dimensions]]
   [[__mt11213b] [2[sup 11213]-1] [`352*sizeof(uint32_t)`] [[mt11213b_speed]] [good uniform distribution in up to 350 dimensions]]
   [[__mt19937] [2[sup 19937]-1] [`625*sizeof(uint32_t)`] [[mt19937_speed]] [good uniform distribution in up to 623 dimensions]]
+ [[__mt19937_64] [2[sup 19937]-1] [`312*sizeof(uint64_t)`] [] [good uniform distribution in up to 311 dimensions]]
   [[__lagged_fibonacci607] [~2[sup 32000]] [`607*sizeof(double)`] [[lagged_fibonacci607_speed]] [-]]
   [[__lagged_fibonacci1279] [~2[sup 67000]] [`1279*sizeof(double)`] [[lagged_fibonacci1279_speed]] [-]]
   [[__lagged_fibonacci2281] [~2[sup 120000]] [`2281*sizeof(double)`] [[lagged_fibonacci2281_speed]] [-]]

Modified: trunk/libs/random/doc/random.qbk
==============================================================================
--- trunk/libs/random/doc/random.qbk (original)
+++ trunk/libs/random/doc/random.qbk 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -37,8 +37,9 @@
 [def __kreutzer1986 [classref boost::kreutzer1986 kreutzer1986]]
 [def __taus88 [classref boost::taus88 taus88]]
 [def __hellekalek1995 [classref boost::hellekalek1995 hellekalek1995]]
-[def __mt11213b [classref boost::mt11213b mt11213b]]
-[def __mt19937 [classref boost::mt19937 mt19937]]
+[def __mt11213b [classref boost::random::mt11213b mt11213b]]
+[def __mt19937 [classref boost::random::mt19937 mt19937]]
+[def __mt19937_64 [classref boost::random::mt19937_64 mt19937_64]]
 [def __lagged_fibonacci607 [classref boost::lagged_fibonacci607 lagged_fibonacci607]]
 [def __lagged_fibonacci1279 [classref boost::lagged_fibonacci1279 lagged_fibonacci1279]]
 [def __lagged_fibonacci2281 [classref boost::lagged_fibonacci2281 lagged_fibonacci2281]]
@@ -65,7 +66,7 @@
 [def __binomial_distribution [classref boost::random::binomial_distribution binomial_distribution]]
 [def __cauchy_distribution [classref boost::cauchy_distribution cauchy_distribution]]
 [def __discrete_distribution [classref boost::random::discrete_distribution discrete_distribution]]
-[def __gamma_distribution [classref boost::gamma_distribution gamma_distribution]]
+[def __gamma_distribution [classref boost::random::gamma_distribution gamma_distribution]]
 [def __poisson_distribution [classref boost::random::poisson_distribution poisson_distribution]]
 [def __geometric_distribution [classref boost::geometric_distribution geometric_distribution]]
 [def __triangle_distribution [classref boost::triangle_distribution triangle_distribution]]
@@ -89,11 +90,11 @@
 
 For a very quick start, here's an example:
 
- ``[classref boost::mt19937]`` rng; // produces randomness out of thin air
+ ``[classref boost::random::mt19937]`` rng; // produces randomness out of thin air
                                       // see pseudo-random number generators
   ``[classref boost::uniform_int]<>`` six(1,6); // distribution that maps to 1..6
                                       // see random number distributions
- ``[classref boost::variate_generator]``<``[classref boost::mt19937]``&, ``[classref boost::uniform_int]``<> >
+ ``[classref boost::variate_generator]``<``[classref boost::random::mt19937]``&, ``[classref boost::uniform_int]``<> >
            die(rng, six); // glues randomness with mapping
   int x = die(); // simulate rolling a die
 

Modified: trunk/libs/random/example/die.cpp
==============================================================================
--- trunk/libs/random/example/die.cpp (original)
+++ trunk/libs/random/example/die.cpp 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -25,7 +25,7 @@
   change this is to seed with the current time (`std::time(0)`
   defined in ctime).
 */
-boost::mt19937 gen;
+boost::random::mt19937 gen;
 /*`
   [note We are using a /global/ generator object here. This
   is important because we don't want to create a new [prng
@@ -46,14 +46,14 @@
>>*/
     boost::uniform_int<> dist(1, 6);
     /*<< __variate_generator combines a generator with a distribution.
- [important We pass [classref boost::mt19937 boost::mt19937&] to
- __variate_generator instead of just [classref boost::mt19937]
+ [important We pass [classref boost::random::mt19937 boost::mt19937&] to
+ __variate_generator instead of just [classref boost::random::mt19937]
         (note the reference). Without the reference, __variate_generator
         would make a copy of the generator and would leave the global
         `gen` unchanged. Consequently, `roll_die` would produce *the same value*
         every time it was called.]
>>*/
- boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(gen, dist);
+ boost::variate_generator<boost::random::mt19937&, boost::uniform_int<> > die(gen, dist);
     /*<< A __variate_generator is a function object. >>*/
     return die();
 }

Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2 (original)
+++ trunk/libs/random/test/Jamfile.v2 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -50,6 +50,8 @@
 run test_poisson_distribution.cpp /boost//unit_test_framework ;
 run test_discrete.cpp ;
 run test_discrete_distribution.cpp /boost//unit_test_framework ;
+run test_gamma.cpp ;
+run test_gamma_distribution.cpp /boost//unit_test_framework ;
 
 # run nondet_random_speed.cpp ;
 # run random_device.cpp ;

Added: trunk/libs/random/test/test_gamma.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_gamma.cpp 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -0,0 +1,111 @@
+/* test_gamma.cpp
+ *
+ * Copyright Steven Watanabe 2010
+ * 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/gamma_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/math/distributions/gamma.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <vector>
+#include <iostream>
+#include <numeric>
+
+#include "statistic_tests.hpp"
+
+bool do_test(double alpha, double beta, int max) {
+ std::cout << "running gamma(" << alpha << ", " << beta << ")" << " " << max << " times: " << std::flush;
+
+ boost::math::gamma_distribution<> expected(alpha, beta);
+
+ boost::random::gamma_distribution<> dist(alpha, beta);
+ boost::mt19937 gen;
+ kolmogorov_experiment test(max);
+ boost::variate_generator<boost::mt19937&, boost::random::gamma_distribution<> > vgen(gen, dist);
+
+ double prob = test.probability(test.run(vgen, expected));
+
+ bool result = prob < 0.99;
+ const char* err = result? "" : "*";
+ std::cout << std::setprecision(17) << prob << err << std::endl;
+
+ std::cout << std::setprecision(6);
+
+ return result;
+}
+
+bool do_tests(int repeat, double max_alpha, double max_beta, int trials) {
+ boost::mt19937 gen;
+ boost::uniform_real<> adist(0.00001, max_alpha);
+ boost::uniform_real<> bdist(0.00001, max_beta);
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(adist(gen), bdist(gen), trials)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_gamma -r <repeat> -n <max n> -t <trials>" << std::endl;
+ return 2;
+}
+
+template<class T>
+bool handle_option(int& argc, char**& argv, char opt, T& value) {
+ if(argv[0][1] == opt && argc > 1) {
+ --argc;
+ ++argv;
+ value = boost::lexical_cast<T>(argv[0]);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int main(int argc, char** argv) {
+ int repeat = 10;
+ double max_alpha = 1000.0;
+ double max_beta = 1000.0;
+ int trials = 1000000;
+
+ if(argc > 0) {
+ --argc;
+ ++argv;
+ }
+ while(argc > 0) {
+ if(argv[0][0] != '-') return usage();
+ else if(!handle_option(argc, argv, 'r', repeat)
+ && !handle_option(argc, argv, 'a', max_alpha)
+ && !handle_option(argc, argv, 'b', max_beta)
+ && !handle_option(argc, argv, 't', trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat, max_alpha, max_beta, trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}

Added: trunk/libs/random/test/test_gamma_distribution.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_gamma_distribution.cpp 2010-06-22 16:22:41 EDT (Tue, 22 Jun 2010)
@@ -0,0 +1,132 @@
+/* test_gamma_distribution.cpp
+ *
+ * Copyright Steven Watanabe 2010
+ * 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/gamma_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <sstream>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_CASE(test_constructors) {
+ boost::random::gamma_distribution<> dist;
+ BOOST_CHECK_EQUAL(dist.alpha(), 1.0);
+ BOOST_CHECK_EQUAL(dist.beta(), 1.0);
+ boost::random::gamma_distribution<> dist_one(7.5);
+ BOOST_CHECK_EQUAL(dist_one.alpha(), 7.5);
+ BOOST_CHECK_EQUAL(dist_one.beta(), 1.0);
+ boost::random::gamma_distribution<> dist_two(7.5, 0.25);
+ BOOST_CHECK_EQUAL(dist_two.alpha(), 7.5);
+ BOOST_CHECK_EQUAL(dist_two.beta(), 0.25);
+ boost::random::gamma_distribution<> copy(dist);
+ BOOST_CHECK_EQUAL(dist, copy);
+ boost::random::gamma_distribution<> copy_one(dist_one);
+ BOOST_CHECK_EQUAL(dist_one, copy_one);
+ boost::random::gamma_distribution<> copy_two(dist_two);
+ BOOST_CHECK_EQUAL(dist_two, copy_two);
+}
+
+BOOST_AUTO_TEST_CASE(test_param) {
+ boost::random::gamma_distribution<> dist(7.5, 0.25);
+ boost::random::gamma_distribution<>::param_type param = dist.param();
+ BOOST_CHECK_EQUAL(param.alpha(), 7.5);
+ BOOST_CHECK_EQUAL(param.beta(), 0.25);
+ boost::random::gamma_distribution<> copy1(param);
+ BOOST_CHECK_EQUAL(dist, copy1);
+ boost::random::gamma_distribution<> copy2;
+ copy2.param(param);
+ BOOST_CHECK_EQUAL(dist, copy2);
+
+ boost::random::gamma_distribution<>::param_type param_copy = param;
+ BOOST_CHECK_EQUAL(param, param_copy);
+ BOOST_CHECK(param == param_copy);
+ BOOST_CHECK(!(param != param_copy));
+ boost::random::gamma_distribution<>::param_type param_default;
+ BOOST_CHECK_EQUAL(param_default.alpha(), 1.0);
+ BOOST_CHECK_EQUAL(param_default.beta(), 1.0);
+ BOOST_CHECK(param != param_default);
+ BOOST_CHECK(!(param == param_default));
+ boost::random::gamma_distribution<>::param_type param_one(7.5);
+ BOOST_CHECK_EQUAL(param_one.alpha(), 7.5);
+ BOOST_CHECK_EQUAL(param_one.beta(), 1.0);
+ BOOST_CHECK(param != param_one);
+ BOOST_CHECK(!(param == param_one));
+ BOOST_CHECK(param_default != param_one);
+ BOOST_CHECK(!(param_default == param_one));
+ boost::random::gamma_distribution<>::param_type param_two(7.5, 0.25);
+ BOOST_CHECK_EQUAL(param_two.alpha(), 7.5);
+ BOOST_CHECK_EQUAL(param_two.beta(), 0.25);
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max) {
+ boost::random::gamma_distribution<> dist;
+ BOOST_CHECK_EQUAL((dist.min)(), 0);
+ BOOST_CHECK_EQUAL((dist.max)(), (std::numeric_limits<double>::max)());
+ boost::random::gamma_distribution<> dist_one(7.5);
+ BOOST_CHECK_EQUAL((dist_one.min)(), 0);
+ BOOST_CHECK_EQUAL((dist_one.max)(), (std::numeric_limits<double>::max)());
+ boost::random::gamma_distribution<> dist_two(7.5, 0.25);
+ BOOST_CHECK_EQUAL((dist_two.min)(), 0);
+ BOOST_CHECK_EQUAL((dist_two.max)(), (std::numeric_limits<double>::max)());
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison) {
+ boost::random::gamma_distribution<> dist;
+ boost::random::gamma_distribution<> dist_copy(dist);
+ boost::random::gamma_distribution<> dist_one(7.5);
+ boost::random::gamma_distribution<> dist_one_copy(dist_one);
+ boost::random::gamma_distribution<> dist_two(7.5, 0.25);
+ boost::random::gamma_distribution<> dist_two_copy(dist_two);
+ BOOST_CHECK(dist == dist_copy);
+ BOOST_CHECK(!(dist != dist_copy));
+ BOOST_CHECK(dist_one == dist_one_copy);
+ BOOST_CHECK(!(dist_one != dist_one_copy));
+ BOOST_CHECK(dist_two == dist_two_copy);
+ BOOST_CHECK(!(dist_two != dist_two_copy));
+ BOOST_CHECK(dist != dist_one);
+ BOOST_CHECK(!(dist == dist_one));
+ BOOST_CHECK(dist != dist_two);
+ BOOST_CHECK(!(dist == dist_two));
+ BOOST_CHECK(dist_one != dist_two);
+ BOOST_CHECK(!(dist_one == dist_two));
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming) {
+ boost::random::gamma_distribution<> dist(7.5, 0.25);
+ std::stringstream stream;
+ stream << dist;
+ boost::random::gamma_distribution<> restored_dist;
+ stream >> restored_dist;
+ BOOST_CHECK_EQUAL(dist, restored_dist);
+}
+
+BOOST_AUTO_TEST_CASE(test_generation) {
+ boost::minstd_rand0 gen;
+ boost::random::gamma_distribution<> dist;
+ boost::random::gamma_distribution<> dist_two(1.0, 1000000.0);
+ for(int i = 0; i < 10; ++i) {
+ // This test is not guaranteed to work, since
+ // a gamma distribution with a large scale parameter
+ // can produce small values and a distribution with
+ // a small scale can produce large values, but the
+ // chances of failure are small.
+ double value = dist(gen);
+ BOOST_CHECK_GE(value, 0.0);
+ BOOST_CHECK_LE(value, 100.0);
+ double value_two = dist_two(gen);
+ BOOST_CHECK_GE(value_two, 100.0);
+ double value_param = dist_two(gen, dist.param());
+ BOOST_CHECK_GE(value_param, 0);
+ BOOST_CHECK_LE(value_param, 100.0);
+ double value_two_param = dist(gen, dist_two.param());
+ BOOST_CHECK_GE(value_two_param, 100.0);
+ }
+}


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