summaryrefslogtreecommitdiff
path: root/libs/random
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/random
downloadboost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'libs/random')
-rw-r--r--libs/random/build/Jamfile.v218
-rw-r--r--libs/random/doc/Jamfile.v2169
-rw-r--r--libs/random/doc/concepts.qbk246
-rw-r--r--libs/random/doc/distribution_performance_linux.qbk24
-rw-r--r--libs/random/doc/distribution_performance_windows.qbk24
-rw-r--r--libs/random/doc/distributions.qbk106
-rw-r--r--libs/random/doc/generator_defs.qbk37
-rw-r--r--libs/random/doc/generator_performance_linux.qbk37
-rw-r--r--libs/random/doc/generator_performance_windows.qbk37
-rw-r--r--libs/random/doc/generators.qbk92
-rw-r--r--libs/random/doc/nondet_random.qbk103
-rw-r--r--libs/random/doc/performance.qbk28
-rw-r--r--libs/random/doc/performance_data.qbk34
-rw-r--r--libs/random/doc/random.qbk168
-rw-r--r--libs/random/doc/tutorial.qbk28
-rw-r--r--libs/random/example/Jamfile.v212
-rw-r--r--libs/random/example/die.cpp60
-rw-r--r--libs/random/example/password.cpp48
-rw-r--r--libs/random/example/random_demo.cpp110
-rw-r--r--libs/random/example/weighted_die.cpp55
-rw-r--r--libs/random/extra/Jamfile.v210
-rw-r--r--libs/random/extra/haertel.hpp156
-rw-r--r--libs/random/extra/test_haertel.cpp62
-rw-r--r--libs/random/index.html14
-rw-r--r--libs/random/nondet_random.html17
-rw-r--r--libs/random/performance/Jamfile.v218
-rw-r--r--libs/random/performance/generate_table.cpp133
-rw-r--r--libs/random/performance/nondet_random_speed.cpp60
-rw-r--r--libs/random/performance/random_speed.cpp399
-rw-r--r--libs/random/random-concepts.html17
-rw-r--r--libs/random/random-distributions.html17
-rw-r--r--libs/random/random-generators.html17
-rw-r--r--libs/random/random-misc.html17
-rw-r--r--libs/random/random-performance.html17
-rw-r--r--libs/random/random-variate.html17
-rw-r--r--libs/random/src/random_device.cpp217
-rw-r--r--libs/random/test/Jamfile.v2126
-rw-r--r--libs/random/test/chi_squared_test.hpp92
-rw-r--r--libs/random/test/concepts.hpp210
-rw-r--r--libs/random/test/histogram.cpp165
-rw-r--r--libs/random/test/integrate.hpp79
-rw-r--r--libs/random/test/statistic_tests.cpp503
-rw-r--r--libs/random/test/statistic_tests.hpp709
-rw-r--r--libs/random/test/test_bernoulli.cpp108
-rw-r--r--libs/random/test/test_bernoulli_distribution.cpp32
-rw-r--r--libs/random/test/test_binomial.cpp30
-rw-r--r--libs/random/test/test_binomial_distribution.cpp37
-rw-r--r--libs/random/test/test_cauchy.cpp28
-rw-r--r--libs/random/test/test_cauchy_distribution.cpp35
-rw-r--r--libs/random/test/test_chi_squared.cpp24
-rw-r--r--libs/random/test/test_chi_squared_distribution.cpp34
-rw-r--r--libs/random/test/test_const_mod.cpp183
-rw-r--r--libs/random/test/test_discrete.cpp123
-rw-r--r--libs/random/test/test_discrete_distribution.cpp168
-rw-r--r--libs/random/test/test_distribution.ipp290
-rw-r--r--libs/random/test/test_ecuyer1988.cpp24
-rw-r--r--libs/random/test/test_exponential.cpp24
-rw-r--r--libs/random/test/test_exponential_distribution.cpp32
-rw-r--r--libs/random/test/test_extreme_value.cpp28
-rw-r--r--libs/random/test/test_extreme_value_distribution.cpp36
-rw-r--r--libs/random/test/test_fisher_f.cpp28
-rw-r--r--libs/random/test/test_fisher_f_distribution.cpp33
-rw-r--r--libs/random/test/test_gamma.cpp28
-rw-r--r--libs/random/test/test_gamma_distribution.cpp37
-rw-r--r--libs/random/test/test_generate_canonical.cpp103
-rw-r--r--libs/random/test/test_generator.ipp246
-rw-r--r--libs/random/test/test_geometric.cpp26
-rw-r--r--libs/random/test/test_geometric_distribution.cpp31
-rw-r--r--libs/random/test/test_hellekalek1995.cpp24
-rw-r--r--libs/random/test/test_independent_bits31.cpp26
-rw-r--r--libs/random/test/test_independent_bits32.cpp26
-rw-r--r--libs/random/test/test_knuth_b.cpp26
-rw-r--r--libs/random/test/test_kreutzer1986.cpp26
-rw-r--r--libs/random/test/test_lagged_fibonacci.cpp25
-rw-r--r--libs/random/test/test_lagged_fibonacci1279.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci19937.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci2281.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci23209.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci3217.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci4423.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci44497.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci607.cpp24
-rw-r--r--libs/random/test/test_lagged_fibonacci9689.cpp24
-rw-r--r--libs/random/test/test_linear_feedback_shift.cpp25
-rw-r--r--libs/random/test/test_lognormal.cpp28
-rw-r--r--libs/random/test/test_lognormal_distribution.cpp36
-rw-r--r--libs/random/test/test_minstd_rand.cpp26
-rw-r--r--libs/random/test/test_minstd_rand0.cpp26
-rw-r--r--libs/random/test/test_mt11213b.cpp24
-rw-r--r--libs/random/test/test_mt19937.cpp78
-rw-r--r--libs/random/test/test_mt19937_64.cpp26
-rw-r--r--libs/random/test/test_negative_binomial.cpp30
-rw-r--r--libs/random/test/test_negative_binomial_distribution.cpp37
-rw-r--r--libs/random/test/test_normal.cpp28
-rw-r--r--libs/random/test/test_normal_distribution.cpp36
-rw-r--r--libs/random/test/test_old_uniform_int.cpp26
-rw-r--r--libs/random/test/test_old_uniform_int_distribution.cpp76
-rw-r--r--libs/random/test/test_old_uniform_real.cpp25
-rw-r--r--libs/random/test/test_old_uniform_real_distribution.cpp38
-rw-r--r--libs/random/test/test_piecewise_constant.cpp158
-rw-r--r--libs/random/test/test_piecewise_constant_distribution.cpp246
-rw-r--r--libs/random/test/test_piecewise_linear.cpp175
-rw-r--r--libs/random/test/test_piecewise_linear_distribution.cpp252
-rw-r--r--libs/random/test/test_poisson.cpp25
-rw-r--r--libs/random/test/test_poisson_distribution.cpp33
-rw-r--r--libs/random/test/test_rand48.cpp26
-rw-r--r--libs/random/test/test_random_device.cpp29
-rw-r--r--libs/random/test/test_random_number_generator.cpp33
-rw-r--r--libs/random/test/test_ranlux24.cpp26
-rw-r--r--libs/random/test/test_ranlux24_base.cpp25
-rw-r--r--libs/random/test/test_ranlux3.cpp25
-rw-r--r--libs/random/test/test_ranlux3_01.cpp26
-rw-r--r--libs/random/test/test_ranlux4.cpp25
-rw-r--r--libs/random/test/test_ranlux48.cpp26
-rw-r--r--libs/random/test/test_ranlux48_base.cpp26
-rw-r--r--libs/random/test/test_ranlux4_01.cpp26
-rw-r--r--libs/random/test/test_ranlux64_3.cpp27
-rw-r--r--libs/random/test/test_ranlux64_3_01.cpp26
-rw-r--r--libs/random/test/test_ranlux64_4.cpp27
-rw-r--r--libs/random/test/test_ranlux64_4_01.cpp26
-rw-r--r--libs/random/test/test_real_distribution.ipp195
-rw-r--r--libs/random/test/test_seed_seq.cpp113
-rw-r--r--libs/random/test/test_student_t.cpp24
-rw-r--r--libs/random/test/test_student_t_distribution.cpp29
-rw-r--r--libs/random/test/test_taus88.cpp24
-rw-r--r--libs/random/test/test_triangle.cpp26
-rw-r--r--libs/random/test/test_triangle_distribution.cpp41
-rw-r--r--libs/random/test/test_uniform_int.cpp27
-rw-r--r--libs/random/test/test_uniform_int.ipp149
-rw-r--r--libs/random/test/test_uniform_int_distribution.cpp42
-rw-r--r--libs/random/test/test_uniform_on_sphere_distribution.cpp43
-rw-r--r--libs/random/test/test_uniform_real.cpp26
-rw-r--r--libs/random/test/test_uniform_real_distribution.cpp38
-rw-r--r--libs/random/test/test_uniform_smallint.cpp27
-rw-r--r--libs/random/test/test_uniform_smallint_distribution.cpp38
-rw-r--r--libs/random/test/test_weibull.cpp28
-rw-r--r--libs/random/test/test_weibull_distribution.cpp36
137 files changed, 9404 insertions, 0 deletions
diff --git a/libs/random/build/Jamfile.v2 b/libs/random/build/Jamfile.v2
new file mode 100644
index 0000000000..34d7f2495d
--- /dev/null
+++ b/libs/random/build/Jamfile.v2
@@ -0,0 +1,18 @@
+# Jamfile.v2
+#
+# Copyright (c) 2010
+# Steven Watanabe
+#
+# 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)
+
+project /boost/random
+ : source-location ../src
+ : requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
+ : usage-requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
+;
+
+lib boost_random : [ glob *.cpp ] ;
+
+boost-install boost_random ;
diff --git a/libs/random/doc/Jamfile.v2 b/libs/random/doc/Jamfile.v2
new file mode 100644
index 0000000000..a5db8b7938
--- /dev/null
+++ b/libs/random/doc/Jamfile.v2
@@ -0,0 +1,169 @@
+# Jamfile.v2
+#
+# Copyright (c) 2009
+# Steven Watanabe
+#
+# 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)
+
+using quickbook ;
+using doxygen ;
+using boostbook ;
+import regex ;
+import os ;
+import path ;
+
+doxygen_files =
+ additive_combine
+ bernoulli_distribution
+ binomial_distribution
+ cauchy_distribution
+ chi_squared_distribution
+ discard_block
+ discrete_distribution
+ exponential_distribution
+ extreme_value_distribution
+ fisher_f_distribution
+ gamma_distribution
+ geometric_distribution
+ independent_bits
+ inversive_congruential
+ lagged_fibonacci
+ linear_congruential
+ linear_feedback_shift
+ lognormal_distribution
+ mersenne_twister
+ negative_binomial_distribution
+ normal_distribution
+ piecewise_constant_distribution
+ piecewise_linear_distribution
+ poisson_distribution
+ random_device
+ random_number_generator
+ ranlux
+ seed_seq
+ shuffle_order
+ # shuffle_output
+ student_t_distribution
+ subtract_with_carry
+ taus88
+ triangle_distribution
+ uniform_01
+ uniform_int_distribution
+ uniform_on_sphere
+ uniform_real_distribution
+ uniform_smallint
+ variate_generator
+ weibull_distribution
+ xor_combine
+;
+
+path-constant here : . ;
+path-constant boost-root : ../../.. ;
+
+# Figure out where the root of the boost tree is relative
+# to the html directory.
+local BOOST_ROOT = [ path.relative-to
+ [ path.join [ path.pwd ] html ]
+ [ path.root
+ [ path.make $(boost-root) ]
+ [ path.pwd ] ] ] ;
+
+doxygen reference :
+ $(here)/../../../boost/random/$(doxygen_files).hpp
+ $(here)/../../../boost/random.hpp
+ :
+ <doxygen:param>EXPAND_ONLY_PREDEF=YES
+ <doxygen:param>"ALIASES= \\
+ xmlnote=\"@xmlonly <note><para> @endxmlonly\" \\
+ endxmlnote=\"@xmlonly </para></note> @endxmlonly\" \\
+ xmlwarning=\"@xmlonly <warning><para> @endxmlonly\" \\
+ endxmlwarning=\"@xmlonly </para></warning> @endxmlonly\" \\
+ blockquote=\"@xmlonly <blockquote><para> @endxmlonly\" \\
+ endblockquote=\"@xmlonly </para></blockquote> @endxmlonly\" \\
+ boost=\"$(BOOST_ROOT)\" \\
+ random_distribution=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.random_distribution\\\">random distribution</link> @endxmlonly\" \\
+ pseudo_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.pseudo_random_number_generator\\\">pseudo-random number generator</link> @endxmlonly\" \\
+ uniform_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.uniform_random_number_generator\\\">uniform random number generator</link> @endxmlonly\" \\
+ nondeterministic_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.non_deterministic_uniform_random_number_generator\\\">non-deterministic random number generator</link> @endxmlonly\" \\
+ generators=\"@xmlonly <link linkend=\\\"boost_random.reference.generators\\\">generators</link> @endxmlonly\" \\
+ distributions=\"@xmlonly <link linkend=\\\"boost_random.reference.distributions\\\">distributions</link> @endxmlonly\" \\
+ additive_combine_engine=\"@xmlonly <classname alt=\\\"boost::random::additive_combine_engine\\\">additive_combine_engine</classname> @endxmlonly\" \\
+ discard_block_engine=\"@xmlonly <classname alt=\\\"boost::random::discard_block_engine\\\">discard_block_engine</classname> @endxmlonly\" \\
+ lagged_fibonacci_engine=\"@xmlonly<classname alt=\\\"boost::random::lagged_fibonacci_engine\\\">lagged_fibonacci_engine</classname>@endxmlonly\" \\
+ subtract_with_carry_01_engine=\"@xmlonly<classname alt=\\\"boost::random::subtract_with_carry_01_engine\\\">subtract_with_carry_01_engine</classname>@endxmlonly\" \\
+ linear_congruential_engine=\"@xmlonly<classname alt=\\\"boost::random::linear_congruential_engine\\\">linear_congruential_engine</classname>@endxmlonly\" \\
+ minstd_rand=\"@xmlonly <classname alt=\\\"boost::random::minstd_rand\\\">minstd_rand</classname> @endxmlonly\" \\
+ minstd_rand0=\"@xmlonly <classname alt=\\\"boost::random::minstd_rand0\\\">minstd_rand0</classname> @endxmlonly\" \\
+ rand48=\"@xmlonly <classname alt=\\\"boost::random::rand48\\\">rand48</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::random::ecuyer1988\\\">ecuyer1988</classname> @endxmlonly\" \\
+ lagged_fibonacci607=\"@xmlonly <classname alt=\\\"boost::random::lagged_fibonacci607\\\">lagged_fibonacci607</classname> @endxmlonly\" \\
+ lagged_fibonacci44497=\"@xmlonly <classname alt=\\\"boost::random::lagged_fibonacci44497\\\">lagged_fibonacci44497</classname> @endxmlonly\" \\
+ bernoulli_distribution=\"@xmlonly <classname alt=\\\"boost::random::bernoulli_distribution\\\">bernoulli_distribution</classname> @endxmlonly\" \\
+ cauchy_distribution=\"@xmlonly <classname alt=\\\"boost::random::cauchy_distribution\\\">cauchy_distribution</classname> @endxmlonly\" \\
+ uniform_01=\"@xmlonly<classname alt=\\\"boost::random::uniform_01\\\">uniform_01</classname>@endxmlonly\" \\
+ random_device=\"@xmlonly<classname alt=\\\"boost::random::random_device\\\">random_device</classname>@endxmlonly\""
+ <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+ <doxygen:param>QUIET=YES
+ <doxygen:param>WARN_IF_UNDOCUMENTED=NO
+ <doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>ENABLE_PREPROCESSING=YES
+ <doxygen:param>MACRO_EXPANSION=YES
+ <doxygen:param>SEARCH_INCLUDES=NO
+ # Expand macros and clean up a bunch of ugly names
+ <doxygen:param>"PREDEFINED= \\
+ \"BOOST_RANDOM_DOXYGEN=1\" \\
+ \"BOOST_PREVENT_MACRO_SUBSTITUTION=\" \\
+ \"BOOST_STATIC_ASSERT(x)=\" \\
+ \"BOOST_STATIC_CONSTANT(type,value)=static const type value\" \\
+ \"UINT64_C(value)=value ## ull\" \\
+ \"BOOST_RANDOM_DECL=\" \\
+ \"RealType(x)=x\" \\
+ \"result_type(x)=x\" \\
+ \"p_arg=p\" \\
+ \"median_arg=median\" \\
+ \"mean_arg=mean\" \\
+ \"sigma_arg=sigma\" \\
+ \"lambda_arg=lambda\" \\
+ \"alpha_arg=alpha\" \\
+ \"beta_arg=beta\" \\
+ \"a_arg=a\" \\
+ \"b_arg=b\" \\
+ \"c_arg=c\" \\
+ \"t_arg=t\" \\
+ \"m_arg=m\" \\
+ \"n_arg=n\" \\
+ \"s_arg=s\" \\
+ \"k_arg=k\" \\
+ \"min_arg=min\" \\
+ \"max_arg=max\" \\
+ \"dim_arg=dim\" \\
+ \"parm=param\" \\
+ \"aseed=seed\" \\
+ \"seed_arg=seed\" \\
+ \"BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,T,t)=template<class CharT, class Traits> friend std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,T,t)=template<class CharT, class Traits> friend std::basic_istream<CharT,Traits>& operator>>(std::basic_istream<CharT,Traits>& is, const T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T,lhs,rhs)=friend bool operator==(const T& lhs, const T& rhs)\" \\
+ \"BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T)=friend bool operator!=(const T& lhs, const T& rhs) { return !(lhs == rhs); }\" \\
+ \"BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self,T,t)=explicit Self(T t)\" \\
+ \"BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self,T,t)=template<class T> explicit Self(T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self,T,t)=template<class T> explicit Self(T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self,T,t)=void seed(T t)\" \\
+ \"BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self,T,t)=template<class T> void seed(T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self,T,t)=template<class T> void seed(T& t)\""
+ <reftitle>"Headers"
+ <doxygen:xml-imagedir>images/random
+;
+
+xml random : random.qbk : <dependency>reference ;
+
+boostbook standalone :
+ random
+ :
+ <implicit-dependency>reference
+ <xsl:param>boost.root=../../../..
+ <xsl:param>chunk.section.depth=2
+;
diff --git a/libs/random/doc/concepts.qbk b/libs/random/doc/concepts.qbk
new file mode 100644
index 0000000000..d001b0eb13
--- /dev/null
+++ b/libs/random/doc/concepts.qbk
@@ -0,0 +1,246 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+[section Introduction]
+
+Random numbers are required in a number of different problem domains, such as
+
+* numerics (simulation, Monte-Carlo integration)
+* games (non-deterministic enemy behavior)
+* security (key generation)
+* testing (random coverage in white-box tests)
+
+The Boost Random Number Generator Library provides a framework for random
+number generators with well-defined properties so that the generators can be
+used in the demanding numerics and security domains. For a general
+introduction to random numbers in numerics, see
+
+[:"Numerical Recipes in C: The art of scientific computing", William H. Press,
+Saul A. Teukolsky, William A. Vetterling, Brian P. Flannery, 2nd ed., 1992,
+pp. 274-328]
+
+Depending on the requirements of the problem domain, different variations of
+random number generators are appropriate:
+
+* non-deterministic random number generator
+* pseudo-random number generator
+* quasi-random number generator
+
+All variations have some properties in common, the concepts (in the STL
+sense) is called __UniformRandomNumberGenerator. This
+concept will be defined in a subsequent section.
+
+The goals for this library are the following:
+
+* allow easy integration of third-party random-number generators
+* provide easy-to-use front-end classes which model popular distributions
+* provide maximum efficiency
+
+[endsect]
+
+[section Uniform Random Number Generator]
+
+A uniform random number generator provides a
+sequence of random numbers uniformly distributed on a given range. The
+range can be compile-time fixed or available (only) after run-time construction
+of the object.
+
+The /tight lower bound/ of some (finite) set S is the (unique) member l in S, so
+that for all v in S, l <= v holds. Likewise, the /tight upper bound/ of some
+(finite) set S is the (unique) member u in S, so that for all v in S, v <= u
+holds.
+
+In the following table, X denotes a number generator class returning objects
+of type T, and v is a const value of X.
+
+[table UniformRandomNumberGenerator requirements
+ [[expression] [return type] [pre/post-condition]]
+ [[`X::result_type`] [`T`] [`std::numeric_limits<T>::is_specialized` is
+ `true`, `T` is __LessThanComparable]]
+ [[`u.operator()()`] [`T`] [-]]
+ [[`v.min()`] [`T`] [tight lower bound on the set of all values returned by
+ `operator()`. The return value of this function shall not
+ change during the lifetime of the object.]]
+ [[`v.max()`] [`T`] [if `std::numeric_limits<T>::is_integer`, tight upper
+ bound on the set of all values returned by `operator()`,
+ otherwise, the smallest representable number larger than
+ the tight upper bound on the set of all values returned
+ by `operator()`. In any case, the return value of this
+ function shall not change during the lifetime of the
+ object.]]
+]
+
+The member functions `min`, `max`, and `operator()` shall have amortized
+constant time complexity.
+
+[note For integer generators (i.e. integer `T`), the generated values `x`
+fulfill `min() <= x <= max()`, for non-integer generators (i.e. non-integer
+`T`), the generated values `x` fulfill `min() <= x < max()`.
+
+Rationale: The range description with min and max serves two purposes. First,
+it allows scaling of the values to some canonical range, such as [0..1).
+Second, it describes the significant bits of the values, which may be
+relevant for further processing.
+
+The range is a closed interval \[min,max\] for integers, because the underlying
+type may not be able to represent the half-open interval \[min,max+1). It is
+a half-open interval \[min, max) for non-integers, because this is much more
+practical for borderline cases of continuous distributions.]
+
+[note The __UniformRandomNumberGenerator concept does not require
+`operator()(long)` and thus it does not fulfill the `RandomNumberGenerator`
+(std:25.2.11 \[lib.alg.random.shuffle\]) requirements. Use the
+__random_number_generator adapter for that.
+
+Rationale: `operator()(long)` is not provided, because mapping the output of
+some generator with integer range to a different integer range is not trivial.]
+
+[endsect]
+
+[section Non-deterministic Uniform Random Number Generator]
+
+A non-deterministic uniform random number generator is a
+__UniformRandomNumberGenerator that is based on some stochastic process.
+Thus, it provides a sequence of truly-random numbers. Examples for such
+processes are nuclear decay, noise of a Zehner diode, tunneling of quantum
+particles, rolling a die, drawing from an urn, and tossing a coin. Depending
+on the environment, inter-arrival times of network packets or keyboard events
+may be close approximations of stochastic processes.
+
+The class __random_device is a model for a non-deterministic random number
+generator.
+
+[note This type of random-number generator is useful for security
+applications, where it is important to prevent an outside attacker from
+guessing the numbers and thus obtaining your encryption or authentication key.
+Thus, models of this concept should be cautious not to leak any information,
+to the extent possible by the environment. For example, it might be advisable
+to explicitly clear any temporary storage as soon as it is no longer needed.]
+
+[endsect]
+
+[section Pseudo-Random Number Generator]
+
+A pseudo-random number generator is a __UniformRandomNumberGenerator which
+provides a deterministic sequence of pseudo-random numbers, based on some
+algorithm and internal state.
+[classref boost::random::linear_congruential_engine
+Linear congruential] and [classref boost::random::inversive_congruential_engine
+inversive congruential] generators are examples of such [prng pseudo-random
+number generators]. Often, these generators are very sensitive to their
+parameters. In order to prevent wrong implementations from being used, an
+external testsuite should check that the generated sequence and the validation
+value provided do indeed match.
+
+Donald E. Knuth gives an extensive overview on pseudo-random number generation
+in his book "The Art of Computer Programming, Vol. 2, 3rd edition,
+Addison-Wesley, 1997". The descriptions for the specific generators contain
+additional references.
+
+[note Because the state of a pseudo-random number generator is necessarily
+finite, the sequence of numbers returned by the generator will loop
+eventually.]
+
+In addition to the __UniformRandomNumberGenerator requirements,
+a pseudo-random number generator has some additional requirements. In the
+following table, `X` denotes a pseudo-random number generator class returning
+objects of type `T`, `x` is a value of `T`, `u` is a value of `X`, and `v` is
+a const value of `X`.
+
+[table PseudoRandomNumberGenerator requirements
+ [[expression] [return type] [pre/post-condition]]
+ [[`X()`] [-] [creates a generator in some implementation-defined state.
+ Note: Several generators thusly created may possibly produce
+ dependent or identical sequences of random numbers.]]
+ [[`X(...)`] [-] [creates a generator with user-provided state; the
+ implementation shall specify the constructor
+ argument(s)]]
+ [[`u.seed(...)`] [`void`] [sets the current state according to the
+ argument(s); at least functions with the same
+ signature as the non-default constructor(s)
+ shall be provided.]]
+]
+
+[note The seed member function is similar to the assign member function in
+STL containers. However, the naming did not seem appropriate.]
+
+Classes which model a pseudo-random number generator shall also model
+__EqualityComparable, i.e. implement `operator==`. Two pseudo-random number
+generators are defined to be /equivalent/ if they both return an identical
+sequence of numbers starting from a given state.
+
+Classes which model a pseudo-random number generator should also model the
+__Streamable concept, i.e. implement `operator<<` and `operator>>`. If so,
+`operator<<` writes all current state of the pseudo-random number generator
+to the given `ostream` so that `operator>>` can restore the state at a later
+time. The state shall be written in a platform-independent manner, but it is
+assumed that the `locales` used for writing and reading be the same. The
+pseudo-random number generator with the restored state and the original at
+the just-written state shall be equivalent.
+
+Classes which model a pseudo-random number generator should also model the
+__CopyConstructible and __Assignable concepts. However, note that the
+sequences of the original and the copy are strongly correlated (in fact,
+they are identical), which may make them unsuitable for some problem domains.
+Thus, copying pseudo-random number generators is discouraged; they should
+always be passed by (non-const) reference.
+
+The classes __rand48, __minstd_rand, and __mt19937 are models for a
+pseudo-random number generator.
+
+[note This type of random-number generator is useful for numerics, games and
+testing. The non-zero arguments constructor(s) and the `seed()` member
+function(s) allow for a user-provided state to be installed in the generator.
+This is useful for debugging Monte-Carlo algorithms and analyzing particular
+test scenarios. The __Streamable concept allows to save/restore the state of
+the generator, for example to re-run a test suite at a later time.]
+
+[endsect]
+
+[section Random Distribution]
+
+A random distribution produces random numbers distributed according to some
+distribution, given uniformly distributed random values as input. In the
+following table, `X` denotes a random distribution class returning objects of
+type `T`, `u` is a value of `X`, `x` is a (possibly const) value of `X`, and
+`e` is an lvalue of an arbitrary type that meets the requirements of a
+__UniformRandomNumberGenerator, returning values of type `U`.
+
+[table Random distribution requirements (in addition to CopyConstructible, and Assignable)
+ [[expression] [return type] [pre/post-condition] [complexity]]
+ [[`X::result_type`] [`T`] [-] [compile-time]]
+ [[`u.reset()`] [`void`] [subsequent uses of `u` do not depend on values
+ produced by any engine prior to invoking `reset`.]
+ [constant]]
+ [[`u(e)`] [`T`] [the sequence of numbers returned by successive invocations
+ with the same object `e` is randomly distributed with some
+ probability density function `p(x)`]
+ [amortized constant number of invocations of `e`]]
+ [[`os << x`] [`std::ostream&`] [writes a textual representation for the
+ parameters and additional internal data of
+ the distribution `x` to `os`.
+ post: The `os.fmtflags` and fill character
+ are unchanged.]
+ [O(size of state)]]
+ [[`is >> u`] [`std::istream&`] [restores the parameters and additional
+ internal data of the distribution `u`.
+ pre: `is` provides a textual representation
+ that was previously written by `operator<<`
+ post: The `is.fmtflags` are unchanged.]
+ [O(size of state)]]
+]
+
+Additional requirements: The sequence of numbers produced by repeated
+invocations of `x(e)` does not change whether or not `os << x` is invoked
+between any of the invocations `x(e)`. If a textual representation is written
+using `os << x` and that representation is restored into the same or a
+different object `y` of the same type using `is >> y`, repeated invocations
+of `y(e)` produce the same sequence of random numbers as would repeated
+invocations of `x(e)`.
+
+[endsect]
diff --git a/libs/random/doc/distribution_performance_linux.qbk b/libs/random/doc/distribution_performance_linux.qbk
new file mode 100644
index 0000000000..0d4db8752a
--- /dev/null
+++ b/libs/random/doc/distribution_performance_linux.qbk
@@ -0,0 +1,24 @@
+[table Distributions (Linux)
+ [[\[M rn/sec\]][minstd_rand][kreutzer1986][mt19937][lagged_fibonacci607]]
+ [[uniform_int][16.2338][48.7805][21.5517][23.8663]]
+ [[uniform_smallint][18.9036][114.943][25.3165][74.6269]]
+ [[bernoulli][21.322][85.4701][23.2558][125]]
+ [[geometric][9.42507][11.7925][7.38007][15.528]]
+ [[binomial][13.4953][29.7619][12.7877][38.7597]]
+ [[negative_binomial][1.69549][2.29305][1.65563][2.45098]]
+ [[poisson][13.7552][34.1297][13.369][43.8596]]
+ [[uniform_real][18.2815][44.4444][19.8413][119.048]]
+ [[uniform_01][21.692][72.4638][17.1233][116.279]]
+ [[triangle][15.2207][29.3255][11.9904][51.2821]]
+ [[exponential][10.5374][17.0068][10.8814][22.2222]]
+ [[normal polar][8.82613][12.9199][9.00901][14.771]]
+ [[lognormal][6.15764][7.50188][5.68182][8.61326]]
+ [[chi squared][2.07297][2.8401][2.10926][3.07409]]
+ [[cauchy][9.18274][14.8368][7.37463][17.3913]]
+ [[fisher f][1.04646][1.47449][1.08026][1.61186]]
+ [[student t][1.60927][2.18245][1.65207][2.34192]]
+ [[gamma][2.1097][2.87439][2.13538][3.01296]]
+ [[weibull][4.73709][5.77367][4.20521][6.33312]]
+ [[extreme value][7.40192][10.101][6.23441][11.5741]]
+ [[uniform_on_sphere][2.22222][2.78552][2.28311][2.7933]]
+]
diff --git a/libs/random/doc/distribution_performance_windows.qbk b/libs/random/doc/distribution_performance_windows.qbk
new file mode 100644
index 0000000000..2a1fce4ed6
--- /dev/null
+++ b/libs/random/doc/distribution_performance_windows.qbk
@@ -0,0 +1,24 @@
+[table Distributions (Windows)
+ [[\[M rn/sec\]][minstd_rand][kreutzer1986][mt19937][lagged_fibonacci607]]
+ [[uniform_int][27.049][79.1139][29.8151][34.8432]]
+ [[uniform_smallint][31.736][90.3342][33.9213][59.9161]]
+ [[bernoulli][25.641][56.2114][27.049][62.8141]]
+ [[geometric][12.8717][18.9645][14.6671][18.5805]]
+ [[binomial][18.2116][32.2165][19.8491][29.4118]]
+ [[negative_binomial][2.79065][3.99138][2.73358][3.72898]]
+ [[poisson][20.0321][37.7074][18.9645][36.4299]]
+ [[uniform_real][27.6319][78.1861][26.4901][71.2251]]
+ [[uniform_01][36.63][95.6938][26.3783][85.4701]]
+ [[triangle][19.4856][43.8982][19.425][36.8324]]
+ [[exponential][17.0474][32.0513][18.005][28.6205]]
+ [[normal polar][14.4051][19.7863][13.1354][20.7426]]
+ [[lognormal][10.8472][13.6968][10.3563][13.7855]]
+ [[chi squared][3.53957][4.95][3.44448][4.83442]]
+ [[cauchy][15.1906][23.5682][14.9768][23.31]]
+ [[fisher f][1.74951][2.45417][1.69854][2.38743]]
+ [[student t][2.63151][3.75291][2.53872][3.51432]]
+ [[gamma][3.50275][4.9729][3.35087][4.75195]]
+ [[weibull][8.96539][11.9161][9.09256][11.6754]]
+ [[extreme value][12.3274][18.4196][12.5945][17.5623]]
+ [[uniform_on_sphere][2.83688][3.58038][2.73898][3.60101]]
+]
diff --git a/libs/random/doc/distributions.qbk b/libs/random/doc/distributions.qbk
new file mode 100644
index 0000000000..e6589369a2
--- /dev/null
+++ b/libs/random/doc/distributions.qbk
@@ -0,0 +1,106 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+In addition to the [link boost_random.reference.generators random number generators],
+this library provides distribution functions which map one distribution
+(often a uniform distribution provided by some generator) to another.
+
+Usually, there are several possible implementations of any given mapping.
+Often, there is a choice between using more space, more invocations of the
+underlying source of random numbers, or more time-consuming arithmetic such
+as trigonometric functions. This interface description does not mandate any
+specific implementation. However, implementations which cannot reach certain
+values of the specified distribution or otherwise do not converge
+statistically to it are not acceptable.
+
+[table Uniform Distributions
+ [[distribution] [explanation] [example]]
+ [[__uniform_smallint] [discrete uniform distribution on a small set of integers
+ (much smaller than the range of the underlying
+ generator)]
+ [drawing from an urn]]
+ [[__uniform_int_distribution] [discrete uniform distribution on a set of integers; the
+ underlying generator may be called several times to gather
+ enough randomness for the output]
+ [drawing from an urn]]
+ [[__uniform_01] [continuous uniform distribution on the range [0,1);
+ important basis for other distributions]
+ [-]]
+ [[__uniform_real_distribution] [continuous uniform distribution on some range [min, max) of
+ real numbers]
+ [for the range [0, 2pi): randomly dropping a stick and
+ measuring its angle in radians (assuming the angle is
+ uniformly distributed)]]
+]
+
+[table Bernoulli Distributions
+ [[distribution] [explanation] [example]]
+ [[__bernoulli_distribution] [Bernoulli experiment: discrete boolean valued
+ distribution with configurable probability]
+ [tossing a coin (p=0.5)]]
+ [[__binomial_distribution] [counts outcomes of repeated Bernoulli
+ experiments]
+ [tossing a coin 20 times and counting how many
+ front sides are shown]]
+ [[__geometric_distribution] [measures distance between outcomes of repeated
+ Bernoulli experiments]
+ [throwing a die several times and counting the
+ number of tries until a "6" appears for the
+ first time]]
+ [[__negative_binomial_distribution] [Counts the number of failures of repeated
+ Bernoulli experiments required to get some constant
+ number of successes.]
+ [flipping a coin and counting the number of
+ heads that show up before we get 3 tails]]
+]
+
+[table Poisson Distributions
+ [[distribution] [explanation] [example]]
+ [[__poisson_distribution][poisson distribution]
+ [counting the number of alpha particles emitted
+ by radioactive matter in a fixed period of time]]
+ [[__exponential_distribution] [exponential distribution]
+ [measuring the inter-arrival time of alpha
+ particles emitted by radioactive matter]]
+ [[__gamma_distribution][gamma distribution][-]]
+ [[__weibull_distribution] [weibull distribution] [-]]
+ [[__extreme_value_distribution] [extreme value distribution] [-]]
+]
+
+[table Normal Distributions
+ [[distribution] [explanation] [example]]
+ [[__normal_distribution] [counts outcomes of (infinitely) repeated Bernoulli
+ experiments]
+ [tossing a coin 10000 times and counting how many
+ front sides are shown]]
+ [[__lognormal_distribution] [lognormal distribution (sometimes used in
+ simulations)]
+ [measuring the job completion time of an assembly
+ line worker]]
+ [[__chi_squared_distribution][chi-squared distribution][-]]
+ [[__cauchy_distribution][Cauchy distribution][-]]
+ [[__fisher_f_distribution][Fisher F distribution][-]]
+ [[__student_t_distribution][Student t distribution][-]]
+]
+
+[table Sampling Distributions
+ [[distribution] [explanation] [example]]
+ [[__discrete_distribution][discrete distribution with specific probabilities][rolling an unfair die]]
+ [[__piecewise_constant_distribution][-][-]]
+ [[__piecewise_linear_distribution][-][-]]
+]
+
+
+[table Miscellaneous Distributions
+ [[distribution] [explanation] [example]]
+ [[__triangle_distribution] [triangle distribution] [-]]
+ [[__uniform_on_sphere] [uniform distribution on a unit sphere of arbitrary
+ dimension]
+ [choosing a random point on Earth (assumed to be a
+ sphere) where to spend the next vacations]]
+]
diff --git a/libs/random/doc/generator_defs.qbk b/libs/random/doc/generator_defs.qbk
new file mode 100644
index 0000000000..abc9d3d75c
--- /dev/null
+++ b/libs/random/doc/generator_defs.qbk
@@ -0,0 +1,37 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+[template rand48_speed[] 68%]
+[template lrand48_run_time_speed[] 12%]
+[template minstd_rand0_speed[] 32%]
+[template minstd_rand_speed[] 26%]
+[template ecuyer_combined_speed[] 11%]
+[template kreutzer1986_speed[] 46%]
+[template hellekalek1995__inversive__speed[] 2%]
+[template mt11213b_speed[] 95%]
+[template mt19937_speed[] 100%]
+[template lagged_fibonacci607_speed[] 42%]
+[template lagged_fibonacci1279_speed[] 44%]
+[template lagged_fibonacci2281_speed[] 44%]
+[template lagged_fibonacci3217_speed[] 43%]
+[template lagged_fibonacci4423_speed[] 44%]
+[template lagged_fibonacci9689_speed[] 44%]
+[template lagged_fibonacci19937_speed[] 44%]
+[template lagged_fibonacci23209_speed[] 44%]
+[template lagged_fibonacci44497_speed[] 44%]
+[template subtract_with_carry_speed[] 72%]
+[template subtract_with_carry_01_speed[] 54%]
+[template ranlux3_speed[] 6%]
+[template ranlux4_speed[] 4%]
+[template ranlux3_01_speed[] 5%]
+[template ranlux4_01_speed[] 2%]
+[template ranlux64_3_speed[] 6%]
+[template ranlux64_4_speed[] 4%]
+[template ranlux64_3_01_speed[] 4%]
+[template ranlux64_4_01_speed[] 2%]
+[template mt19937ar_c_speed[] 97%]
diff --git a/libs/random/doc/generator_performance_linux.qbk b/libs/random/doc/generator_performance_linux.qbk
new file mode 100644
index 0000000000..9197b6ee88
--- /dev/null
+++ b/libs/random/doc/generator_performance_linux.qbk
@@ -0,0 +1,37 @@
+[table Basic Generators (Linux)
+ [[generator] [M rn/sec] [time per random number \[nsec\]] [relative speed compared to fastest \[percent\]]]
+ [[rand48][149.254][6.7][59%]]
+ [[lrand48 run-time][158.73][6.3][63%]]
+ [[minstd_rand0][22.9885][43.5][9%]]
+ [[minstd_rand][22.0751][45.3][8%]]
+ [[ecuyer combined][42.735][23.4][17%]]
+ [[kreutzer1986][151.515][6.6][60%]]
+ [[taus88][250][4][100%]]
+ [[knuth_b][19.6078][51][7%]]
+ [[hellekalek1995 (inversive)][4.54545][220][1%]]
+ [[mt11213b][204.082][4.9][81%]]
+ [[mt19937][204.082][4.9][81%]]
+ [[mt19937_64][60.6061][16.5][24%]]
+ [[lagged_fibonacci607][126.582][7.9][50%]]
+ [[lagged_fibonacci1279][129.87][7.7][51%]]
+ [[lagged_fibonacci2281][129.87][7.7][51%]]
+ [[lagged_fibonacci3217][131.579][7.6][52%]]
+ [[lagged_fibonacci4423][128.205][7.8][51%]]
+ [[lagged_fibonacci9689][128.205][7.8][51%]]
+ [[lagged_fibonacci19937][131.579][7.6][52%]]
+ [[lagged_fibonacci23209][131.579][7.6][52%]]
+ [[lagged_fibonacci44497][131.579][7.6][52%]]
+ [[subtract_with_carry][147.059][6.8][58%]]
+ [[subtract_with_carry_01][105.263][9.5][42%]]
+ [[ranlux3][15.748][63.5][6%]]
+ [[ranlux4][9.11577][109.7][3%]]
+ [[ranlux3_01][10.5708][94.6][4%]]
+ [[ranlux4_01][6.27353][159.4][2%]]
+ [[ranlux64_3][15.8983][62.9][6%]]
+ [[ranlux64_4][9.14913][109.3][3%]]
+ [[ranlux64_3_01][10.9409][91.4][4%]]
+ [[ranlux64_4_01][6.32911][158][2%]]
+ [[ranlux24][15.1976][65.8][6%]]
+ [[ranlux48][8.88099][112.6][3%]]
+ [[mt19937ar.c][111.111][9][44%]]
+]
diff --git a/libs/random/doc/generator_performance_windows.qbk b/libs/random/doc/generator_performance_windows.qbk
new file mode 100644
index 0000000000..35d0115390
--- /dev/null
+++ b/libs/random/doc/generator_performance_windows.qbk
@@ -0,0 +1,37 @@
+[table Basic Generators (Windows)
+ [[generator] [M rn/sec] [time per random number \[nsec\]] [relative speed compared to fastest \[percent\]]]
+ [[rand48][152.672][6.55][64%]]
+ [[lrand48 run-time][24.3724][41.03][10%]]
+ [[minstd_rand0][39.8248][25.11][16%]]
+ [[minstd_rand][39.0778][25.59][16%]]
+ [[ecuyer combined][16.7813][59.59][7%]]
+ [[kreutzer1986][89.0472][11.23][37%]]
+ [[taus88][237.53][4.21][100%]]
+ [[knuth_b][30.8166][32.45][12%]]
+ [[hellekalek1995 (inversive)][5.28457][189.23][2%]]
+ [[mt11213b][237.53][4.21][100%]]
+ [[mt19937][221.239][4.52][93%]]
+ [[mt19937_64][91.5751][10.92][38%]]
+ [[lagged_fibonacci607][142.45][7.02][59%]]
+ [[lagged_fibonacci1279][142.45][7.02][59%]]
+ [[lagged_fibonacci2281][145.56][6.87][61%]]
+ [[lagged_fibonacci3217][149.031][6.71][62%]]
+ [[lagged_fibonacci4423][142.45][7.02][59%]]
+ [[lagged_fibonacci9689][145.773][6.86][61%]]
+ [[lagged_fibonacci19937][142.45][7.02][59%]]
+ [[lagged_fibonacci23209][145.773][6.86][61%]]
+ [[lagged_fibonacci44497][142.45][7.02][59%]]
+ [[subtract_with_carry][136.24][7.34][57%]]
+ [[subtract_with_carry_01][90.3342][11.07][38%]]
+ [[ranlux3][13.1631][75.97][5%]]
+ [[ranlux4][7.60398][131.51][3%]]
+ [[ranlux3_01][8.62738][115.91][3%]]
+ [[ranlux4_01][4.99625][200.15][2%]]
+ [[ranlux64_3][13.1631][75.97][5%]]
+ [[ranlux64_4][7.5861][131.82][3%]]
+ [[ranlux64_3_01][8.63931][115.75][3%]]
+ [[ranlux64_4_01][5.01958][199.22][2%]]
+ [[ranlux24][13.1631][75.97][5%]]
+ [[ranlux48][7.5861][131.82][3%]]
+ [[mt19937ar.c][200.401][4.99][84%]]
+]
diff --git a/libs/random/doc/generators.qbk b/libs/random/doc/generators.qbk
new file mode 100644
index 0000000000..d1326cb756
--- /dev/null
+++ b/libs/random/doc/generators.qbk
@@ -0,0 +1,92 @@
+[/
+ / Copyright (c) 2009-2010 Steven Watanabe
+ /
+ / 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)
+]
+
+This library provides several [prng pseudo-random number generators]. The
+quality of a [prng pseudo random number generator] crucially depends on both
+the algorithm and its parameters. This library implements the algorithms as
+class templates with template value parameters, hidden in
+`namespace boost::random`. Any particular choice of parameters is represented
+as the appropriately specializing `typedef` in `namespace boost`.
+
+[prng Pseudo-random number generators] should not be constructed (initialized)
+frequently during program execution, for two reasons. First, initialization
+requires full initialization of the internal state of the generator. Thus,
+generators with a lot of internal state (see below) are costly to initialize.
+Second, initialization always requires some value used as a "seed" for the
+generated sequence. It is usually difficult to obtain several good seed
+values. For example, one method to obtain a seed is to determine the current
+time at the highest resolution available, e.g. microseconds or nanoseconds.
+When the [prng pseudo-random number generator] is initialized again with the
+then-current time as the seed, it is likely that this is at a near-constant
+(non-random) distance from the time given as the seed for first
+initialization. The distance could even be zero if the resolution of the
+clock is low, thus the generator re-iterates the same sequence of random
+numbers. For some applications, this is inappropriate.
+
+Note that all [prng pseudo-random number generators] described below are
+__CopyConstructible and __Assignable. Copying or assigning a generator will
+copy all its internal state, so the original and the copy will generate the
+identical sequence of random numbers. Often, such behavior is not wanted. In
+particular, beware of the algorithms from the standard library such as
+`std::generate`. They take a functor argument by value, thereby invoking the
+copy constructor when called.
+
+The following table gives an overview of some characteristics of the
+generators. The cycle length is a rough estimate of the quality of the
+generator; the approximate relative speed is a performance measure, higher
+numbers mean faster random number generation.
+
+[table generators
+ [[generator] [length of cycle] [approx. memory requirements] [approx. speed compared to fastest] [comment]]
+ [[__minstd_rand0] [2[sup 31]-2] [`sizeof(int32_t)`] [[minstd_rand0_speed]] [-]]
+ [[__minstd_rand] [2[sup 31]-2] [`sizeof(int32_t)`] [[minstd_rand_speed]] [-]]
+ [[__rand48][2[sup 48]-1] [`sizeof(uint64_t)`] [[rand48_speed]] [-]]
+ [[__ecuyer1988] [approx. 2[sup 61]] [`2*sizeof(int32_t)`] [[ecuyer_combined_speed]] [-]]
+ [[__knuth_b] [?] [`257*sizeof(uint32_t)`] [[knuth_b_speed]] [-]]
+ [[__kreutzer1986] [?] [`1368*sizeof(uint32_t)`] [[kreutzer1986_speed]] [-]]
+ [[__taus88] [~2[sup 88]] [`3*sizeof(uint32_t)`] [[taus88_speed]] [-]]
+ [[__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)`] [[mt19937_64_speed]] [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]] [-]]
+ [[__lagged_fibonacci3217] [~2[sup 170000]] [`3217*sizeof(double)`] [[lagged_fibonacci3217_speed]] [-]]
+ [[__lagged_fibonacci4423] [~2[sup 230000]] [`4423*sizeof(double)`] [[lagged_fibonacci4423_speed]] [-]]
+ [[__lagged_fibonacci9689] [~2[sup 510000]] [`9689*sizeof(double)`] [[lagged_fibonacci9689_speed]] [-]]
+ [[__lagged_fibonacci19937] [~2[sup 1050000]] [`19937*sizeof(double)`] [[lagged_fibonacci19937_speed]] [-]]
+ [[__lagged_fibonacci23209] [~2[sup 1200000]] [`23209*sizeof(double)`] [[lagged_fibonacci23209_speed]] [-]]
+ [[__lagged_fibonacci44497] [~2[sup 2300000]] [`44497*sizeof(double)`] [[lagged_fibonacci44497_speed]] [-]]
+ [[__ranlux3] [~10[sup 171]] [`24*sizeof(int)`] [[ranlux3_speed]] [-]]
+ [[__ranlux4] [~10[sup 171]] [`24*sizeof(int)`] [[ranlux4_speed]] [-]]
+ [[__ranlux64_3] [~10[sup 171]] [`24*sizeof(int64_t)`] [[ranlux64_3_speed]] [-]]
+ [[__ranlux64_4] [~10[sup 171]] [`24*sizeof(int64_t)`] [[ranlux64_4_speed]] [-]]
+ [[__ranlux3_01] [~10[sup 171]] [`24*sizeof(float)`] [[ranlux3_speed]] [-]]
+ [[__ranlux4_01] [~10[sup 171]] [`24*sizeof(float)`] [[ranlux4_speed]] [-]]
+ [[__ranlux64_3_01] [~10[sup 171]] [`24*sizeof(double)`] [[ranlux64_3_speed]] [-]]
+ [[__ranlux64_4_01] [~10[sup 171]] [`24*sizeof(double)`] [[ranlux64_4_speed]] [-]]
+ [[__ranlux24] [~10[sup 171]] [`24*sizeof(uint32_t)`] [[ranlux24_speed]] [-]]
+ [[__ranlux48] [~10[sup 171]] [`12*sizeof(uint64_t)`] [[ranlux48_speed]] [-]]
+]
+
+As observable from the table, there is generally a quality/performance/memory
+trade-off to be decided upon when choosing a random-number generator. The
+multitude of generators provided in this library allows the application
+programmer to optimize the trade-off with regard to his application domain.
+Additionally, employing several fundamentally different random number
+generators for a given application of Monte Carlo simulation will improve
+the confidence in the results.
+
+If the names of the generators don't ring any bell and you have no idea
+which generator to use, it is reasonable to employ __mt19937 for a start: It
+is fast and has acceptable quality.
+
+[note These random number generators are not intended for use in applications
+where non-deterministic random numbers are required. See __random_device
+for a choice of (hopefully) non-deterministic random number generators.]
diff --git a/libs/random/doc/nondet_random.qbk b/libs/random/doc/nondet_random.qbk
new file mode 100644
index 0000000000..edfa635e14
--- /dev/null
+++ b/libs/random/doc/nondet_random.qbk
@@ -0,0 +1,103 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+[section Header <boost/nondet_random.hpp> Synopsis]
+
+ namespace boost {
+ class random_device;
+ } // namespace boost
+
+[endsect]
+
+[section Class random_device]
+
+[section Synopsis]
+
+ class random_device : noncopyable
+ {
+ public:
+ typedef unsigned int result_type;
+ static const bool has_fixed_range = true;
+ static const result_type min_value = /* implementation defined */;
+ static const result_type max_value = /* implementation defined */;
+ result_type min() const;
+ result_type max() const;
+ explicit random_device(const std::string& token = default_token);
+ ~random_device();
+ double entropy() const;
+ unsigned int operator()();
+ };
+
+[endsect]
+
+[section Description]
+
+Class `random_device` models a non-deterministic random number generator. It
+uses one or more implementation-defined stochastic processes to generate a
+sequence of uniformly distributed non-deterministic random numbers. For those
+environments where a non-deterministic random number generator is not
+available, class random_device must not be implemented. See
+
+[:"Randomness Recommendations for Security", D. Eastlake, S. Crocker,
+J. Schiller, Network Working Group, RFC 1750, December 1994]
+
+for further discussions.
+
+[note Some operating systems abstract the computer hardware enough to make it
+difficult to non-intrusively monitor stochastic processes. However, several do
+provide a special device for exactly this purpose. It seems to be impossible
+to emulate the functionality using Standard C++ only, so users should be aware
+that this class may not be available on all platforms.]
+
+[endsect]
+
+[section Members]
+
+ explicit random_device(const std::string& token = default_token)
+
+Effects: Constructs a random_device, optionally using the given token as an
+access specification (for example, a URL) to some implementation-defined
+service for monitoring a stochastic process.
+
+ double entropy() const
+
+Returns: An entropy estimate for the random numbers returned by `operator()`,
+in the range `min()` to `log2(max()+1)`. A deterministic random number
+generator (e.g. a pseudo-random number engine) has entropy 0.
+
+Throws: Nothing.
+
+[endsect]
+
+Implementation Note for Linux
+On the Linux operating system, token is interpreted as a filesystem path. It
+is assumed that this path denotes an operating system pseudo-device which
+generates a stream of non-deterministic random numbers. The pseudo-device
+should never signal an error or end-of-file. Otherwise, std::ios_base::failure
+is thrown. By default, random_device uses the /dev/urandom pseudo-device to
+retrieve the random numbers. Another option would be to specify the
+/dev/random pseudo-device, which blocks on reads if the entropy pool has no
+more random bits available.
+
+[endsect]
+
+[section Performance]
+
+The test program nondet_random_speed.cpp measures the execution times of the
+nondet_random.hpp implementation of the above algorithms in a tight loop.
+The performance has been evaluated on a Pentium Pro 200 MHz with gcc 2.95.2,
+Linux 2.2.13, glibc 2.1.2.
+
+[table preformance
+ [[class] [time per invocation \[usec\]]]
+ [[random_device] [92.0]]
+]
+
+The measurement error is estimated at +/- 1 usec.
+
+[endsect]
diff --git a/libs/random/doc/performance.qbk b/libs/random/doc/performance.qbk
new file mode 100644
index 0000000000..151f74ad74
--- /dev/null
+++ b/libs/random/doc/performance.qbk
@@ -0,0 +1,28 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+For some people, performance of random number generation is an important
+consideration when choosing a random number generator or a particular
+distribution function. This page provides numerous performance tests with
+the wide variety of generators and distributions available in the boost
+library.
+
+The performance has been evaluated on an Intel(R) Core(TM) i7
+CPU Q 840 @ 1.87GHz, 1867 Mhz with Visual C++ 2010, Microsoft
+Windows 7 Professional and with gcc 4.4.5, Ubuntu Linux 2.6.35-25-generic.
+The speed is reported in million random numbers
+per second (M rn/sec), generated in a tight loop.
+
+[include generator_performance_linux.qbk]
+[include generator_performance_windows.qbk]
+
+Note that the lagged Fibonacci and ranlux_01 generators produce
+floating-point numbers, whereas all others produce integers.
+
+[include distribution_performance_linux.qbk]
+[include distribution_performance_windows.qbk]
diff --git a/libs/random/doc/performance_data.qbk b/libs/random/doc/performance_data.qbk
new file mode 100644
index 0000000000..c10e42a34c
--- /dev/null
+++ b/libs/random/doc/performance_data.qbk
@@ -0,0 +1,34 @@
+[template rand48_speed[] 64%]
+[template lrand48_run_time_speed[] 10%]
+[template minstd_rand0_speed[] 16%]
+[template minstd_rand_speed[] 16%]
+[template ecuyer_combined_speed[] 7%]
+[template kreutzer1986_speed[] 37%]
+[template taus88_speed[] 100%]
+[template knuth_b_speed[] 12%]
+[template hellekalek1995__inversive__speed[] 2%]
+[template mt11213b_speed[] 100%]
+[template mt19937_speed[] 93%]
+[template mt19937_64_speed[] 38%]
+[template lagged_fibonacci607_speed[] 59%]
+[template lagged_fibonacci1279_speed[] 59%]
+[template lagged_fibonacci2281_speed[] 61%]
+[template lagged_fibonacci3217_speed[] 62%]
+[template lagged_fibonacci4423_speed[] 59%]
+[template lagged_fibonacci9689_speed[] 61%]
+[template lagged_fibonacci19937_speed[] 59%]
+[template lagged_fibonacci23209_speed[] 61%]
+[template lagged_fibonacci44497_speed[] 59%]
+[template subtract_with_carry_speed[] 57%]
+[template subtract_with_carry_01_speed[] 38%]
+[template ranlux3_speed[] 5%]
+[template ranlux4_speed[] 3%]
+[template ranlux3_01_speed[] 3%]
+[template ranlux4_01_speed[] 2%]
+[template ranlux64_3_speed[] 5%]
+[template ranlux64_4_speed[] 3%]
+[template ranlux64_3_01_speed[] 3%]
+[template ranlux64_4_01_speed[] 2%]
+[template ranlux24_speed[] 5%]
+[template ranlux48_speed[] 3%]
+[template mt19937ar_c_speed[] 84%]
diff --git a/libs/random/doc/random.qbk b/libs/random/doc/random.qbk
new file mode 100644
index 0000000000..3a67ac792b
--- /dev/null
+++ b/libs/random/doc/random.qbk
@@ -0,0 +1,168 @@
+[library Boost.Random
+ [quickbook 1.5]
+ [authors [Maurer, Jens]]
+ [copyright 2000-2005 Jens Maurer, 2009-2010 Steven Watanabe]
+ [license
+ 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])
+ ]
+ [purpose A complete system for random number generation]
+]
+
+[template sup[text]'''<superscript>'''[text]'''</superscript>''']
+
+[template prng[text] [link boost_random.reference.concepts.pseudo_random_number_generator [text]]]
+[template concepts[text] [link boost_random.reference.concepts [text]]]
+[template generators[text] [link boost_random.reference.generators [text]]]
+[template distributions[text] [link boost_random.reference.distributions [text]]]
+
+[def __NumberGenerator [link boost_random.reference.concepts.number_generator NumberGenerator]]
+[def __UniformRandomNumberGenerator [link boost_random.reference.concepts.uniform_random_number_generator UniformRandomNumberGenerator]]
+
+[def __CopyConstructible [@boost:/doc/html/CopyConstructible.html CopyConstructible]]
+[def __Assignable [@boost:/doc/html/Assignable.html Assignable]]
+[def __LessThanComparable [@boost:/doc/html/LessThanComparable.html LessThanComparable]]
+[def __EqualityComparable [@boost:/doc/html/EqualityComparable.html EqualityComparable]]
+[def __Streamable Streamable]
+
+[def __random_device [classref boost::random::random_device random_device]]
+[def __random_number_generator [classref boost::random::random_number_generator random_number_generator]]
+[def __variate_generator [classref boost::random::variate_generator variate_generator]]
+
+[def __minstd_rand0 [classref boost::random::minstd_rand0 minstd_rand0]]
+[def __minstd_rand [classref boost::random::minstd_rand minstd_rand]]
+[def __rand48 [classref boost::random::rand48 rand48]]
+[def __ecuyer1988 [classref boost::random::ecuyer1988 ecuyer1988]]
+[def __kreutzer1986 [classref boost::random::kreutzer1986 kreutzer1986]]
+[def __knuth_b [classref boost::random::knuth_b knuth_b]]
+[def __taus88 [classref boost::random::taus88 taus88]]
+[def __hellekalek1995 [classref boost::random::hellekalek1995 hellekalek1995]]
+[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::random::lagged_fibonacci607 lagged_fibonacci607]]
+[def __lagged_fibonacci1279 [classref boost::random::lagged_fibonacci1279 lagged_fibonacci1279]]
+[def __lagged_fibonacci2281 [classref boost::random::lagged_fibonacci2281 lagged_fibonacci2281]]
+[def __lagged_fibonacci3217 [classref boost::random::lagged_fibonacci3217 lagged_fibonacci3217]]
+[def __lagged_fibonacci4423 [classref boost::random::lagged_fibonacci4423 lagged_fibonacci4423]]
+[def __lagged_fibonacci9689 [classref boost::random::lagged_fibonacci9689 lagged_fibonacci9689]]
+[def __lagged_fibonacci19937 [classref boost::random::lagged_fibonacci19937 lagged_fibonacci19937]]
+[def __lagged_fibonacci23209 [classref boost::random::lagged_fibonacci23209 lagged_fibonacci23209]]
+[def __lagged_fibonacci44497 [classref boost::random::lagged_fibonacci44497 lagged_fibonacci44497]]
+[def __ranlux3 [classref boost::random::ranlux3 ranlux3]]
+[def __ranlux4 [classref boost::random::ranlux4 ranlux4]]
+[def __ranlux64_3 [classref boost::random::ranlux64_3 ranlux64_3]]
+[def __ranlux64_4 [classref boost::random::ranlux64_4 ranlux64_4]]
+[def __ranlux3_01 [classref boost::random::ranlux3_01 ranlux3_01]]
+[def __ranlux4_01 [classref boost::random::ranlux4_01 ranlux4_01]]
+[def __ranlux64_3_01 [classref boost::random::ranlux64_3_01 ranlux64_3_01]]
+[def __ranlux64_4_01 [classref boost::random::ranlux64_4_01 ranlux64_4_01]]
+[def __ranlux24 [classref boost::random::ranlux24 ranlux24]]
+[def __ranlux48 [classref boost::random::ranlux48 ranlux48]]
+
+[def __uniform_smallint [classref boost::random::uniform_smallint uniform_smallint]]
+[def __uniform_int_distribution [classref boost::random::uniform_int_distribution uniform_int_distribution]]
+[def __uniform_01 [classref boost::random::uniform_01 uniform_01]]
+[def __uniform_real_distribution [classref boost::random::uniform_real_distribution uniform_real_distribution]]
+[def __bernoulli_distribution [classref boost::random::bernoulli_distribution bernoulli_distribution]]
+[def __binomial_distribution [classref boost::random::binomial_distribution binomial_distribution]]
+[def __cauchy_distribution [classref boost::random::cauchy_distribution cauchy_distribution]]
+[def __discrete_distribution [classref boost::random::discrete_distribution discrete_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::random::geometric_distribution geometric_distribution]]
+[def __triangle_distribution [classref boost::random::triangle_distribution triangle_distribution]]
+[def __exponential_distribution [classref boost::random::exponential_distribution exponential_distribution]]
+[def __normal_distribution [classref boost::random::normal_distribution normal_distribution]]
+[def __lognormal_distribution [classref boost::random::lognormal_distribution lognormal_distribution]]
+[def __uniform_on_sphere [classref boost::random::uniform_on_sphere uniform_on_sphere]]
+[def __weibull_distribution [classref boost::random::weibull_distribution weibull_distribution]]
+[def __extreme_value_distribution [classref boost::random::extreme_value_distribution extreme_value_distribution]]
+[def __negative_binomial_distribution [classref boost::random::negative_binomial_distribution negative_binomial_distribution]]
+[def __student_t_distribution [classref boost::random::student_t_distribution student_t_distribution]]
+[def __fisher_f_distribution [classref boost::random::fisher_f_distribution fisher_f_distribution]]
+[def __chi_squared_distribution [classref boost::random::chi_squared_distribution chi_squared_distribution]]
+[def __piecewise_constant_distribution [classref boost::random::piecewise_constant_distribution piecewise_constant_distribution]]
+[def __piecewise_linear_distribution [classref boost::random::piecewise_linear_distribution piecewise_linear_distribution]]
+
+[include performance_data.qbk]
+
+[section Introduction]
+
+Random numbers are useful in a variety of applications. The Boost Random
+Number Library (Boost.Random for short) provides a variety of
+[generators generators] and [distributions distributions] to produce
+random numbers having useful properties, such as uniform distribution.
+
+You should read the [concepts concepts documentation] for an introduction and the
+definition of the basic concepts. For a quick start, it may be sufficient
+to have a look at [@boost:/libs/random/example/random_demo.cpp random_demo.cpp].
+
+For a very quick start, here's an example:
+
+ ``[classref boost::random::mt19937]`` rng; // produces randomness out of thin air
+ // see pseudo-random number generators
+ ``[classref boost::random::uniform_int_distribution]<>`` six(1,6);
+ // distribution that maps to 1..6
+ // see random number distributions
+ int x = six(rng); // simulate rolling a die
+
+[endsect]
+
+[section Tutorial]
+[include tutorial.qbk]
+[endsect]
+
+[section Reference]
+
+[section Concepts]
+[include concepts.qbk]
+[endsect]
+
+[section Generators]
+[include generators.qbk]
+[endsect]
+
+[section Distributions]
+[include distributions.qbk]
+[endsect]
+
+[xinclude reference.xml]
+
+[endsect]
+
+[section Performance]
+[include performance.qbk]
+[endsect]
+
+[section History and Acknowledgements]
+
+In November 1999, Jeet Sukumaran proposed a framework based on virtual
+functions, and later sketched a template-based approach. Ed Brey pointed
+out that Microsoft Visual C++ does not support in-class member
+initializations and suggested the enum workaround. Dave Abrahams highlighted
+quantization issues.
+
+The first public release of this random number library materialized in
+March 2000 after extensive discussions on the boost mailing list. Many
+thanks to Beman Dawes for his original min_rand class, portability fixes,
+documentation suggestions, and general guidance. Harry Erwin sent a header
+file which provided additional insight into the requirements. Ed Brey and
+Beman Dawes wanted an iterator-like interface.
+
+Beman Dawes managed the formal review, during which Matthias Troyer,
+Csaba Szepesvari, and Thomas Holenstein gave detailed comments. The
+reviewed version became an official part of boost on 17 June 2000.
+
+Gary Powell contributed suggestions for code cleanliness. Dave Abrahams
+and Howard Hinnant suggested to move the basic generator templates from
+`namespace boost::detail` to `boost::random`.
+
+Ed Brey asked to remove superfluous warnings and helped with `uint64_t`
+handling. Andreas Scherer tested with MSVC. Matthias Troyer contributed
+a [headerref boost/random/lagged_fibonacci.hpp lagged Fibonacci generator].
+Michael Stevens found a bug in the copy semantics of __normal_distribution
+and suggested documentation improvements.
+
+[endsect]
diff --git a/libs/random/doc/tutorial.qbk b/libs/random/doc/tutorial.qbk
new file mode 100644
index 0000000000..d14c340e43
--- /dev/null
+++ b/libs/random/doc/tutorial.qbk
@@ -0,0 +1,28 @@
+[/
+ / Copyright (c) 2009 Steven Watanabe
+ /
+ / 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)
+]
+
+[section Generating integers in a range]
+
+[import ../example/die.cpp]
+[die]
+
+[endsect]
+
+[section Generating integers with different probabilities]
+
+[import ../example/weighted_die.cpp]
+[weighted_die]
+
+[endsect]
+
+[section Generating a random password]
+
+[import ../example/password.cpp]
+[password]
+
+[endsect]
diff --git a/libs/random/example/Jamfile.v2 b/libs/random/example/Jamfile.v2
new file mode 100644
index 0000000000..a57fe3f71d
--- /dev/null
+++ b/libs/random/example/Jamfile.v2
@@ -0,0 +1,12 @@
+# Jamfile.v2
+#
+# Copyright (c) 2009
+# Steven Watanabe
+#
+# 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)
+
+run die.cpp ;
+run weighted_die.cpp ;
+run password.cpp /boost//random ;
diff --git a/libs/random/example/die.cpp b/libs/random/example/die.cpp
new file mode 100644
index 0000000000..8ed0b8fc13
--- /dev/null
+++ b/libs/random/example/die.cpp
@@ -0,0 +1,60 @@
+// die.cpp
+//
+// Copyright (c) 2009
+// Steven Watanabe
+//
+// 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)
+
+//[die
+/*`
+ For the source of this example see
+ [@boost://libs/random/example/die.cpp die.cpp].
+ First we include the headers we need for __mt19937
+ and __uniform_int_distribution.
+*/
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+
+/*`
+ We use __mt19937 with the default seed as a source of
+ randomness. The numbers produced will be the same
+ every time the program is run. One common method to
+ change this is to seed with the current time (`std::time(0)`
+ defined in ctime).
+*/
+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
+ pseudo-random number generator] at every call]
+*/
+/*`
+ Now we can define a function that simulates an ordinary
+ six-sided die.
+*/
+int roll_die() {
+ /*<< __mt19937 produces integers in the range [0, 2[sup 32]-1].
+ However, we want numbers in the range [1, 6]. The distribution
+ __uniform_int_distribution performs this transformation.
+ [warning Contrary to common C++ usage __uniform_int_distribution
+ does not take a /half-open range/. Instead it takes a /closed range/.
+ Given the parameters 1 and 6, __uniform_int_distribution can
+ can produce any of the values 1, 2, 3, 4, 5, or 6.]
+ >>*/
+ boost::random::uniform_int_distribution<> dist(1, 6);
+ /*<< A distribution is a function object. We generate a random
+ number by calling `dist` with the generator.
+ >>*/
+ return dist(gen);
+}
+//]
+
+#include <iostream>
+
+int main() {
+ for(int i = 0; i < 10; ++i) {
+ std::cout << roll_die() << std::endl;
+ }
+}
diff --git a/libs/random/example/password.cpp b/libs/random/example/password.cpp
new file mode 100644
index 0000000000..19ab308e58
--- /dev/null
+++ b/libs/random/example/password.cpp
@@ -0,0 +1,48 @@
+// password.cpp
+//
+// Copyright (c) 2010
+// Steven Watanabe
+//
+// 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)
+
+//[password
+/*`
+ For the source of this example see
+ [@boost://libs/random/example/password.cpp password.cpp].
+
+ This example demonstrates generating a random 8 character
+ password.
+ */
+
+
+#include <boost/random/random_device.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+
+int main() {
+ /*<< We first define the characters that we're going
+ to allow. This is pretty much just the characters
+ on a standard keyboard.
+ >>*/
+ std::string chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "1234567890"
+ "!@#$%^&*()"
+ "`~-_=+[{]{\\|;:'\",<.>/? ");
+ /*<< We use __random_device as a source of entropy, since we want
+ passwords that are not predictable.
+ >>*/
+ boost::random::random_device rng;
+ /*<< Finally we select 8 random characters from the
+ string and print them to cout.
+ >>*/
+ boost::random::uniform_int_distribution<> index_dist(0, chars.size() - 1);
+ for(int i = 0; i < 8; ++i) {
+ std::cout << chars[index_dist(rng)];
+ }
+ std::cout << std::endl;
+}
+
+//]
diff --git a/libs/random/example/random_demo.cpp b/libs/random/example/random_demo.cpp
new file mode 100644
index 0000000000..9086b921c8
--- /dev/null
+++ b/libs/random/example/random_demo.cpp
@@ -0,0 +1,110 @@
+/* boost random_demo.cpp profane demo
+ *
+ * Copyright Jens Maurer 2000
+ * 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: random_demo.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ * A short demo program how to use the random number library.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <ctime> // std::time
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/variate_generator.hpp>
+#include <boost/generator_iterator.hpp>
+
+// This is a typedef for a random number generator.
+// Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand
+typedef boost::minstd_rand base_generator_type;
+
+// This is a reproducible simulation experiment. See main().
+void experiment(base_generator_type & generator)
+{
+ // Define a uniform random number distribution of integer values between
+ // 1 and 6 inclusive.
+ typedef boost::uniform_int<> distribution_type;
+ typedef boost::variate_generator<base_generator_type&, distribution_type> gen_type;
+ gen_type die_gen(generator, distribution_type(1, 6));
+
+ // If you want to use an STL iterator interface, use iterator_adaptors.hpp.
+ boost::generator_iterator<gen_type> die(&die_gen);
+ for(int i = 0; i < 10; i++)
+ std::cout << *die++ << " ";
+ std::cout << '\n';
+}
+
+int main()
+{
+ // Define a random number generator and initialize it with a reproducible
+ // seed.
+ base_generator_type generator(42);
+
+ std::cout << "10 samples of a uniform distribution in [0..1):\n";
+
+ // Define a uniform random number distribution which produces "double"
+ // values between 0 and 1 (0 inclusive, 1 exclusive).
+ boost::uniform_real<> uni_dist(0,1);
+ boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni(generator, uni_dist);
+
+ std::cout.setf(std::ios::fixed);
+ // You can now retrieve random numbers from that distribution by means
+ // of a STL Generator interface, i.e. calling the generator as a zero-
+ // argument function.
+ for(int i = 0; i < 10; i++)
+ std::cout << uni() << '\n';
+
+ /*
+ * Change seed to something else.
+ *
+ * Caveat: std::time(0) is not a very good truly-random seed. When
+ * called in rapid succession, it could return the same values, and
+ * thus the same random number sequences could ensue. If not the same
+ * values are returned, the values differ only slightly in the
+ * lowest bits. A linear congruential generator with a small factor
+ * wrapped in a uniform_smallint (see experiment) will produce the same
+ * values for the first few iterations. This is because uniform_smallint
+ * takes only the highest bits of the generator, and the generator itself
+ * needs a few iterations to spread the initial entropy from the lowest bits
+ * to the whole state.
+ */
+ generator.seed(static_cast<unsigned int>(std::time(0)));
+
+ std::cout << "\nexperiment: roll a die 10 times:\n";
+
+ // You can save a generator's state by copy construction.
+ base_generator_type saved_generator = generator;
+
+ // When calling other functions which take a generator or distribution
+ // as a parameter, make sure to always call by reference (or pointer).
+ // Calling by value invokes the copy constructor, which means that the
+ // sequence of random numbers at the caller is disconnected from the
+ // sequence at the callee.
+ experiment(generator);
+
+ std::cout << "redo the experiment to verify it:\n";
+ experiment(saved_generator);
+
+ // After that, both generators are equivalent
+ assert(generator == saved_generator);
+
+ // as a degenerate case, you can set min = max for uniform_int
+ boost::uniform_int<> degen_dist(4,4);
+ boost::variate_generator<base_generator_type&, boost::uniform_int<> > deg(generator, degen_dist);
+ std::cout << deg() << " " << deg() << " " << deg() << std::endl;
+
+ {
+ // You can save the generator state for future use. You can read the
+ // state back in at any later time using operator>>.
+ std::ofstream file("rng.saved", std::ofstream::trunc);
+ file << generator;
+ }
+
+ return 0;
+}
diff --git a/libs/random/example/weighted_die.cpp b/libs/random/example/weighted_die.cpp
new file mode 100644
index 0000000000..8dd9c2ac72
--- /dev/null
+++ b/libs/random/example/weighted_die.cpp
@@ -0,0 +1,55 @@
+// weighted_die.cpp
+//
+// Copyright (c) 2009
+// Steven Watanabe
+//
+// 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)
+
+//[weighted_die
+/*`
+ For the source of this example see
+ [@boost://libs/random/example/weighted_die.cpp weighted_die.cpp].
+*/
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/discrete_distribution.hpp>
+
+boost::mt19937 gen;
+
+/*`
+ This time, instead of a fair die, the probability of
+ rolling a 1 is 50% (!). The other five faces are all
+ equally likely.
+
+ __discrete_distribution works nicely here by allowing
+ us to assign weights to each of the possible outcomes.
+
+ [tip If your compiler supports `std::initializer_list`,
+ you can initialize __discrete_distribution directly with
+ the weights.]
+*/
+double probabilities[] = {
+ 0.5, 0.1, 0.1, 0.1, 0.1, 0.1
+};
+boost::random::discrete_distribution<> dist(probabilities);
+
+/*`
+ Now define a function that simulates rolling this die.
+*/
+int roll_weighted_die() {
+ /*<< Add 1 to make sure that the result is in the range [1,6]
+ instead of [0,5].
+ >>*/
+ return dist(gen) + 1;
+}
+
+//]
+
+#include <iostream>
+
+int main() {
+ for(int i = 0; i < 10; ++i) {
+ std::cout << roll_weighted_die() << std::endl;
+ }
+}
diff --git a/libs/random/extra/Jamfile.v2 b/libs/random/extra/Jamfile.v2
new file mode 100644
index 0000000000..a0ee2af3b2
--- /dev/null
+++ b/libs/random/extra/Jamfile.v2
@@ -0,0 +1,10 @@
+# Jamfile.v2
+#
+# Copyright (c) 2009
+# Steven Watanabe
+#
+# 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)
+
+run test_haertel.cpp ;
diff --git a/libs/random/extra/haertel.hpp b/libs/random/extra/haertel.hpp
new file mode 100644
index 0000000000..e3907509ef
--- /dev/null
+++ b/libs/random/extra/haertel.hpp
@@ -0,0 +1,156 @@
+/* haertel.hpp file
+ *
+ * Copyright Jens Maurer 2000, 2002
+ * 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: haertel.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ * Revision history
+ */
+
+/*
+ * NOTE: This is not part of the official boost submission. It exists
+ * only as a collection of ideas.
+ */
+
+#ifndef BOOST_RANDOM_HAERTEL_HPP
+#define BOOST_RANDOM_HAERTEL_HPP
+
+#include <boost/cstdint.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/inversive_congruential.hpp>
+
+namespace boost {
+namespace random {
+
+// Wikramaratna 1989 ACORN
+template<class IntType, int k, IntType m, IntType val>
+class additive_congruential
+{
+public:
+ typedef IntType result_type;
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+ static const bool has_fixed_range = true;
+ static const result_type min_value = 0;
+ static const result_type max_value = m-1;
+#else
+ enum {
+ has_fixed_range = true,
+ min_value = 0,
+ max_value = m-1
+ };
+#endif
+ template<class InputIterator>
+ explicit additive_congruential(InputIterator start) { seed(start); }
+ template<class InputIterator>
+ void seed(InputIterator start)
+ {
+ for(int i = 0; i <= k; ++i, ++start)
+ values[i] = *start;
+ }
+
+ result_type operator()()
+ {
+ for(int i = 1; i <= k; ++i) {
+ IntType tmp = values[i-1] + values[i];
+ if(tmp >= m)
+ tmp -= m;
+ values[i] = tmp;
+ }
+ return values[k];
+ }
+ result_type validation() const { return val; }
+private:
+ IntType values[k+1];
+};
+
+
+template<class IntType, int r, int s, IntType m, IntType val>
+class lagged_fibonacci_int
+{
+public:
+ typedef IntType result_type;
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+ static const bool has_fixed_range = true;
+ static const result_type min_value = 0;
+ static const result_type max_value = m-1;
+#else
+ enum {
+ has_fixed_range = true,
+ min_value = 0,
+ max_value = m-1
+ };
+#endif
+ explicit lagged_fibonacci_int(IntType start) { seed(start); }
+ template<class Generator>
+ explicit lagged_fibonacci_int(Generator & gen) { seed(gen); }
+ void seed(IntType start)
+ {
+ linear_congruential<uint32_t, 299375077, 0, 0, 0> init;
+ seed(init);
+ }
+ template<class Generator>
+ void seed(Generator & gen)
+ {
+ assert(r > s);
+ for(int i = 0; i < 607; ++i)
+ values[i] = gen();
+ current = 0;
+ lag = r-s;
+ }
+
+ result_type operator()()
+ {
+ result_type tmp = values[current] + values[lag];
+ if(tmp >= m)
+ tmp -= m;
+ values[current] = tmp;
+ ++current;
+ if(current >= r)
+ current = 0;
+ ++lag;
+ if(lag >= r)
+ lag = 0;
+ return tmp;
+ }
+ result_type validation() const { return val; }
+private:
+ result_type values[r];
+ int current, lag;
+};
+
+} // namespace random
+} // namespace boost
+
+// distributions from Haertel's dissertation
+// (additional parameterizations of the basic templates)
+namespace Haertel {
+ typedef boost::random::linear_congruential<boost::uint64_t, 45965, 453816691,
+ (boost::uint64_t(1)<<31), 0> LCG_Af2;
+ typedef boost::random::linear_congruential<boost::uint64_t, 211936855, 0,
+ (boost::uint64_t(1)<<29)-3, 0> LCG_Die1;
+ typedef boost::random::linear_congruential<boost::uint32_t, 2824527309u, 0,
+ 0, 0> LCG_Fis;
+ typedef boost::random::linear_congruential<boost::uint64_t, 950706376u, 0,
+ (boost::uint64_t(1)<<31)-1, 0> LCG_FM;
+ typedef boost::random::linear_congruential<boost::int32_t, 51081, 0,
+ 2147483647, 0> LCG_Hae;
+ typedef boost::random::linear_congruential<boost::uint32_t, 69069, 1,
+ 0, 0> LCG_VAX;
+ typedef boost::random::inversive_congruential<boost::int64_t, 240318, 197,
+ 1000081, 0> NLG_Inv1;
+ typedef boost::random::inversive_congruential<boost::int64_t, 15707262,
+ 13262967, (1<<24)-17, 0> NLG_Inv2;
+ typedef boost::random::inversive_congruential<boost::int32_t, 1, 1,
+ 2147483647, 0> NLG_Inv4;
+ typedef boost::random::inversive_congruential<boost::int32_t, 1, 2,
+ 1<<30, 0> NLG_Inv5;
+ typedef boost::random::additive_congruential<boost::int32_t, 6,
+ (1<<30)-35, 0> MRG_Acorn7;
+ typedef boost::random::lagged_fibonacci_int<boost::uint32_t, 607, 273,
+ 0, 0> MRG_Fib2;
+} // namespace Haertel
+
+#endif
diff --git a/libs/random/extra/test_haertel.cpp b/libs/random/extra/test_haertel.cpp
new file mode 100644
index 0000000000..9ae3020d9b
--- /dev/null
+++ b/libs/random/extra/test_haertel.cpp
@@ -0,0 +1,62 @@
+/* haertel.hpp file
+ *
+ * Copyright Jens Maurer 2000, 2002
+ * 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: test_haertel.cpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ * Revision history
+ */
+
+#include <string>
+#include <iostream>
+
+#include <boost/format.hpp>
+
+#include "haertel.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/included/unit_test.hpp>
+
+template<class Gen, class T>
+inline void check_validation(Gen & gen, T value, const std::string & name)
+{
+ for(int i = 0; i < 100000-1; ++i)
+ gen();
+
+ typename Gen::result_type actual = gen();
+ BOOST_CHECK_MESSAGE(value == actual,
+ boost::str(boost::format("%s: check value == gen() failed [%d != %d]") %
+ name % value % actual));
+}
+
+// we have validation after 100000 steps with Haertel's generators
+template<class Gen, class T>
+void validate(T value, const std::string & name)
+{
+ Gen gen(1234567);
+ check_validation(gen, value, name);
+}
+
+BOOST_AUTO_TEST_CASE(test_haertel)
+{
+ using namespace Haertel;
+ validate<LCG_Af2>(183269031u, "LCG_Af2");
+ validate<LCG_Die1>(522319944u, "LCG_Die1");
+ validate<LCG_Fis>(-2065162233u, "LCG_Fis");
+ validate<LCG_FM>(581815473u, "LCG_FM");
+ validate<LCG_Hae>(28931709, "LCG_Hae");
+ validate<LCG_VAX>(1508154087u, "LCG_VAX");
+ validate<NLG_Inv2>(6666884, "NLG_Inv2");
+ validate<NLG_Inv4>(1521640076, "NLG_Inv4");
+ validate<NLG_Inv5>(641840839, "NLG_Inv5");
+ static const int acorn7_init[]
+ = { 1234567, 7654321, 246810, 108642, 13579, 97531, 555555 };
+ MRG_Acorn7 acorn7(acorn7_init);
+ check_validation(acorn7, 874294697, "MRG_Acorn7");
+ // This currently fails. I don't want to touch it until
+ // I trace the source of this generator. --SJW
+ validate<MRG_Fib2>(1234567u, "MRG_Fib2");
+}
diff --git a/libs/random/index.html b/libs/random/index.html
new file mode 100644
index 0000000000..9c0a8475d6
--- /dev/null
+++ b/libs/random/index.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost_random.html">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_random.html">../../doc/html/boost_random.html</a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/nondet_random.html b/libs/random/nondet_random.html
new file mode 100644
index 0000000000..d0ae9a8a14
--- /dev/null
+++ b/libs/random/nondet_random.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost/random_device.html">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost/random_device.html">
+ ../../doc/html/boost/random_device.html
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/performance/Jamfile.v2 b/libs/random/performance/Jamfile.v2
new file mode 100644
index 0000000000..431538589b
--- /dev/null
+++ b/libs/random/performance/Jamfile.v2
@@ -0,0 +1,18 @@
+mt19937ar-files = [ glob mt19937ar.c ] ;
+
+if $(mt19937ar-files)
+{
+ alias mt19937ar : $(mt19937ar-files) : : <define>HAVE_MT19937AR_C ;
+}
+else
+{
+ alias mt19937ar ;
+}
+
+exe random_speed.exe : random_speed.cpp mt19937ar : release ;
+exe generate_table.exe : generate_table.cpp /boost//regex : <link>static ;
+exe nondet_random_speed.exe : nondet_random_speed.cpp /boost//random : release <link>static ;
+
+install random_speed : random_speed.exe : <install-type>EXE <location>. ;
+install nondet_random_speed : nondet_random_speed.exe : <install-type>EXE <location>. ;
+install generate_table : generate_table.exe : <install-type>EXE <location>. ;
diff --git a/libs/random/performance/generate_table.cpp b/libs/random/performance/generate_table.cpp
new file mode 100644
index 0000000000..c899d08f72
--- /dev/null
+++ b/libs/random/performance/generate_table.cpp
@@ -0,0 +1,133 @@
+// generate_table.cpp
+//
+// Copyright (c) 2009
+// Steven Watanabe
+//
+// 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)
+
+#include <vector>
+#include <utility>
+#include <iostream>
+#include <cstring>
+#include <fstream>
+#include <boost/regex.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+
+boost::regex generator_regex("(?:fixed-range )?([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
+boost::regex distribution_regex("([^\\s]+)( virtual function)? ([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
+
+std::string template_name(std::string arg) {
+ return boost::regex_replace(arg, boost::regex("[^\\w]"), "_");
+}
+
+struct compare_second {
+ template<class Pair>
+ bool operator()(const Pair& p1, const Pair& p2) const {
+ return (p1.second < p2.second);
+ }
+};
+
+typedef boost::multi_index_container<
+ std::string,
+ boost::mpl::vector<
+ boost::multi_index::sequenced<>,
+ boost::multi_index::hashed_unique<boost::multi_index::identity<std::string> >
+ >
+> unique_list;
+
+int main(int argc, char** argv) {
+
+ std::string suffix;
+ std::string id;
+
+ if(argc >= 2 && std::strcmp(argv[1], "-linux") == 0) {
+ suffix = "linux";
+ id = "Linux";
+ } else {
+ suffix = "windows";
+ id = "Windows";
+ }
+
+ std::vector<std::pair<std::string, double> > generator_info;
+ std::string line;
+ while(std::getline(std::cin, line)) {
+ boost::smatch match;
+ if(std::strncmp(line.c_str(), "counting ", 9) == 0) break;
+ if(boost::regex_match(line, match, generator_regex)) {
+ std::string generator(match[1]);
+ double time = boost::lexical_cast<double>(match[2]);
+ if(generator != "counting") {
+ generator_info.push_back(std::make_pair(generator, time));
+ }
+ } else {
+ std::cerr << "oops: " << line << std::endl;
+ }
+ }
+
+ double min = std::min_element(generator_info.begin(), generator_info.end(), compare_second())->second;
+
+ std::ofstream generator_defs("performance_data.qbk");
+ std::ofstream generator_performance(("generator_performance_" + suffix + ".qbk").c_str());
+ generator_performance << "[table Basic Generators (" << id << ")\n";
+ generator_performance << " [[generator] [M rn/sec] [time per random number \\[nsec\\]] "
+ "[relative speed compared to fastest \\[percent\\]]]\n";
+
+ typedef std::pair<std::string, double> pair_type;
+ BOOST_FOREACH(const pair_type& pair, generator_info) {
+ generator_defs << boost::format("[template %s_speed[] %d%%]\n")
+ % template_name(pair.first) % static_cast<int>(100*min/pair.second);
+ generator_performance << boost::format(" [[%s][%g][%g][%d%%]]\n")
+ % pair.first % (1000/pair.second) % pair.second % static_cast<int>(100*min/pair.second);
+ }
+ generator_performance << "]\n";
+
+ std::map<std::pair<std::string, std::string>, double> distribution_info;
+ unique_list generator_names;
+ unique_list distribution_names;
+ do {
+ boost::smatch match;
+ if(boost::regex_match(line, match, distribution_regex)) {
+ if(!match[2].matched && match[1] != "counting") {
+ std::string generator(match[1]);
+ std::string distribution(match[3]);
+ double time = boost::lexical_cast<double>(match[4]);
+ generator_names.push_back(generator);
+ distribution_names.push_back(distribution);
+ distribution_info.insert(std::make_pair(std::make_pair(distribution, generator), time));
+ }
+ } else {
+ std::cerr << "oops: " << line << std::endl;
+ }
+ } while(std::getline(std::cin, line));
+
+ std::ofstream distribution_performance(("distribution_performance_" + suffix + ".qbk").c_str());
+
+ distribution_performance << "[table Distributions (" << id << ")\n";
+ distribution_performance << " [[\\[M rn/sec\\]]";
+ BOOST_FOREACH(const std::string& generator, generator_names) {
+ distribution_performance << boost::format("[%s]") % generator;
+ }
+ distribution_performance << "]\n";
+ BOOST_FOREACH(const std::string& distribution, distribution_names) {
+ distribution_performance << boost::format(" [[%s]") % distribution;
+ BOOST_FOREACH(const std::string& generator, generator_names) {
+ std::map<std::pair<std::string, std::string>, double>::iterator pos =
+ distribution_info.find(std::make_pair(distribution, generator));
+ if(pos != distribution_info.end()) {
+ distribution_performance << boost::format("[%g]") % (1000/pos->second);
+ } else {
+ distribution_performance << "[-]";
+ }
+ }
+ distribution_performance << "]\n";
+ }
+ distribution_performance << "]\n";
+}
diff --git a/libs/random/performance/nondet_random_speed.cpp b/libs/random/performance/nondet_random_speed.cpp
new file mode 100644
index 0000000000..56a1da8d5f
--- /dev/null
+++ b/libs/random/performance/nondet_random_speed.cpp
@@ -0,0 +1,60 @@
+/* boost nondet_random_speed.cpp performance test
+ *
+ * Copyright Jens Maurer 2000
+ * 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: nondet_random_speed.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <iostream>
+#include <string>
+#include <boost/timer.hpp>
+#include <boost/random/random_device.hpp>
+
+// set to your CPU frequency
+static const double cpu_frequency = 1.87 * 1e9;
+
+static void show_elapsed(double end, int iter, const std::string & name)
+{
+ double usec = end/iter*1e6;
+ double cycles = usec * cpu_frequency/1e6;
+ std::cout << name << ": "
+ << usec*1e3 << " nsec/loop = "
+ << cycles << " CPU cycles"
+ << std::endl;
+}
+
+template<class Result, class RNG>
+static void timing(RNG & rng, int iter, const std::string& name)
+{
+ volatile Result tmp; // make sure we're not optimizing too much
+ boost::timer t;
+ for(int i = 0; i < iter; i++)
+ tmp = rng();
+ show_elapsed(t.elapsed(), iter, name);
+}
+
+template<class RNG>
+void run(int iter, const std::string & name)
+{
+ RNG rng;
+ timing<long>(rng, iter, name);
+}
+
+int main(int argc, char*argv[])
+{
+ if(argc != 2) {
+ std::cerr << "usage: " << argv[0] << " iterations" << std::endl;
+ return 1;
+ }
+
+ int iter = std::atoi(argv[1]);
+
+ boost::random::random_device dev;
+ timing<unsigned int>(dev, iter, "random_device");
+
+ return 0;
+}
diff --git a/libs/random/performance/random_speed.cpp b/libs/random/performance/random_speed.cpp
new file mode 100644
index 0000000000..d1aa32e6c0
--- /dev/null
+++ b/libs/random/performance/random_speed.cpp
@@ -0,0 +1,399 @@
+/* boost random_speed.cpp performance measurements
+ *
+ * Copyright Jens Maurer 2000
+ * 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: random_speed.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <boost/config.hpp>
+#include <boost/random.hpp>
+#include <boost/progress.hpp>
+#include <boost/shared_ptr.hpp>
+
+/*
+ * Configuration Section
+ */
+
+// define if your C library supports the non-standard drand48 family
+//#define HAVE_DRAND48
+
+// define if you have the original mt19937int.c (with commented out main())
+#undef HAVE_MT19937INT_C
+
+// define if you have the original mt19937ar.c (with commented out main())
+// #define HAVE_MT19937AR_C
+
+// set to your CPU frequency
+static const double cpu_frequency = 1.87 * 1e9;
+
+/*
+ * End of Configuration Section
+ */
+
+/*
+ * General portability note:
+ * MSVC mis-compiles explicit function template instantiations.
+ * For example, f<A>() and f<B>() are both compiled to call f<A>().
+ * BCC is unable to implicitly convert a "const char *" to a std::string
+ * when using explicit function template instantiations.
+ *
+ * Therefore, avoid explicit function template instantiations.
+ */
+
+// provides a run-time configurable linear congruential generator, just
+// for comparison
+template<class IntType>
+class linear_congruential
+{
+public:
+ typedef IntType result_type;
+
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+ linear_congruential(IntType x0, IntType a, IntType c, IntType m)
+ : _x(x0), _a(a), _c(c), _m(m) { }
+ // compiler-generated copy ctor and assignment operator are fine
+ void seed(IntType x0, IntType a, IntType c, IntType m)
+ { _x = x0; _a = a; _c = c; _m = m; }
+ void seed(IntType x0) { _x = x0; }
+ result_type operator()() { _x = (_a*_x+_c) % _m; return _x; }
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c == 0 ? 1 : 0; }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _m -1; }
+
+private:
+ IntType _x, _a, _c, _m;
+};
+
+
+// simplest "random" number generator possible, to check on overhead
+class counting
+{
+public:
+ typedef int result_type;
+
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+ counting() : _x(0) { }
+ result_type operator()() { return ++_x; }
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::numeric_limits<result_type>::max)(); }
+
+private:
+ int _x;
+};
+
+
+// decoration of variate_generator to make it runtime-exchangeable
+// for speed comparison
+template<class Ret>
+class RandomGenBase
+{
+public:
+ virtual Ret operator()() = 0;
+ virtual ~RandomGenBase() { }
+};
+
+template<class URNG, class Dist, class Ret = typename Dist::result_type>
+class DynamicRandomGenerator
+ : public RandomGenBase<Ret>
+{
+public:
+ DynamicRandomGenerator(URNG& urng, const Dist& d) : _rng(urng, d) { }
+ Ret operator()() { return _rng(); }
+private:
+ boost::variate_generator<URNG&, Dist> _rng;
+};
+
+template<class Ret>
+class GenericRandomGenerator
+{
+public:
+ typedef Ret result_type;
+
+ GenericRandomGenerator() { };
+ void set(boost::shared_ptr<RandomGenBase<Ret> > p) { _p = p; }
+ // takes over ownership
+ void set(RandomGenBase<Ret> * p) { _p.reset(p); }
+ Ret operator()() { return (*_p)(); }
+private:
+ boost::shared_ptr<RandomGenBase<Ret> > _p;
+};
+
+
+// start implementation of measuring timing
+
+void show_elapsed(double end, int iter, const std::string & name)
+{
+ double usec = end/iter*1e6;
+ double cycles = usec * cpu_frequency/1e6;
+ std::cout << name << ": "
+ << usec*1e3 << " nsec/loop = "
+ << cycles << " CPU cycles"
+ << std::endl;
+}
+
+#if 0
+template<class RNG>
+void timing(RNG & rng, int iter, const std::string& name)
+{
+ // make sure we're not optimizing too much
+ volatile typename RNG::result_type tmp;
+ boost::timer t;
+ for(int i = 0; i < iter; i++)
+ tmp = rng();
+ show_elapsed(t.elapsed(), iter, name);
+}
+#endif
+
+// overload for using a copy, allows more concise invocation
+template<class RNG>
+void timing(RNG rng, int iter, const std::string& name)
+{
+ // make sure we're not optimizing too much
+ volatile typename RNG::result_type tmp;
+ boost::timer t;
+ for(int i = 0; i < iter; i++)
+ tmp = rng();
+ show_elapsed(t.elapsed(), iter, name);
+}
+
+template<class RNG>
+void timing_sphere(RNG rng, int iter, const std::string & name)
+{
+ boost::timer t;
+ for(int i = 0; i < iter; i++) {
+ // the special return value convention of uniform_on_sphere saves 20% CPU
+ const std::vector<double> & tmp = rng();
+ (void) tmp[0];
+ }
+ show_elapsed(t.elapsed(), iter, name);
+}
+
+template<class RNG>
+void run(int iter, const std::string & name, RNG rng)
+{
+ std::cout << (RNG::has_fixed_range ? "fixed-range " : "");
+ // BCC has trouble with string autoconversion for explicit specializations
+
+ // make sure we're not optimizing too much
+ volatile typename RNG::result_type tmp;
+ boost::timer t;
+ for(int i = 0; i < iter; i++)
+ tmp = rng();
+ show_elapsed(t.elapsed(), iter, name);
+}
+
+#ifdef HAVE_DRAND48
+// requires non-standard C library support for srand48/lrand48
+struct lrand48_ {
+ static const bool has_fixed_range = false;
+ typedef long result_type;
+ lrand48_() {
+ using namespace std;
+ srand48(1);
+ }
+ result_type operator()() {
+ using namespace std;
+ return lrand48();
+ }
+};
+#endif
+
+#ifdef HAVE_MT19937INT_C // requires the original mt19937int.c
+extern "C" void sgenrand(unsigned long);
+extern "C" unsigned long genrand();
+
+void run(int iter, const std::string & name, float)
+{
+ sgenrand(4357);
+ timing(genrand, iter, name, 0u);
+}
+#endif
+
+#ifdef HAVE_MT19937AR_C
+extern "C" {
+void init_genrand(unsigned long s);
+unsigned long genrand_int32(void);
+}
+struct mt19937_c {
+ static const bool has_fixed_range = false;
+ mt19937_c() {
+ init_genrand(5489);
+ }
+ typedef unsigned long result_type;
+ result_type operator()() {
+ return genrand_int32();
+ }
+};
+#endif
+
+template<class PRNG, class Dist>
+inline boost::variate_generator<PRNG&, Dist> make_gen(PRNG & rng, Dist d)
+{
+ return boost::variate_generator<PRNG&, Dist>(rng, d);
+}
+
+template<class Gen>
+void distrib(int iter, const std::string & name, const Gen &)
+{
+ Gen gen;
+
+ timing(make_gen(gen, boost::random::uniform_int_distribution<>(-2, 4)),
+ iter, name + " uniform_int");
+
+ timing(make_gen(gen, boost::random::uniform_smallint<>(-2, 4)),
+ iter, name + " uniform_smallint");
+
+ timing(make_gen(gen, boost::random::bernoulli_distribution<>(0.5)),
+ iter, name + " bernoulli");
+
+ timing(make_gen(gen, boost::random::geometric_distribution<>(0.5)),
+ iter, name + " geometric");
+
+ timing(make_gen(gen, boost::random::binomial_distribution<int>(4, 0.8)),
+ iter, name + " binomial");
+
+ timing(make_gen(gen, boost::random::negative_binomial_distribution<int>(4, 0.8)),
+ iter, name + " negative_binomial");
+
+ timing(make_gen(gen, boost::random::poisson_distribution<>(1)),
+ iter, name + " poisson");
+
+
+ timing(make_gen(gen, boost::random::uniform_real_distribution<>(-5.3, 4.8)),
+ iter, name + " uniform_real");
+
+ timing(make_gen(gen, boost::random::uniform_01<>()),
+ iter, name + " uniform_01");
+
+ timing(make_gen(gen, boost::random::triangle_distribution<>(1, 2, 7)),
+ iter, name + " triangle");
+
+ timing(make_gen(gen, boost::random::exponential_distribution<>(3)),
+ iter, name + " exponential");
+
+ timing(make_gen(gen, boost::random::normal_distribution<>()),
+ iter, name + " normal polar");
+
+ timing(make_gen(gen, boost::random::lognormal_distribution<>()),
+ iter, name + " lognormal");
+
+ timing(make_gen(gen, boost::random::chi_squared_distribution<>(4)),
+ iter, name + " chi squared");
+
+ timing(make_gen(gen, boost::random::cauchy_distribution<>()),
+ iter, name + " cauchy");
+
+ timing(make_gen(gen, boost::random::fisher_f_distribution<>(4, 5)),
+ iter, name + " fisher f");
+
+ timing(make_gen(gen, boost::random::student_t_distribution<>(7)),
+ iter, name + " student t");
+
+ timing(make_gen(gen, boost::random::gamma_distribution<>(2.8)),
+ iter, name + " gamma");
+
+ timing(make_gen(gen, boost::random::weibull_distribution<>(3)),
+ iter, name + " weibull");
+
+ timing(make_gen(gen, boost::random::extreme_value_distribution<>()),
+ iter, name + " extreme value");
+
+ timing_sphere(make_gen(gen, boost::random::uniform_on_sphere<>(3)),
+ iter/10, name + " uniform_on_sphere");
+}
+
+int main(int argc, char*argv[])
+{
+ if(argc != 2) {
+ std::cerr << "usage: " << argv[0] << " iterations" << std::endl;
+ return 1;
+ }
+
+ // okay, it's ugly, but it's only used here
+ int iter =
+#ifndef BOOST_NO_STDC_NAMESPACE
+ std::
+#endif
+ atoi(argv[1]);
+
+#if !defined(BOOST_NO_INT64_T) && \
+ !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+ run(iter, "rand48", boost::rand48());
+ linear_congruential<boost::uint64_t>
+ lcg48(boost::uint64_t(1)<<16 | 0x330e,
+ boost::uint64_t(0xDEECE66DUL) | (boost::uint64_t(0x5) << 32), 0xB,
+ boost::uint64_t(1)<<48);
+ timing(lcg48, iter, "lrand48 run-time");
+#endif
+
+#ifdef HAVE_DRAND48
+ // requires non-standard C library support for srand48/lrand48
+ run(iter, "lrand48", lrand48_()); // coded for lrand48()
+#endif
+
+ run(iter, "minstd_rand0", boost::minstd_rand0());
+ run(iter, "minstd_rand", boost::minstd_rand());
+ run(iter, "ecuyer combined", boost::ecuyer1988());
+ run(iter, "kreutzer1986", boost::kreutzer1986());
+ run(iter, "taus88", boost::taus88());
+ run(iter, "knuth_b", boost::random::knuth_b());
+
+ run(iter, "hellekalek1995 (inversive)", boost::hellekalek1995());
+
+ run(iter, "mt11213b", boost::mt11213b());
+ run(iter, "mt19937", boost::mt19937());
+#if !defined(BOOST_NO_INT64_T)
+ run(iter, "mt19937_64", boost::mt19937_64());
+#endif
+
+ run(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
+ run(iter, "lagged_fibonacci1279", boost::lagged_fibonacci1279());
+ run(iter, "lagged_fibonacci2281", boost::lagged_fibonacci2281());
+ run(iter, "lagged_fibonacci3217", boost::lagged_fibonacci3217());
+ run(iter, "lagged_fibonacci4423", boost::lagged_fibonacci4423());
+ run(iter, "lagged_fibonacci9689", boost::lagged_fibonacci9689());
+ run(iter, "lagged_fibonacci19937", boost::lagged_fibonacci19937());
+ run(iter, "lagged_fibonacci23209", boost::lagged_fibonacci23209());
+ run(iter, "lagged_fibonacci44497", boost::lagged_fibonacci44497());
+
+ run(iter, "subtract_with_carry", boost::random::ranlux_base());
+ run(iter, "subtract_with_carry_01", boost::random::ranlux_base_01());
+ run(iter, "ranlux3", boost::ranlux3());
+ run(iter, "ranlux4", boost::ranlux4());
+ run(iter, "ranlux3_01", boost::ranlux3_01());
+ run(iter, "ranlux4_01", boost::ranlux4_01());
+ run(iter, "ranlux64_3", boost::ranlux3());
+ run(iter, "ranlux64_4", boost::ranlux4());
+ run(iter, "ranlux64_3_01", boost::ranlux3_01());
+ run(iter, "ranlux64_4_01", boost::ranlux4_01());
+ run(iter, "ranlux24", boost::ranlux3());
+ run(iter, "ranlux48", boost::ranlux4());
+
+ run(iter, "counting", counting());
+
+#ifdef HAVE_MT19937INT_C
+ // requires the original mt19937int.c
+ run<float>(iter, "mt19937 original"); // coded for sgenrand()/genrand()
+#endif
+
+#ifdef HAVE_MT19937AR_C
+ run(iter, "mt19937ar.c", mt19937_c());
+#endif
+
+ distrib(iter, "counting", counting());
+
+ distrib(iter, "minstd_rand", boost::minstd_rand());
+
+ distrib(iter, "kreutzer1986", boost::kreutzer1986());
+
+ distrib(iter, "mt19937", boost::mt19937());
+
+ distrib(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
+}
diff --git a/libs/random/random-concepts.html b/libs/random/random-concepts.html
new file mode 100644
index 0000000000..aea420b192
--- /dev/null
+++ b/libs/random/random-concepts.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost_random/reference.html#boost_random.reference.concepts">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_random/reference.html#boost_random.reference.concepts">
+ ../../doc/html/boost_random/reference.html#boost_random.reference.concepts
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/random-distributions.html b/libs/random/random-distributions.html
new file mode 100644
index 0000000000..605bfa69d4
--- /dev/null
+++ b/libs/random/random-distributions.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost_random/reference.html#boost_random.reference.distributions">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_random/reference.html#boost_random.reference.distributions">
+ ../../doc/html/boost_random/reference.html#boost_random.reference.distributions
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/random-generators.html b/libs/random/random-generators.html
new file mode 100644
index 0000000000..1872c4097f
--- /dev/null
+++ b/libs/random/random-generators.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost_random/reference.html#boost_random.reference.generators">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_random/reference.html#boost_random.reference.generators">
+ ../../doc/html/boost_random/reference.html#boost_random.reference.generators
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/random-misc.html b/libs/random/random-misc.html
new file mode 100644
index 0000000000..5b319904bf
--- /dev/null
+++ b/libs/random/random-misc.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost/random_number_generator.html">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost/random_number_generator.html">
+ ../../doc/html/boost/random_number_generator.html
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/random-performance.html b/libs/random/random-performance.html
new file mode 100644
index 0000000000..6cbef8dea0
--- /dev/null
+++ b/libs/random/random-performance.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost_random/performance.html">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_random/performance.html">
+ ../../doc/html/boost_random/performance.html
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/random-variate.html b/libs/random/random-variate.html
new file mode 100644
index 0000000000..a5d931feed
--- /dev/null
+++ b/libs/random/random-variate.html
@@ -0,0 +1,17 @@
+<html>
+ <!-- boostinspect:nounlinked boostinspect:nolink -->
+ <head>
+ <meta http-equiv="refresh" content="0; URL=../../doc/html/boost/variate_generator.html">
+ </head>
+ <body>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost/variate_generator.html">
+ ../../doc/html/boost/variate_generator.html
+ </a>
+ <p>Copyright (c) 2010 Steven Watanabe</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+ </body>
+</html>
diff --git a/libs/random/src/random_device.cpp b/libs/random/src/random_device.cpp
new file mode 100644
index 0000000000..699a880fdd
--- /dev/null
+++ b/libs/random/src/random_device.cpp
@@ -0,0 +1,217 @@
+/* boost random_device.cpp implementation
+ *
+ * Copyright Jens Maurer 2000
+ * Copyright Steven Watanabe 2010-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: random_device.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#define BOOST_RANDOM_SOURCE
+
+#include <boost/random/random_device.hpp>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/detail/workaround.hpp>
+#include <string>
+
+#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+// A definition is required even for integral static constants
+const bool boost::random::random_device::has_fixed_range;
+#endif
+
+
+#if defined(BOOST_WINDOWS)
+
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdexcept> // std::invalid_argument
+
+#define BOOST_AUTO_LINK_NOMANGLE
+#define BOOST_LIB_NAME "Advapi32"
+#include <boost/config/auto_link.hpp>
+
+#ifdef __MINGW32__
+
+extern "C" {
+
+// mingw's wincrypt.h appears to be missing some things
+WINADVAPI
+BOOL
+WINAPI
+CryptEnumProvidersA(
+ DWORD dwIndex,
+ DWORD *pdwReserved,
+ DWORD dwFlags,
+ DWORD *pdwProvType,
+ LPSTR szProvName,
+ DWORD *pcbProvName
+ );
+
+}
+
+#endif
+
+namespace {
+
+const char * const default_token = MS_DEF_PROV_A;
+
+}
+
+class boost::random::random_device::impl
+{
+public:
+ impl(const std::string & token) : provider(token) {
+ char buffer[80];
+ DWORD type;
+ DWORD len;
+
+ // Find the type of the provider
+ for(DWORD i = 0; ; ++i) {
+ len = sizeof(buffer);
+ if(!CryptEnumProvidersA(i, NULL, 0, &type, buffer, &len)) {
+ error("Could not find provider name");
+ }
+ if(buffer == provider) {
+ break;
+ }
+ }
+
+ if(!CryptAcquireContextA(&hProv, NULL, provider.c_str(), type,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ error("Could not acquire CSP context");
+ }
+ }
+
+ ~impl() {
+ if(!CryptReleaseContext(hProv, 0)) error("Could not release CSP context");
+ }
+
+ unsigned int next() {
+ unsigned int result;
+
+ if(!CryptGenRandom(hProv, sizeof(result),
+ static_cast<BYTE*>(static_cast<void*>(&result)))) {
+ error("error while reading");
+ }
+
+ return result;
+ }
+
+private:
+ void error(const std::string & msg) {
+ char buf[80];
+ DWORD num = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ 0,
+ buf,
+ sizeof(buf),
+ NULL);
+
+ throw std::invalid_argument("boost::random_device: " + msg +
+ " Cryptopraphic Service Provider " + provider +
+ ": " + std::string(&buf[0], &buf[0] + num));
+ }
+ const std::string provider;
+ HCRYPTPROV hProv;
+};
+
+#else
+
+namespace {
+// the default is the unlimited capacity device, using some secure hash
+// try "/dev/random" for blocking when the entropy pool has drained
+const char * const default_token = "/dev/urandom";
+}
+
+/*
+ * This uses the POSIX interface for unbuffered reading.
+ * Using buffered std::istream would consume entropy which may
+ * not actually be used. Entropy is a precious good we avoid
+ * wasting.
+ */
+
+#if defined(__GNUC__) && defined(_CXXRT_STD_NAME)
+// I have severe difficulty to get the POSIX includes to work with
+// -fhonor-std and Dietmar Kuhl's standard C++ library. Hack around that
+// problem for now.
+extern "C" {
+static const int O_RDONLY = 0;
+extern int open(const char *__file, int __oflag, ...);
+extern int read(int __fd, __ptr_t __buf, size_t __nbytes);
+extern int close(int __fd);
+}
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h> // open
+#include <unistd.h> // read, close
+#endif
+
+#include <errno.h> // errno
+#include <string.h> // strerror
+#include <stdexcept> // std::invalid_argument
+
+
+class boost::random::random_device::impl
+{
+public:
+ impl(const std::string & token) : path(token) {
+ fd = open(token.c_str(), O_RDONLY);
+ if(fd < 0)
+ error("cannot open");
+ }
+
+ ~impl() { if(close(fd) < 0) error("could not close"); }
+
+ unsigned int next() {
+ unsigned int result;
+ long sz = read(fd, reinterpret_cast<char *>(&result), sizeof(result));
+ if(sz == -1)
+ error("error while reading");
+ else if(sz != sizeof(result)) {
+ errno = 0;
+ error("EOF while reading");
+ }
+ return result;
+ }
+
+private:
+ void error(const std::string & msg) {
+ throw std::invalid_argument("boost::random_device: " + msg +
+ " random-number pseudo-device " + path +
+ ": " + strerror(errno));
+ }
+ const std::string path;
+ int fd;
+};
+
+#endif // BOOST_WINDOWS
+
+BOOST_RANDOM_DECL boost::random::random_device::random_device()
+ : pimpl(new impl(default_token))
+{}
+
+BOOST_RANDOM_DECL boost::random::random_device::random_device(const std::string& token)
+ : pimpl(new impl(token))
+{}
+
+BOOST_RANDOM_DECL boost::random_device::~random_device()
+{
+ delete pimpl;
+}
+
+BOOST_RANDOM_DECL double boost::random_device::entropy() const
+{
+ return 10;
+}
+
+BOOST_RANDOM_DECL unsigned int boost::random_device::operator()()
+{
+ return pimpl->next();
+}
diff --git a/libs/random/test/Jamfile.v2 b/libs/random/test/Jamfile.v2
new file mode 100644
index 0000000000..8cdae2bfa2
--- /dev/null
+++ b/libs/random/test/Jamfile.v2
@@ -0,0 +1,126 @@
+# Copyright 2003 Jens Maurer
+# Copyright 2009-2011 Steven Watanabe
+# Distributed under the Boost Software License, Version 1.0. (See accompany-
+# ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Boost Random Library test Jamfile
+
+# bring in rules for testing
+import testing ;
+
+project /boost/random/test : requirements <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS ;
+
+run test_const_mod.cpp /boost//unit_test_framework ;
+run test_generate_canonical.cpp /boost//unit_test_framework ;
+run test_random_number_generator.cpp /boost//unit_test_framework ;
+run ../example/random_demo.cpp ;
+run test_random_device.cpp /boost//random : : : <link>static : test_random_device ;
+run test_random_device.cpp /boost//random : : : <link>shared : test_random_device_dll ;
+
+run test_minstd_rand0.cpp /boost//unit_test_framework ;
+run test_minstd_rand.cpp /boost//unit_test_framework ;
+run test_rand48.cpp /boost//unit_test_framework ;
+run test_mt11213b.cpp /boost//unit_test_framework ;
+run test_mt19937.cpp /boost//unit_test_framework ;
+run test_mt19937_64.cpp /boost//unit_test_framework ;
+run test_ecuyer1988.cpp /boost//unit_test_framework ;
+run test_hellekalek1995.cpp /boost//unit_test_framework ;
+run test_linear_feedback_shift.cpp /boost//unit_test_framework ;
+run test_taus88.cpp /boost//unit_test_framework ;
+run test_kreutzer1986.cpp /boost//unit_test_framework ;
+run test_ranlux3.cpp /boost//unit_test_framework ;
+run test_ranlux4.cpp /boost//unit_test_framework ;
+run test_ranlux3_01.cpp /boost//unit_test_framework ;
+run test_ranlux4_01.cpp /boost//unit_test_framework ;
+run test_ranlux64_4.cpp /boost//unit_test_framework ;
+run test_ranlux64_3.cpp /boost//unit_test_framework ;
+run test_ranlux64_3_01.cpp /boost//unit_test_framework ;
+run test_ranlux64_4_01.cpp /boost//unit_test_framework ;
+run test_ranlux24_base.cpp /boost//unit_test_framework ;
+run test_ranlux24.cpp /boost//unit_test_framework ;
+run test_ranlux48_base.cpp /boost//unit_test_framework ;
+run test_ranlux48.cpp /boost//unit_test_framework ;
+run test_knuth_b.cpp /boost//unit_test_framework ;
+run test_independent_bits31.cpp /boost//unit_test_framework ;
+run test_independent_bits32.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci607.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci1279.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci2281.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci3217.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci4423.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci9689.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci19937.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci23209.cpp /boost//unit_test_framework ;
+run test_lagged_fibonacci44497.cpp /boost//unit_test_framework ;
+
+# Disable by default. These don't add much and the larger
+# ones can overflow the stack.
+explicit test_lagged_fibonacci1279 test_lagged_fibonacci2281
+ test_lagged_fibonacci2281 test_lagged_fibonacci3217
+ test_lagged_fibonacci4423 test_lagged_fibonacci9689
+ test_lagged_fibonacci19937 test_lagged_fibonacci23209
+ test_lagged_fibonacci44497 ;
+
+run test_seed_seq.cpp /boost//unit_test_framework ;
+
+run test_binomial.cpp ;
+run test_binomial_distribution.cpp /boost//unit_test_framework ;
+run test_poisson.cpp ;
+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 test_weibull.cpp ;
+run test_weibull_distribution.cpp /boost//unit_test_framework ;
+run test_extreme_value.cpp ;
+run test_extreme_value_distribution.cpp /boost//unit_test_framework ;
+run test_negative_binomial.cpp ;
+run test_negative_binomial_distribution.cpp /boost//unit_test_framework ;
+run test_chi_squared.cpp ;
+run test_chi_squared_distribution.cpp /boost//unit_test_framework ;
+run test_fisher_f.cpp ;
+run test_fisher_f_distribution.cpp /boost//unit_test_framework ;
+run test_student_t.cpp ;
+run test_student_t_distribution.cpp /boost//unit_test_framework ;
+run test_normal.cpp ;
+run test_normal_distribution.cpp /boost//unit_test_framework ;
+run test_piecewise_constant.cpp ;
+run test_piecewise_constant_distribution.cpp /boost//unit_test_framework ;
+run test_piecewise_linear.cpp ;
+run test_piecewise_linear_distribution.cpp /boost//unit_test_framework ;
+run test_exponential.cpp ;
+run test_exponential_distribution.cpp /boost//unit_test_framework ;
+run test_bernoulli.cpp ;
+run test_bernoulli_distribution.cpp /boost//unit_test_framework ;
+run test_cauchy.cpp ;
+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 test_triangle.cpp ;
+run test_triangle_distribution.cpp /boost//unit_test_framework ;
+run test_uniform_int.cpp ;
+run test_uniform_int_distribution.cpp /boost//unit_test_framework ;
+run test_uniform_real.cpp ;
+run test_uniform_real_distribution.cpp /boost//unit_test_framework ;
+run test_uniform_on_sphere_distribution.cpp /boost//unit_test_framework ;
+run test_uniform_smallint.cpp ;
+run test_uniform_smallint_distribution.cpp /boost//unit_test_framework ;
+run test_old_uniform_real.cpp ;
+run test_old_uniform_real_distribution.cpp /boost//unit_test_framework ;
+run test_old_uniform_int.cpp ;
+run test_old_uniform_int_distribution.cpp /boost//unit_test_framework ;
+
+# run nondet_random_speed.cpp ;
+# run random_device.cpp ;
+# run random_speed.cpp ;
+# run statistic_tests.cpp ;
+
+exe statistic_tests.exe : statistic_tests.cpp ;
+explicit statistic_tests.exe ;
+
+install statistic_tests : statistic_tests.exe : <install-type>EXE <location>. ;
+explicit statistic_tests ;
diff --git a/libs/random/test/chi_squared_test.hpp b/libs/random/test/chi_squared_test.hpp
new file mode 100644
index 0000000000..46355205c3
--- /dev/null
+++ b/libs/random/test/chi_squared_test.hpp
@@ -0,0 +1,92 @@
+/* chi_squared_test.hpp header file
+ *
+ * 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: chi_squared_test.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#ifndef BOOST_RANDOM_TEST_CHI_SQUARED_TEST_HPP_INCLUDED
+#define BOOST_RANDOM_TEST_CHI_SQUARED_TEST_HPP_INCLUDED
+
+#include <vector>
+
+#include <boost/math/special_functions/pow.hpp>
+#include <boost/math/distributions/chi_squared.hpp>
+
+// This only works for discrete distributions with fixed
+// upper and lower bounds.
+
+template<class IntType>
+struct chi_squared_collector {
+
+ static const IntType cutoff = 5;
+
+ chi_squared_collector()
+ : chi_squared(0),
+ variables(0),
+ prev_actual(0),
+ prev_expected(0),
+ current_actual(0),
+ current_expected(0)
+ {}
+
+ void operator()(IntType actual, double expected) {
+ current_actual += actual;
+ current_expected += expected;
+
+ if(current_expected >= cutoff) {
+ if(prev_expected != 0) {
+ update(prev_actual, prev_expected);
+ }
+ prev_actual = current_actual;
+ prev_expected = current_expected;
+
+ current_actual = 0;
+ current_expected = 0;
+ }
+ }
+
+ void update(IntType actual, double expected) {
+ chi_squared += boost::math::pow<2>(actual - expected) / expected;
+ ++variables;
+ }
+
+ double cdf() {
+ if(prev_expected != 0) {
+ update(prev_actual + current_actual, prev_expected + current_expected);
+ prev_actual = 0;
+ prev_expected = 0;
+ current_actual = 0;
+ current_expected = 0;
+ }
+ if(variables <= 1) {
+ return 0;
+ } else {
+ return boost::math::cdf(boost::math::chi_squared(variables - 1), chi_squared);
+ }
+ }
+
+ double chi_squared;
+ std::size_t variables;
+
+ IntType prev_actual;
+ double prev_expected;
+
+ IntType current_actual;
+ double current_expected;
+};
+
+template<class IntType>
+double chi_squared_test(const std::vector<IntType>& results, const std::vector<double>& probabilities, IntType iterations) {
+ chi_squared_collector<IntType> calc;
+ for(std::size_t i = 0; i < results.size(); ++i) {
+ calc(results[i], iterations * probabilities[i]);
+ }
+ return calc.cdf();
+}
+
+#endif
diff --git a/libs/random/test/concepts.hpp b/libs/random/test/concepts.hpp
new file mode 100644
index 0000000000..b901f56ac9
--- /dev/null
+++ b/libs/random/test/concepts.hpp
@@ -0,0 +1,210 @@
+/* concepts.hpp
+ *
+ * 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: concepts.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $
+ *
+ */
+
+#ifndef BOOST_RANDOM_TEST_CONCEPTS_HPP
+#define BOOST_RANDOM_TEST_CONCEPTS_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4100)
+#endif
+
+#include <boost/concept_check.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/concept_archetype.hpp>
+#include <boost/concept/requires.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <istream>
+#include <ostream>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4510)
+#pragma warning(disable:4610)
+#endif
+
+namespace boost {
+namespace random {
+namespace test {
+
+template<class Base = null_archetype<> >
+struct seed_seq_archetype : Base
+{
+ template<class Iter>
+ BOOST_CONCEPT_REQUIRES(
+ ((Mutable_RandomAccessIterator<Iter>))
+ ((UnsignedInteger<typename Mutable_RandomAccessIterator<Iter>::value_type>)),
+ (void))
+ generate(Iter, Iter) {}
+};
+
+template<class R = unsigned, class Base = null_archetype<> >
+struct uniform_random_number_generator_archetype : Base
+{
+ typedef R result_type;
+ static R min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ static R max BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ R operator()() { return 0; }
+};
+
+template<class SSeq>
+struct SeedSeq
+{
+public:
+ BOOST_CONCEPT_USAGE(SeedSeq)
+ {
+ q.generate(rb, re);
+ }
+private:
+ SSeq q;
+ mutable_random_access_iterator_archetype<boost::uint32_t> rb, re;
+};
+
+template<class T>
+struct Streamable
+{
+public:
+ BOOST_CONCEPT_USAGE(Streamable)
+ {
+ os << x;
+ is >> v;
+ wos << x;
+ wis >> v;
+ }
+private:
+ const T x;
+ T v;
+
+ std::istream is;
+ std::ostream os;
+ std::wistream wis;
+ std::wostream wos;
+};
+
+// Type deduction will fail unless the arguments have the same type.
+template <typename T>
+void same_type(T const&, T const&) {}
+
+template <class E>
+struct RandomNumberEngine :
+ DefaultConstructible<E>,
+ CopyConstructible<E>,
+ Assignable<E>,
+ EqualityComparable<E>,
+ Streamable<E>
+{
+public:
+ typedef typename E::result_type result_type;
+
+ // relaxed from the standard
+ BOOST_MPL_ASSERT((boost::is_arithmetic<result_type>));
+
+ // backwards compatibility check
+ BOOST_STATIC_ASSERT(!E::has_fixed_range);
+
+ // a generator can be used to seed another generator (extension)
+ BOOST_CONCEPT_ASSERT((SeedSeq<E>));
+
+ BOOST_CONCEPT_USAGE(RandomNumberEngine)
+ {
+ same_type(e(), result_type());
+ same_type((E::min)(), result_type());
+ same_type((E::max)(), result_type());
+
+ (void)E();
+ (void)E(s);
+ (void)E(q);
+
+ e.seed();
+ e.seed(s);
+ e.seed(q);
+
+ e.discard(z);
+
+ // extension
+ (void)E(sb, se);
+ e.seed(sb, se);
+ }
+
+private:
+ E e;
+ E v;
+ const E x;
+ seed_seq_archetype<> q;
+ typename detail::seed_type<result_type>::type s;
+ unsigned long long z;
+
+ input_iterator_archetype<boost::uint32_t> sb, se;
+};
+
+template<class D>
+struct RandomNumberDistribution :
+ DefaultConstructible<D>,
+ CopyConstructible<D>,
+ Assignable<D>,
+ EqualityComparable<D>,
+ Streamable<D>
+{
+public:
+ typedef typename D::result_type result_type;
+ typedef typename D::param_type param_type;
+ // backwards compatibility
+ typedef typename D::input_type input_type;
+
+ typedef param_type P;
+
+ BOOST_CONCEPT_ASSERT((DefaultConstructible<P>));
+ BOOST_CONCEPT_ASSERT((CopyConstructible<P>));
+ BOOST_CONCEPT_ASSERT((Assignable<P>));
+ BOOST_CONCEPT_ASSERT((EqualityComparable<P>));
+ BOOST_CONCEPT_ASSERT((Streamable<P>));
+
+ BOOST_MPL_ASSERT((boost::is_same<typename P::distribution_type, D>));
+
+ BOOST_CONCEPT_USAGE(RandomNumberDistribution)
+ {
+ (void)D(p);
+ d.reset();
+ same_type(x.param(), p);
+ d.param(p);
+ same_type(d(g), result_type());
+ same_type(d(g, p), result_type());
+ same_type((x.min)(), result_type());
+ same_type((x.max)(), result_type());
+ }
+
+private:
+ D d;
+ const D x;
+ const P p;
+ uniform_random_number_generator_archetype<> g;
+};
+
+}
+}
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/libs/random/test/histogram.cpp b/libs/random/test/histogram.cpp
new file mode 100644
index 0000000000..11ad00c3f3
--- /dev/null
+++ b/libs/random/test/histogram.cpp
@@ -0,0 +1,165 @@
+/* boost histogram.cpp graphical verification of distribution functions
+ *
+ * Copyright Jens Maurer 2000
+ * 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: histogram.cpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ * This test program allows to visibly examine the results of the
+ * distribution functions.
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include <cmath>
+#include <string>
+#include <boost/random.hpp>
+
+
+void plot_histogram(const std::vector<int>& slots, int samples,
+ double from, double to)
+{
+ int m = *std::max_element(slots.begin(), slots.end());
+ const int nRows = 20;
+ std::cout.setf(std::ios::fixed|std::ios::left);
+ std::cout.precision(5);
+ for(int r = 0; r < nRows; r++) {
+ double y = ((nRows - r) * double(m))/(nRows * samples);
+ std::cout << std::setw(10) << y << " ";
+ for(unsigned int col = 0; col < slots.size(); col++) {
+ char out = ' ';
+ if(slots[col]/double(samples) >= y)
+ out = 'x';
+ std::cout << out;
+ }
+ std::cout << std::endl;
+ }
+ std::cout << std::setw(12) << " "
+ << std::setw(10) << from;
+ std::cout.setf(std::ios::right, std::ios::adjustfield);
+ std::cout << std::setw(slots.size()-10) << to << std::endl;
+}
+
+// I am not sure whether these two should be in the library as well
+
+// maintain sum of NumberGenerator results
+template<class NumberGenerator,
+ class Sum = typename NumberGenerator::result_type>
+class sum_result
+{
+public:
+ typedef NumberGenerator base_type;
+ typedef typename base_type::result_type result_type;
+ explicit sum_result(const base_type & g) : gen(g), _sum(0) { }
+ result_type operator()() { result_type r = gen(); _sum += r; return r; }
+ base_type & base() { return gen; }
+ Sum sum() const { return _sum; }
+ void reset() { _sum = 0; }
+private:
+ base_type gen;
+ Sum _sum;
+};
+
+
+// maintain square sum of NumberGenerator results
+template<class NumberGenerator,
+ class Sum = typename NumberGenerator::result_type>
+class squaresum_result
+{
+public:
+ typedef NumberGenerator base_type;
+ typedef typename base_type::result_type result_type;
+ explicit squaresum_result(const base_type & g) : gen(g), _sum(0) { }
+ result_type operator()() { result_type r = gen(); _sum += r*r; return r; }
+ base_type & base() { return gen; }
+ Sum squaresum() const { return _sum; }
+ void reset() { _sum = 0; }
+private:
+ base_type gen;
+ Sum _sum;
+};
+
+
+template<class RNG>
+void histogram(RNG base, int samples, double from, double to,
+ const std::string & name)
+{
+ typedef squaresum_result<sum_result<RNG, double>, double > SRNG;
+ SRNG gen((sum_result<RNG, double>(base)));
+ const int nSlots = 60;
+ std::vector<int> slots(nSlots,0);
+ for(int i = 0; i < samples; i++) {
+ double val = gen();
+ if(val < from || val >= to) // early check avoids overflow
+ continue;
+ int slot = int((val-from)/(to-from) * nSlots);
+ if(slot < 0 || slot > (int)slots.size())
+ continue;
+ slots[slot]++;
+ }
+ std::cout << name << std::endl;
+ plot_histogram(slots, samples, from, to);
+ double mean = gen.base().sum() / samples;
+ std::cout << "mean: " << mean
+ << " sigma: " << std::sqrt(gen.squaresum()/samples-mean*mean)
+ << "\n" << std::endl;
+}
+
+template<class PRNG, class Dist>
+inline boost::variate_generator<PRNG&, Dist> make_gen(PRNG & rng, Dist d)
+{
+ return boost::variate_generator<PRNG&, Dist>(rng, d);
+}
+
+template<class PRNG>
+void histograms()
+{
+ PRNG rng;
+ using namespace boost;
+ histogram(make_gen(rng, uniform_smallint<>(0, 5)), 100000, -1, 6,
+ "uniform_smallint(0,5)");
+ histogram(make_gen(rng, uniform_int<>(0, 5)), 100000, -1, 6,
+ "uniform_int(0,5)");
+ histogram(make_gen(rng, uniform_real<>(0,1)), 100000, -0.5, 1.5,
+ "uniform_real(0,1)");
+ histogram(make_gen(rng, bernoulli_distribution<>(0.2)), 100000, -0.5, 1.5,
+ "bernoulli(0.2)");
+ histogram(make_gen(rng, binomial_distribution<>(4, 0.2)), 100000, -1, 5,
+ "binomial(4, 0.2)");
+ histogram(make_gen(rng, triangle_distribution<>(1, 2, 8)), 100000, 0, 10,
+ "triangle(1,2,8)");
+ histogram(make_gen(rng, geometric_distribution<>(5.0/6.0)), 100000, 0, 10,
+ "geometric(5/6)");
+ histogram(make_gen(rng, exponential_distribution<>(0.3)), 100000, 0, 10,
+ "exponential(0.3)");
+ histogram(make_gen(rng, cauchy_distribution<>()), 100000, -5, 5,
+ "cauchy");
+ histogram(make_gen(rng, lognormal_distribution<>(3, 2)), 100000, 0, 10,
+ "lognormal");
+ histogram(make_gen(rng, normal_distribution<>()), 100000, -3, 3,
+ "normal");
+ histogram(make_gen(rng, normal_distribution<>(0.5, 0.5)), 100000, -3, 3,
+ "normal(0.5, 0.5)");
+ histogram(make_gen(rng, poisson_distribution<>(1.5)), 100000, 0, 5,
+ "poisson(1.5)");
+ histogram(make_gen(rng, poisson_distribution<>(10)), 100000, 0, 20,
+ "poisson(10)");
+ histogram(make_gen(rng, gamma_distribution<>(0.5)), 100000, 0, 0.5,
+ "gamma(0.5)");
+ histogram(make_gen(rng, gamma_distribution<>(1)), 100000, 0, 3,
+ "gamma(1)");
+ histogram(make_gen(rng, gamma_distribution<>(2)), 100000, 0, 6,
+ "gamma(2)");
+}
+
+
+int main()
+{
+ histograms<boost::mt19937>();
+ // histograms<boost::lagged_fibonacci607>();
+}
+
diff --git a/libs/random/test/integrate.hpp b/libs/random/test/integrate.hpp
new file mode 100644
index 0000000000..2bef63ca54
--- /dev/null
+++ b/libs/random/test/integrate.hpp
@@ -0,0 +1,79 @@
+/* integrate.hpp header file
+ *
+ * Copyright Jens Maurer 2000
+ * 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: integrate.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ * Revision history
+ * 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
+ */
+
+#ifndef INTEGRATE_HPP
+#define INTEGRATE_HPP
+
+#include <boost/limits.hpp>
+
+template<class UnaryFunction>
+inline typename UnaryFunction::result_type
+trapezoid(UnaryFunction f, typename UnaryFunction::argument_type a,
+ typename UnaryFunction::argument_type b, int n)
+{
+ typename UnaryFunction::result_type tmp = 0;
+ for(int i = 1; i <= n-1; ++i)
+ tmp += f(a+(b-a)/n*i);
+ return (b-a)/2/n * (f(a) + f(b) + 2*tmp);
+}
+
+template<class UnaryFunction>
+inline typename UnaryFunction::result_type
+simpson(UnaryFunction f, typename UnaryFunction::argument_type a,
+ typename UnaryFunction::argument_type b, int n)
+{
+ typename UnaryFunction::result_type tmp1 = 0;
+ for(int i = 1; i <= n-1; ++i)
+ tmp1 += f(a+(b-a)/n*i);
+ typename UnaryFunction::result_type tmp2 = 0;
+ for(int i = 1; i <= n ; ++i)
+ tmp2 += f(a+(b-a)/2/n*(2*i-1));
+
+ return (b-a)/6/n * (f(a) + f(b) + 2*tmp1 + 4*tmp2);
+}
+
+// compute b so that f(b) = y; assume f is monotone increasing
+template<class UnaryFunction, class T>
+inline T
+invert_monotone_inc(UnaryFunction f, typename UnaryFunction::result_type y,
+ T lower = -1,
+ T upper = 1)
+{
+ while(upper-lower > 1e-6) {
+ double middle = (upper+lower)/2;
+ if(f(middle) > y)
+ upper = middle;
+ else
+ lower = middle;
+ }
+ return (upper+lower)/2;
+}
+
+// compute b so that I(f(x), a, b) == y
+template<class UnaryFunction>
+inline typename UnaryFunction::argument_type
+quantil(UnaryFunction f, typename UnaryFunction::argument_type a,
+ typename UnaryFunction::result_type y,
+ typename UnaryFunction::argument_type step)
+{
+ typedef typename UnaryFunction::result_type result_type;
+ if(y >= 1.0)
+ return std::numeric_limits<result_type>::infinity();
+ typename UnaryFunction::argument_type b = a;
+ for(result_type result = 0; result < y; b += step)
+ result += step*f(b);
+ return b;
+}
+
+
+#endif /* INTEGRATE_HPP */
diff --git a/libs/random/test/statistic_tests.cpp b/libs/random/test/statistic_tests.cpp
new file mode 100644
index 0000000000..ec85882ce4
--- /dev/null
+++ b/libs/random/test/statistic_tests.cpp
@@ -0,0 +1,503 @@
+/* statistic_tests.cpp file
+ *
+ * Copyright Jens Maurer 2000, 2002
+ * 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: statistic_tests.cpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ * Revision history
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <functional>
+#include <vector>
+#include <set>
+#include <algorithm>
+
+#include <boost/cstdint.hpp>
+#include <boost/random.hpp>
+
+#include <boost/math/special_functions/gamma.hpp>
+
+#include <boost/math/distributions/uniform.hpp>
+#include <boost/math/distributions/chi_squared.hpp>
+#include <boost/math/distributions/normal.hpp>
+#include <boost/math/distributions/triangular.hpp>
+#include <boost/math/distributions/cauchy.hpp>
+#include <boost/math/distributions/gamma.hpp>
+#include <boost/math/distributions/exponential.hpp>
+#include <boost/math/distributions/lognormal.hpp>
+
+#include "statistic_tests.hpp"
+#include "integrate.hpp"
+
+class test_environment;
+
+class test_base
+{
+protected:
+ explicit test_base(test_environment & env) : environment(env) { }
+ void check_(double val) const;
+private:
+ test_environment & environment;
+};
+
+class equidistribution_test : test_base
+{
+public:
+ equidistribution_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(classes-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "equidistribution: " << std::flush;
+ equidistribution_experiment equi(classes);
+ variate_generator<RNG&, uniform_smallint<> > uint_linear(rng, uniform_smallint<>(0, classes-1));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(equi, uint_linear, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(equi, uint_linear, n1), 2*n2));
+
+ std::cout << " 2D: " << std::flush;
+ equidistribution_2d_experiment equi_2d(classes);
+ unsigned int root = static_cast<unsigned int>(std::sqrt(double(classes)));
+ assert(root * root == classes);
+ variate_generator<RNG&, uniform_smallint<> > uint_square(rng, uniform_smallint<>(0, root-1));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(equi_2d, uint_square, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(equi_2d, uint_square, n1), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class ks_distribution_test : test_base
+{
+public:
+ ks_distribution_test(test_environment & env, unsigned int classes)
+ : test_base(env),
+ test_distrib_chi_square(kolmogorov_smirnov_probability(5000),
+ classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ boost::math::uniform ud(static_cast<double>((rng.min)()), static_cast<double>((rng.max)()));
+ run(rng, ud, n1, n2);
+ }
+ template<class RNG, class Dist>
+ void run(RNG & rng, const Dist& dist, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "KS: " << std::flush;
+ kolmogorov_experiment ks(n1);
+ check_(run_experiment(test_distrib_chi_square,
+ ks_experiment_generator(ks, rng, dist), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ ks_experiment_generator(ks, rng, dist), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ distribution_experiment test_distrib_chi_square;
+};
+
+class runs_test : test_base
+{
+public:
+ runs_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(classes-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "runs: up: " << std::flush;
+ runs_experiment<true> r_up(classes);
+
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(r_up, rng, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(r_up, rng, n1), 2*n2));
+
+ std::cout << " down: " << std::flush;
+ runs_experiment<false> r_down(classes);
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(r_down, rng, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(r_down, rng, n1), 2*n2));
+
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class gap_test : test_base
+{
+public:
+ gap_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(classes-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ boost::math::uniform ud(
+ static_cast<double>((rng.min)()),
+ static_cast<double>((rng.max)()) +
+ (std::numeric_limits<typename RNG::result_type>::is_integer? 0.0 : 1.0));
+ run(rng, ud, n1, n2);
+ }
+
+ template<class RNG, class Dist>
+ void run(RNG & rng, const Dist& dist, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "gaps: " << std::flush;
+ gap_experiment gap(classes, dist, 0.2, 0.8);
+
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(gap, rng, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(gap, rng, n1), 2*n2));
+
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class poker_test : test_base
+{
+public:
+ poker_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(classes-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "poker: " << std::flush;
+ poker_experiment poker(8, classes);
+ variate_generator<RNG&, uniform_smallint<> > usmall(rng, uniform_smallint<>(0, 7));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(poker, usmall, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(poker, usmall, n1), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class coupon_collector_test : test_base
+{
+public:
+ coupon_collector_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(classes-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "coupon collector: " << std::flush;
+ coupon_collector_experiment coupon(5, classes);
+
+ variate_generator<RNG&, uniform_smallint<> > usmall(rng, uniform_smallint<>(0, 4));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(coupon, usmall, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(coupon, usmall, n1), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class permutation_test : test_base
+{
+public:
+ permutation_test(test_environment & env, unsigned int classes,
+ unsigned int high_classes)
+ : test_base(env), classes(classes),
+ test_distrib_chi_square(boost::math::chi_squared(fac<int>(classes)-1),
+ high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "permutation: " << std::flush;
+ permutation_experiment perm(classes);
+
+ // generator_reference_t<RNG> gen_ref(rng);
+ RNG& gen_ref(rng);
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(perm, gen_ref, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(perm, gen_ref, n1), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ unsigned int classes;
+ distribution_experiment test_distrib_chi_square;
+};
+
+class maximum_test : test_base
+{
+public:
+ maximum_test(test_environment & env, unsigned int high_classes)
+ : test_base(env),
+ test_distrib_chi_square(kolmogorov_smirnov_probability(1000),
+ high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "maximum-of-t: " << std::flush;
+ maximum_experiment<RNG> mx(rng, n1, 5);
+ check_(run_experiment(test_distrib_chi_square, mx, n2));
+ check_(run_experiment(test_distrib_chi_square, mx, 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ distribution_experiment test_distrib_chi_square;
+};
+
+class birthday_test : test_base
+{
+public:
+ birthday_test(test_environment & env, unsigned int high_classes)
+ : test_base(env),
+ test_distrib_chi_square(boost::math::chi_squared(4-1), high_classes)
+ { }
+
+ template<class RNG>
+ void run(RNG & rng, int n1, int n2)
+ {
+ using namespace boost;
+ std::cout << "birthday spacing: " << std::flush;
+ boost::variate_generator<RNG&, boost::uniform_int<> > uni(rng, boost::uniform_int<>(0, (1<<25)-1));
+ birthday_spacing_experiment bsp(4, 512, (1<<25));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(bsp, uni, n1), n2));
+ check_(run_experiment(test_distrib_chi_square,
+ experiment_generator(bsp, uni, n1), 2*n2));
+ std::cout << std::endl;
+ }
+private:
+ distribution_experiment test_distrib_chi_square;
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4355)
+#endif
+
+class test_environment
+{
+public:
+ static const int classes = 20;
+ explicit test_environment(double confid)
+ : confidence(confid),
+ confidence_chi_square_quantil(quantile(boost::math::chi_squared(classes-1), confidence)),
+ test_distrib_chi_square6(boost::math::chi_squared(7-1), classes),
+ ksdist_test(*this, classes),
+ equi_test(*this, 100, classes),
+ rns_test(*this, 7, classes),
+ gp_test(*this, 7, classes),
+ pk_test(*this, 5, classes),
+ cpn_test(*this, 15, classes),
+ perm_test(*this, 5, classes),
+ max_test(*this, classes),
+ bday_test(*this, classes)
+ {
+ std::cout << "Confidence level: " << confid
+ << "; 1-alpha = " << (1-confid)
+ << "; chi_square(" << (classes-1)
+ << ", " << confidence_chi_square_quantil
+ << ") = "
+ << cdf(boost::math::chi_squared(classes-1), confidence_chi_square_quantil)
+ << std::endl;
+ }
+
+ bool check_confidence(double val, double chi_square_conf) const
+ {
+ std::cout << val;
+ bool result = (val <= chi_square_conf);
+ if(!result) {
+ std::cout << "* [";
+ double prob = (val > 10*chi_square_conf ? 1 :
+ cdf(boost::math::chi_squared(classes-1), val));
+ std::cout << (1-prob) << "]";
+ }
+ std::cout << " " << std::flush;
+ return result;
+ }
+
+ bool check_(double chi_square_value) const
+ {
+ return check_confidence(chi_square_value, confidence_chi_square_quantil);
+ }
+
+ template<class RNG>
+ void run_test(const std::string & name)
+ {
+ using namespace boost;
+
+ std::cout << "Running tests on " << name << std::endl;
+
+ RNG rng(1234567);
+
+ ksdist_test.run(rng, 5000, 250);
+ equi_test.run(rng, 5000, 250);
+ rns_test.run(rng, 100000, 250);
+ gp_test.run(rng, 10000, 250);
+ pk_test.run(rng, 5000, 250);
+ cpn_test.run(rng, 500, 250);
+ perm_test.run(rng, 1200, 250);
+ max_test.run(rng, 1000, 250);
+ bday_test.run(rng, 1000, 150);
+
+ std::cout << std::endl;
+ }
+
+ template<class RNG, class Dist, class ExpectedDist>
+ void run_test(const std::string & name, const Dist & dist, const ExpectedDist & expected_dist)
+ {
+ using namespace boost;
+
+ std::cout << "Running tests on " << name << std::endl;
+
+ RNG rng;
+ variate_generator<RNG&, Dist> vgen(rng, dist);
+
+ ksdist_test.run(vgen, expected_dist, 5000, 250);
+ rns_test.run(vgen, 100000, 250);
+ gp_test.run(vgen, expected_dist, 10000, 250);
+ perm_test.run(vgen, 1200, 250);
+
+ std::cout << std::endl;
+ }
+
+private:
+ double confidence;
+ double confidence_chi_square_quantil;
+ distribution_experiment test_distrib_chi_square6;
+ ks_distribution_test ksdist_test;
+ equidistribution_test equi_test;
+ runs_test rns_test;
+ gap_test gp_test;
+ poker_test pk_test;
+ coupon_collector_test cpn_test;
+ permutation_test perm_test;
+ maximum_test max_test;
+ birthday_test bday_test;
+};
+
+void test_base::check_(double val) const
+{
+ environment.check_(val);
+}
+
+class program_args
+{
+public:
+ program_args(int argc, char** argv)
+ {
+ if(argc > 0) {
+ names.insert(argv + 1, argv + argc);
+ }
+ }
+ bool check_(const std::string & test_name) const
+ {
+ return(names.empty() || names.find(test_name) != names.end());
+ }
+private:
+ std::set<std::string> names;
+};
+
+int main(int argc, char* argv[])
+{
+ program_args args(argc, argv);
+ test_environment env(0.99);
+
+#define TEST(name) \
+ if(args.check_(#name)) \
+ env.run_test<boost::name>(#name)
+
+ TEST(minstd_rand0);
+ TEST(minstd_rand);
+ TEST(rand48);
+ TEST(ecuyer1988);
+ TEST(kreutzer1986);
+ TEST(taus88);
+ TEST(hellekalek1995);
+ TEST(mt11213b);
+ TEST(mt19937);
+ TEST(lagged_fibonacci607);
+ TEST(lagged_fibonacci1279);
+ TEST(lagged_fibonacci2281);
+ TEST(lagged_fibonacci3217);
+ TEST(lagged_fibonacci4423);
+ TEST(lagged_fibonacci9689);
+ TEST(lagged_fibonacci19937);
+ TEST(lagged_fibonacci23209);
+ TEST(lagged_fibonacci44497);
+ TEST(ranlux3);
+ TEST(ranlux4);
+
+#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+ TEST(ranlux64_3);
+ TEST(ranlux64_4);
+#endif
+
+ TEST(ranlux3_01);
+ TEST(ranlux4_01);
+ TEST(ranlux64_3_01);
+ TEST(ranlux64_4_01);
+
+ if(args.check_("normal"))
+ env.run_test<boost::mt19937>("normal", boost::normal_distribution<>(), boost::math::normal());
+ if(args.check_("triangle"))
+ env.run_test<boost::mt19937>("triangle", boost::triangle_distribution<>(0, 1, 3), boost::math::triangular(0, 1, 3));
+ if(args.check_("cauchy"))
+ env.run_test<boost::mt19937>("cauchy", boost::cauchy_distribution<>(), boost::math::cauchy());
+ if(args.check_("gamma"))
+ env.run_test<boost::mt19937>("gamma", boost::gamma_distribution<>(1), boost::math::gamma_distribution<>(1));
+ if(args.check_("exponential"))
+ env.run_test<boost::mt19937>("exponential", boost::exponential_distribution<>(), boost::math::exponential());
+ if(args.check_("lognormal"))
+ env.run_test<boost::mt19937>("lognormal", boost::lognormal_distribution<>(1, 1),
+ boost::math::lognormal(std::log(1.0/std::sqrt(2.0)), std::sqrt(std::log(2.0))));
+}
diff --git a/libs/random/test/statistic_tests.hpp b/libs/random/test/statistic_tests.hpp
new file mode 100644
index 0000000000..3198f76a33
--- /dev/null
+++ b/libs/random/test/statistic_tests.hpp
@@ -0,0 +1,709 @@
+/* statistic_tests.hpp header file
+ *
+ * Copyright Jens Maurer 2000
+ * 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: statistic_tests.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#ifndef STATISTIC_TESTS_HPP
+#define STATISTIC_TESTS_HPP
+
+#include <stdexcept>
+#include <iterator>
+#include <vector>
+#include <boost/limits.hpp>
+#include <algorithm>
+#include <cmath>
+
+#include <boost/config.hpp>
+#include <boost/bind.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/variate_generator.hpp>
+
+#include "integrate.hpp"
+
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
+namespace std
+{
+ inline double pow(double a, double b) { return ::pow(a,b); }
+ inline double ceil(double x) { return ::ceil(x); }
+} // namespace std
+#endif
+
+
+template<class T>
+inline T fac(int k)
+{
+ T result = 1;
+ for(T i = 2; i <= k; ++i)
+ result *= i;
+ return result;
+}
+
+template<class T>
+T binomial(int n, int k)
+{
+ if(k < n/2)
+ k = n-k;
+ T result = 1;
+ for(int i = k+1; i<= n; ++i)
+ result *= i;
+ return result / fac<T>(n-k);
+}
+
+template<class T>
+T stirling2(int n, int m)
+{
+ T sum = 0;
+ for(int k = 0; k <= m; ++k)
+ sum += binomial<T>(m, k) * std::pow(double(k), n) *
+ ( (m-k)%2 == 0 ? 1 : -1);
+ return sum / fac<T>(m);
+}
+
+/*
+ * Experiments which create an empirical distribution in classes,
+ * suitable for the chi-square test.
+ */
+// std::floor(gen() * classes)
+
+class experiment_base
+{
+public:
+ experiment_base(int cls) : _classes(cls) { }
+ unsigned int classes() const { return _classes; }
+protected:
+ unsigned int _classes;
+};
+
+class equidistribution_experiment : public experiment_base
+{
+public:
+ explicit equidistribution_experiment(unsigned int classes)
+ : experiment_base(classes) { }
+
+ template<class NumberGenerator, class Counter>
+ void run(NumberGenerator & f, Counter & count, int n) const
+ {
+ assert((f.min)() == 0 &&
+ static_cast<unsigned int>((f.max)()) == classes()-1);
+ for(int i = 0; i < n; ++i)
+ count(f());
+ }
+ double probability(int /*i*/) const { return 1.0/classes(); }
+};
+
+// two-dimensional equidistribution experiment
+class equidistribution_2d_experiment : public equidistribution_experiment
+{
+public:
+ explicit equidistribution_2d_experiment(unsigned int classes)
+ : equidistribution_experiment(classes) { }
+
+ template<class NumberGenerator, class Counter>
+ void run(NumberGenerator & f, Counter & count, int n) const
+ {
+ unsigned int range = (f.max)()+1;
+ assert((f.min)() == 0 && range*range == classes());
+ for(int i = 0; i < n; ++i) {
+ int y1 = f();
+ int y2 = f();
+ count(y1 + range * y2);
+ }
+ }
+};
+
+// distribution experiment: assume a probability density and
+// count events so that an equidistribution results.
+class distribution_experiment : public equidistribution_experiment
+{
+public:
+ template<class Distribution>
+ distribution_experiment(Distribution dist , unsigned int classes)
+ : equidistribution_experiment(classes), limit(classes)
+ {
+ for(unsigned int i = 0; i < classes-1; ++i)
+ limit[i] = quantile(dist, (i+1)*0.05);
+ limit[classes-1] = std::numeric_limits<double>::infinity();
+ if(limit[classes-1] < (std::numeric_limits<double>::max)())
+ limit[classes-1] = (std::numeric_limits<double>::max)();
+#if 0
+ std::cout << __PRETTY_FUNCTION__ << ": ";
+ for(unsigned int i = 0; i < classes; ++i)
+ std::cout << limit[i] << " ";
+ std::cout << std::endl;
+#endif
+ }
+
+ template<class NumberGenerator, class Counter>
+ void run(NumberGenerator & f, Counter & count, int n) const
+ {
+ for(int i = 0; i < n; ++i) {
+ limits_type::const_iterator it =
+ std::lower_bound(limit.begin(), limit.end(), f());
+ count(it-limit.begin());
+ }
+ }
+private:
+ typedef std::vector<double> limits_type;
+ limits_type limit;
+};
+
+template<bool up, bool is_float>
+struct runs_direction_helper
+{
+ template<class T>
+ static T init(T)
+ {
+ return (std::numeric_limits<T>::max)();
+ }
+};
+
+template<>
+struct runs_direction_helper<true, true>
+{
+ template<class T>
+ static T init(T)
+ {
+ return -(std::numeric_limits<T>::max)();
+ }
+};
+
+template<>
+struct runs_direction_helper<true, false>
+{
+ template<class T>
+ static T init(T)
+ {
+ return (std::numeric_limits<T>::min)();
+ }
+};
+
+// runs-up/runs-down experiment
+template<bool up>
+class runs_experiment : public experiment_base
+{
+public:
+ explicit runs_experiment(unsigned int classes) : experiment_base(classes) { }
+
+ template<class NumberGenerator, class Counter>
+ void run(NumberGenerator & f, Counter & count, int n) const
+ {
+ typedef typename NumberGenerator::result_type result_type;
+ result_type init =
+ runs_direction_helper<
+ up,
+ !std::numeric_limits<result_type>::is_integer
+ >::init(result_type());
+ result_type previous = init;
+ unsigned int length = 0;
+ for(int i = 0; i < n; ++i) {
+ result_type val = f();
+ if(up ? previous <= val : previous >= val) {
+ previous = val;
+ ++length;
+ } else {
+ count((std::min)(length, classes())-1);
+ length = 0;
+ previous = init;
+ // don't use this value, so that runs are independent
+ }
+ }
+ }
+ double probability(unsigned int r) const
+ {
+ if(r == classes()-1)
+ return 1.0/fac<double>(classes());
+ else
+ return static_cast<double>(r+1)/fac<double>(r+2);
+ }
+};
+
+// gap length experiment
+class gap_experiment : public experiment_base
+{
+public:
+ template<class Dist>
+ gap_experiment(unsigned int classes, const Dist & dist, double alpha, double beta)
+ : experiment_base(classes), alpha(alpha), beta(beta), low(quantile(dist, alpha)), high(quantile(dist, beta)) {}
+
+ template<class NumberGenerator, class Counter>
+ void run(NumberGenerator & f, Counter & count, int n) const
+ {
+ typedef typename NumberGenerator::result_type result_type;
+ unsigned int length = 0;
+ for(int i = 0; i < n; ) {
+ result_type value = f();
+ if(value < low || value > high)
+ ++length;
+ else {
+ count((std::min)(length, classes()-1));
+ length = 0;
+ ++i;
+ }
+ }
+ }
+ double probability(unsigned int r) const
+ {
+ double p = beta-alpha;
+ if(r == classes()-1)
+ return std::pow(1-p, static_cast<double>(r));
+ else
+ return p * std::pow(1-p, static_cast<double>(r));
+ }
+private:
+ double alpha, beta;
+ double low, high;
+};
+
+// poker experiment
+class poker_experiment : public experiment_base
+{
+public:
+ poker_experiment(unsigned int d, unsigned int k)
+ : experiment_base(k), range(d)
+ {
+ assert(range > 1);
+ }
+
+ template<class UniformRandomNumberGenerator, class Counter>
+ void run(UniformRandomNumberGenerator & f, Counter & count, int n) const
+ {
+ typedef typename UniformRandomNumberGenerator::result_type result_type;
+ assert(std::numeric_limits<result_type>::is_integer);
+ assert((f.min)() == 0);
+ assert((f.max)() == static_cast<result_type>(range-1));
+ std::vector<result_type> v(classes());
+ for(int i = 0; i < n; ++i) {
+ for(unsigned int j = 0; j < classes(); ++j)
+ v[j] = f();
+ std::sort(v.begin(), v.end());
+ result_type prev = v[0];
+ int r = 1; // count different values in v
+ for(unsigned int i = 1; i < classes(); ++i) {
+ if(prev != v[i]) {
+ prev = v[i];
+ ++r;
+ }
+ }
+ count(r-1);
+ }
+ }
+
+ double probability(unsigned int r) const
+ {
+ ++r; // transform to 1 <= r <= 5
+ double result = range;
+ for(unsigned int i = 1; i < r; ++i)
+ result *= range-i;
+ return result / std::pow(range, static_cast<double>(classes())) *
+ stirling2<double>(classes(), r);
+ }
+private:
+ unsigned int range;
+};
+
+// coupon collector experiment
+class coupon_collector_experiment : public experiment_base
+{
+public:
+ coupon_collector_experiment(unsigned int d, unsigned int cls)
+ : experiment_base(cls), d(d)
+ {
+ assert(d > 1);
+ }
+
+ template<class UniformRandomNumberGenerator, class Counter>
+ void run(UniformRandomNumberGenerator & f, Counter & count, int n) const
+ {
+ typedef typename UniformRandomNumberGenerator::result_type result_type;
+ assert(std::numeric_limits<result_type>::is_integer);
+ assert((f.min)() == 0);
+ assert((f.max)() == static_cast<result_type>(d-1));
+ std::vector<bool> occurs(d);
+ for(int i = 0; i < n; ++i) {
+ occurs.assign(d, false);
+ unsigned int r = 0; // length of current sequence
+ int q = 0; // number of non-duplicates in current set
+ for(;;) {
+ result_type val = f();
+ ++r;
+ if(!occurs[val]) { // new set element
+ occurs[val] = true;
+ ++q;
+ if(q == d)
+ break; // one complete set
+ }
+ }
+ count((std::min)(r-d, classes()-1));
+ }
+ }
+ double probability(unsigned int r) const
+ {
+ if(r == classes()-1)
+ return 1-fac<double>(d)/
+ std::pow(static_cast<double>(d), static_cast<double>(d+classes()-2)) *
+ stirling2<double>(d+classes()-2, d);
+ else
+ return fac<double>(d)/
+ std::pow(static_cast<double>(d), static_cast<double>(d+r)) *
+ stirling2<double>(d+r-1, d-1);
+ }
+private:
+ int d;
+};
+
+// permutation test
+class permutation_experiment : public equidistribution_experiment
+{
+public:
+ permutation_experiment(unsigned int t)
+ : equidistribution_experiment(fac<int>(t)), t(t)
+ {
+ assert(t > 1);
+ }
+
+ template<class UniformRandomNumberGenerator, class Counter>
+ void run(UniformRandomNumberGenerator & f, Counter & count, int n) const
+ {
+ typedef typename UniformRandomNumberGenerator::result_type result_type;
+ std::vector<result_type> v(t);
+ for(int i = 0; i < n; ++i) {
+ for(int j = 0; j < t; ++j) {
+ v[j] = f();
+ }
+ int x = 0;
+ for(int r = t-1; r > 0; r--) {
+ typename std::vector<result_type>::iterator it =
+ std::max_element(v.begin(), v.begin()+r+1);
+ x = (r+1)*x + (it-v.begin());
+ std::iter_swap(it, v.begin()+r);
+ }
+ count(x);
+ }
+ }
+private:
+ int t;
+};
+
+// birthday spacing experiment test
+class birthday_spacing_experiment : public experiment_base
+{
+public:
+ birthday_spacing_experiment(unsigned int d, int n, int m)
+ : experiment_base(d), n(n), m(m)
+ {
+ }
+
+ template<class UniformRandomNumberGenerator, class Counter>
+ void run(UniformRandomNumberGenerator & f, Counter & count, int n_total) const
+ {
+ typedef typename UniformRandomNumberGenerator::result_type result_type;
+ assert(std::numeric_limits<result_type>::is_integer);
+ assert((f.min)() == 0);
+ assert((f.max)() == static_cast<result_type>(m-1));
+
+ for(int j = 0; j < n_total; j++) {
+ std::vector<result_type> v(n);
+ std::generate_n(v.begin(), n, f);
+ std::sort(v.begin(), v.end());
+ std::vector<result_type> spacing(n);
+ for(int i = 0; i < n-1; i++)
+ spacing[i] = v[i+1]-v[i];
+ spacing[n-1] = v[0] + m - v[n-1];
+ std::sort(spacing.begin(), spacing.end());
+ unsigned int k = 0;
+ for(int i = 0; i < n-1; ++i) {
+ if(spacing[i] == spacing[i+1])
+ ++k;
+ }
+ count((std::min)(k, classes()-1));
+ }
+ }
+
+ double probability(unsigned int r) const
+ {
+ assert(classes() == 4);
+ assert(m == (1<<25));
+ assert(n == 512);
+ static const double prob[] = { 0.368801577, 0.369035243, 0.183471182,
+ 0.078691997 };
+ return prob[r];
+ }
+private:
+ int n, m;
+};
+/*
+ * Misc. helper functions.
+ */
+
+template<class Float>
+struct distribution_function
+{
+ typedef Float result_type;
+ typedef Float argument_type;
+ typedef Float first_argument_type;
+ typedef Float second_argument_type;
+};
+
+// computes P(K_n <= t) or P(t1 <= K_n <= t2). See Knuth, 3.3.1
+class kolmogorov_smirnov_probability : public distribution_function<double>
+{
+public:
+ kolmogorov_smirnov_probability(int n)
+ : approx(n > 50), n(n), sqrt_n(std::sqrt(double(n)))
+ {
+ if(!approx)
+ n_n = std::pow(static_cast<double>(n), n);
+ }
+
+ double cdf(double t) const
+ {
+ if(approx) {
+ return 1-std::exp(-2*t*t)*(1-2.0/3.0*t/sqrt_n);
+ } else {
+ t *= sqrt_n;
+ double sum = 0;
+ for(int k = static_cast<int>(std::ceil(t)); k <= n; k++)
+ sum += binomial<double>(n, k) * std::pow(k-t, k) *
+ std::pow(t+n-k, n-k-1);
+ return 1 - t/n_n * sum;
+ }
+ }
+ //double operator()(double t1, double t2) const
+ //{ return operator()(t2) - operator()(t1); }
+
+private:
+ bool approx;
+ int n;
+ double sqrt_n;
+ double n_n;
+};
+
+inline double cdf(const kolmogorov_smirnov_probability& dist, double val)
+{
+ return dist.cdf(val);
+}
+
+inline double quantile(const kolmogorov_smirnov_probability& dist, double val)
+{
+ return invert_monotone_inc(boost::bind(&cdf, dist, _1), val, 0.0, 1000.0);
+}
+
+/*
+ * Experiments for generators with continuous distribution functions
+ */
+class kolmogorov_experiment
+{
+public:
+ kolmogorov_experiment(int n) : n(n), ksp(n) { }
+ template<class NumberGenerator, class Distribution>
+ double run(NumberGenerator & gen, Distribution distrib) const
+ {
+ const int m = n;
+ typedef std::vector<double> saved_temp;
+ saved_temp a(m,1.0), b(m,0);
+ std::vector<int> c(m,0);
+ for(int i = 0; i < n; ++i) {
+ double val = static_cast<double>(gen());
+ double y = cdf(distrib, val);
+ int k = static_cast<int>(std::floor(m*y));
+ if(k >= m)
+ --k; // should not happen
+ a[k] = (std::min)(a[k], y);
+ b[k] = (std::max)(b[k], y);
+ ++c[k];
+ }
+ double kplus = 0, kminus = 0;
+ int j = 0;
+ for(int k = 0; k < m; ++k) {
+ if(c[k] > 0) {
+ kminus = (std::max)(kminus, a[k]-j/static_cast<double>(n));
+ j += c[k];
+ kplus = (std::max)(kplus, j/static_cast<double>(n) - b[k]);
+ }
+ }
+ kplus *= std::sqrt(double(n));
+ kminus *= std::sqrt(double(n));
+ // std::cout << "k+ " << kplus << " k- " << kminus << std::endl;
+ return kplus;
+ }
+ double probability(double x) const
+ {
+ return cdf(ksp, x);
+ }
+private:
+ int n;
+ kolmogorov_smirnov_probability ksp;
+};
+
+struct power_distribution
+{
+ power_distribution(double t) : t(t) {}
+ double t;
+};
+
+double cdf(const power_distribution& dist, double val)
+{
+ return std::pow(val, dist.t);
+}
+
+// maximum-of-t test (KS-based)
+template<class UniformRandomNumberGenerator>
+class maximum_experiment
+{
+public:
+ typedef UniformRandomNumberGenerator base_type;
+ maximum_experiment(base_type & f, int n, int t) : f(f), ke(n), t(t)
+ { }
+
+ double operator()() const
+ {
+ generator gen(f, t);
+ return ke.run(gen, power_distribution(t));
+ }
+
+private:
+ struct generator {
+ generator(base_type & f, int t) : f(f, boost::uniform_01<>()), t(t) { }
+ double operator()()
+ {
+ double mx = f();
+ for(int i = 1; i < t; ++i)
+ mx = (std::max)(mx, f());
+ return mx;
+ }
+ private:
+ boost::variate_generator<base_type&, boost::uniform_01<> > f;
+ int t;
+ };
+ base_type & f;
+ kolmogorov_experiment ke;
+ int t;
+};
+
+// compute a chi-square value for the distribution approximation error
+template<class ForwardIterator, class UnaryFunction>
+typename UnaryFunction::result_type
+chi_square_value(ForwardIterator first, ForwardIterator last,
+ UnaryFunction probability)
+{
+ typedef std::iterator_traits<ForwardIterator> iter_traits;
+ typedef typename iter_traits::value_type counter_type;
+ typedef typename UnaryFunction::result_type result_type;
+ unsigned int classes = std::distance(first, last);
+ result_type sum = 0;
+ counter_type n = 0;
+ for(unsigned int i = 0; i < classes; ++first, ++i) {
+ counter_type count = *first;
+ n += count;
+ sum += (count/probability(i)) * count; // avoid overflow
+ }
+#if 0
+ for(unsigned int i = 0; i < classes; ++i) {
+ // std::cout << (n*probability(i)) << " ";
+ if(n * probability(i) < 5)
+ std::cerr << "Not enough test runs for slot " << i
+ << " p=" << probability(i) << ", n=" << n
+ << std::endl;
+ }
+#endif
+ // std::cout << std::endl;
+ // throw std::invalid_argument("not enough test runs");
+
+ return sum/n - n;
+}
+template<class RandomAccessContainer>
+class generic_counter
+{
+public:
+ explicit generic_counter(unsigned int classes) : container(classes, 0) { }
+ void operator()(int i)
+ {
+ assert(i >= 0);
+ assert(static_cast<unsigned int>(i) < container.size());
+ ++container[i];
+ }
+ typename RandomAccessContainer::const_iterator begin() const
+ { return container.begin(); }
+ typename RandomAccessContainer::const_iterator end() const
+ { return container.end(); }
+
+private:
+ RandomAccessContainer container;
+};
+
+// chi_square test
+template<class Experiment, class Generator>
+double run_experiment(const Experiment & experiment, Generator & gen, int n)
+{
+ generic_counter<std::vector<int> > v(experiment.classes());
+ experiment.run(gen, v, n);
+ return chi_square_value(v.begin(), v.end(),
+ std::bind1st(std::mem_fun_ref(&Experiment::probability),
+ experiment));
+}
+
+// chi_square test
+template<class Experiment, class Generator>
+double run_experiment(const Experiment & experiment, const Generator & gen, int n)
+{
+ generic_counter<std::vector<int> > v(experiment.classes());
+ experiment.run(gen, v, n);
+ return chi_square_value(v.begin(), v.end(),
+ std::bind1st(std::mem_fun_ref(&Experiment::probability),
+ experiment));
+}
+
+// number generator with experiment results (for nesting)
+template<class Experiment, class Generator>
+class experiment_generator_t
+{
+public:
+ experiment_generator_t(const Experiment & exper, Generator & gen, int n)
+ : experiment(exper), generator(gen), n(n) { }
+ double operator()() const { return run_experiment(experiment, generator, n); }
+private:
+ const Experiment & experiment;
+ Generator & generator;
+ int n;
+};
+
+template<class Experiment, class Generator>
+experiment_generator_t<Experiment, Generator>
+experiment_generator(const Experiment & e, Generator & gen, int n)
+{
+ return experiment_generator_t<Experiment, Generator>(e, gen, n);
+}
+
+
+template<class Experiment, class Generator, class Distribution>
+class ks_experiment_generator_t
+{
+public:
+ ks_experiment_generator_t(const Experiment & exper, Generator & gen,
+ const Distribution & distrib)
+ : experiment(exper), generator(gen), distribution(distrib) { }
+ double operator()() const { return experiment.run(generator, distribution); }
+private:
+ const Experiment & experiment;
+ Generator & generator;
+ Distribution distribution;
+};
+
+template<class Experiment, class Generator, class Distribution>
+ks_experiment_generator_t<Experiment, Generator, Distribution>
+ks_experiment_generator(const Experiment & e, Generator & gen,
+ const Distribution & distrib)
+{
+ return ks_experiment_generator_t<Experiment, Generator, Distribution>
+ (e, gen, distrib);
+}
+
+
+#endif /* STATISTIC_TESTS_HPP */
+
diff --git a/libs/random/test/test_bernoulli.cpp b/libs/random/test/test_bernoulli.cpp
new file mode 100644
index 0000000000..c72a9c4bca
--- /dev/null
+++ b/libs/random/test/test_bernoulli.cpp
@@ -0,0 +1,108 @@
+/* test_bernoulli.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: test_bernoulli.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/math/distributions/binomial.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <vector>
+#include <iostream>
+#include <numeric>
+
+#include "chi_squared_test.hpp"
+
+bool do_test(double p, long long max) {
+ std::cout << "running bernoulli(" << p << ")" << " " << max << " times: " << std::flush;
+
+ boost::math::binomial expected(static_cast<double>(max), p);
+
+ boost::random::bernoulli_distribution<> dist(p);
+ boost::mt19937 gen;
+ long long count = 0;
+ for(long long i = 0; i < max; ++i) {
+ if(dist(gen)) ++count;
+ }
+
+ double prob = cdf(expected, count);
+
+ bool result = prob < 0.99 && prob > 0.01;
+ 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, long long trials) {
+ boost::mt19937 gen;
+ boost::uniform_01<> rdist;
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(rdist(gen), trials)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_bernoulli_distribution -r <repeat> -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;
+ long long trials = 1000000ll;
+
+ 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, 't', trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat, trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/libs/random/test/test_bernoulli_distribution.cpp b/libs/random/test/test_bernoulli_distribution.cpp
new file mode 100644
index 0000000000..945e3f191b
--- /dev/null
+++ b/libs/random/test/test_bernoulli_distribution.cpp
@@ -0,0 +1,32 @@
+/* test_bernoulli_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: test_bernoulli_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/bernoulli_distribution.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::bernoulli_distribution<>
+#define BOOST_RANDOM_ARG1 p
+#define BOOST_RANDOM_ARG1_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_VALUE 0.25
+
+#define BOOST_RANDOM_DIST0_MIN false
+#define BOOST_RANDOM_DIST0_MAX true
+#define BOOST_RANDOM_DIST1_MIN false
+#define BOOST_RANDOM_DIST1_MAX true
+
+#define BOOST_RANDOM_TEST1_PARAMS (0.0)
+#define BOOST_RANDOM_TEST1_MIN false
+#define BOOST_RANDOM_TEST1_MAX false
+
+#define BOOST_RANDOM_TEST2_PARAMS (1.0)
+#define BOOST_RANDOM_TEST2_MIN true
+#define BOOST_RANDOM_TEST2_MAX true
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_binomial.cpp b/libs/random/test/test_binomial.cpp
new file mode 100644
index 0000000000..44553afb7f
--- /dev/null
+++ b/libs/random/test/test_binomial.cpp
@@ -0,0 +1,30 @@
+/* test_binomial.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: test_binomial.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/math/distributions/binomial.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::binomial_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME binomial
+#define BOOST_MATH_DISTRIBUTION boost::math::binomial
+#define BOOST_RANDOM_ARG1_TYPE int
+#define BOOST_RANDOM_ARG1_NAME n
+#define BOOST_RANDOM_ARG1_DEFAULT 100000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_int<>(0, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME p
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_01<>()
+#define BOOST_RANDOM_DISTRIBUTION_MAX n
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_binomial_distribution.cpp b/libs/random/test/test_binomial_distribution.cpp
new file mode 100644
index 0000000000..18fe0c6dae
--- /dev/null
+++ b/libs/random/test/test_binomial_distribution.cpp
@@ -0,0 +1,37 @@
+/* test_binomial_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: test_binomial_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/binomial_distribution.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::binomial_distribution<>
+#define BOOST_RANDOM_ARG1 t
+#define BOOST_RANDOM_ARG2 p
+#define BOOST_RANDOM_ARG1_DEFAULT 1
+#define BOOST_RANDOM_ARG2_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_VALUE 10
+#define BOOST_RANDOM_ARG2_VALUE 0.25
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX 1
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX 10
+#define BOOST_RANDOM_DIST2_MIN 0
+#define BOOST_RANDOM_DIST2_MAX 10
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 1
+
+#define BOOST_RANDOM_TEST2_PARAMS (10, 0.25)
+#define BOOST_RANDOM_TEST2_MIN 0
+#define BOOST_RANDOM_TEST2_MAX 10
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_cauchy.cpp b/libs/random/test/test_cauchy.cpp
new file mode 100644
index 0000000000..0320a997b6
--- /dev/null
+++ b/libs/random/test/test_cauchy.cpp
@@ -0,0 +1,28 @@
+/* test_cauchy.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: test_cauchy.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/cauchy.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::cauchy_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME cauchy
+#define BOOST_MATH_DISTRIBUTION boost::math::cauchy
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME median
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(-n, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME sigma
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_cauchy_distribution.cpp b/libs/random/test/test_cauchy_distribution.cpp
new file mode 100644
index 0000000000..4856b08865
--- /dev/null
+++ b/libs/random/test/test_cauchy_distribution.cpp
@@ -0,0 +1,35 @@
+/* test_cauchy_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: test_cauchy_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/cauchy_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::cauchy_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#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 -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS (-100000.0, 0.000001)
+#define BOOST_RANDOM_TEST2_PARAMS (100000.0, 0.000001)
+#define BOOST_RANDOM_TEST1_MAX 0.0
+#define BOOST_RANDOM_TEST2_MIN 0.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_chi_squared.cpp b/libs/random/test/test_chi_squared.cpp
new file mode 100644
index 0000000000..67839c348c
--- /dev/null
+++ b/libs/random/test/test_chi_squared.cpp
@@ -0,0 +1,24 @@
+/* test_chi_squared.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: test_chi_squared.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/chi_squared_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/chi_squared.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::chi_squared_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME chi_squared
+#define BOOST_MATH_DISTRIBUTION boost::math::chi_squared
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME n
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_chi_squared_distribution.cpp b/libs/random/test/test_chi_squared_distribution.cpp
new file mode 100644
index 0000000000..5b6ff15cc0
--- /dev/null
+++ b/libs/random/test/test_chi_squared_distribution.cpp
@@ -0,0 +1,34 @@
+/* test_chi_squared_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: test_chi_squared_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/chi_squared_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::chi_squared_distribution<>
+#define BOOST_RANDOM_ARG1 n
+#define BOOST_RANDOM_ARG1_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE 7.5
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN 0
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0.0
+#define BOOST_RANDOM_TEST1_MAX 100.0
+
+#define BOOST_RANDOM_TEST2_PARAMS (10000.0)
+#define BOOST_RANDOM_TEST2_MIN 100.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_const_mod.cpp b/libs/random/test/test_const_mod.cpp
new file mode 100644
index 0000000000..b3b43575fa
--- /dev/null
+++ b/libs/random/test/test_const_mod.cpp
@@ -0,0 +1,183 @@
+/* test_const_mod.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: test_const_mod.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/detail/const_mod.hpp>
+
+#include <boost/cstdint.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+typedef boost::mpl::vector<
+ boost::int8_t,
+ boost::uint8_t
+> int8_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult8, IntType, int8_types) {
+ for(int i = 0; i < 127; ++i) {
+ for(int j = 0; j < 127; ++j) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult(IntType(i), IntType(j))), i * j % 127);
+ }
+ }
+ int modulus = (std::numeric_limits<IntType>::max)() + 1;
+ for(int i = 0; i < modulus; ++i) {
+ for(int j = 0; j < modulus; ++j) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult(IntType(i), IntType(j))), i * j % modulus);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_add8, IntType, int8_types) {
+ for(int i = 0; i < 127; ++i) {
+ for(int j = 0; j < 127; ++j) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::add(IntType(i), IntType(j))), (i + j) % 127);
+ }
+ }
+ {
+ const int modulus = boost::integer_traits<IntType>::const_max;
+ for(int i = 0; i < modulus; ++i) {
+ for(int j = 0; j < modulus; ++j) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, modulus>::add(IntType(i), IntType(j))), (i + j) % modulus);
+ }
+ }
+ }
+ {
+ int modulus = (std::numeric_limits<IntType>::max)() + 1;
+ for(int i = 0; i < modulus; ++i) {
+ for(int j = 0; j < modulus; ++j) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::add(IntType(i), IntType(j))), (i + j) % modulus);
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add8, IntType, int8_types) {
+ for(int i = 0; i < 127; i += 5) {
+ for(int j = 0; j < 127; j += 3) {
+ for(int k = 0; k < 127; k += 3) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult_add(IntType(i), IntType(j), IntType(k))), (i * j + k) % 127);
+ }
+ }
+ }
+ {
+ int modulus = (std::numeric_limits<IntType>::max)() + 1;
+ for(int i = 0; i < modulus; i += 5) {
+ for(int j = 0; j < modulus; j += 3) {
+ for(int k = 0; k < modulus; k += 3) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult_add(IntType(i), IntType(j), IntType(k))), (i * j + k) % modulus);
+ }
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert8, IntType, int8_types) {
+ for(int i = 1; i < 127; ++i) {
+ IntType inverse = boost::random::const_mod<IntType, 127>::invert(IntType(i));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult(IntType(i), inverse)), 1);
+ }
+ int modulus = (std::numeric_limits<IntType>::max)() + 1;
+ for(int i = 1; i < modulus; i += 2) {
+ IntType inverse = boost::random::const_mod<IntType, 0>::invert(IntType(i));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult(IntType(i), inverse)), 1);
+ }
+}
+
+typedef boost::mpl::vector<
+ boost::int32_t,
+ boost::uint32_t
+> int32_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult32, IntType, int32_types) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 2147483562)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 2147483562)), IntType(1));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, 1234657890)), IntType(813106682));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_add32, IntType, int32_types) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(0, 2147483562)), IntType(2147483562));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 0)), IntType(2147483562));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 2147483562)), IntType(2147483561));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(1234567890, 1234657890)), IntType(321742217));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add32, IntType, int32_types) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 2147483562, 827364)), IntType(827364));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 0, 827364)), IntType(827364));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 2147483562, 2147483562)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(1234567890, 1234657890, 1726384759)), IntType(392007878));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert32, IntType, int32_types) {
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::invert(0)), IntType(0));
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 0, 0)), IntType(0));
+ IntType inverse;
+ inverse = boost::random::const_mod<IntType, 2147483563>::invert(2147483562);
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, inverse)), IntType(1));
+ inverse = boost::random::const_mod<IntType, 2147483563>::invert(1234567890);
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, inverse)), IntType(1));
+}
+
+#if !defined(BOOST_NO_INT64_T)
+
+typedef boost::mpl::vector<
+ boost::int64_t,
+ boost::uint64_t
+> int64_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult64, IntType, int64_types) {
+ typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
+ BOOST_CHECK_EQUAL((const_mod_type::mult(0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(0, 2147483562)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(2147483562, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(2147483562, 2147483562)), IntType(INT64_C(316718521754730848)));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(1234567890, 1234657890)), IntType(INT64_C(1524268986129152100)));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(1234567890726352938), INT64_C(1234657890736453927))), IntType(INT64_C(88656187017794672)));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_add64, IntType, int64_types) {
+ typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
+ BOOST_CHECK_EQUAL((const_mod_type::add(0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::add(0, 2147483562)), IntType(2147483562));
+ BOOST_CHECK_EQUAL((const_mod_type::add(2147483562, 0)), IntType(2147483562));
+ BOOST_CHECK_EQUAL((const_mod_type::add(2147483562, 2147483562)), IntType(4294967124U));
+ BOOST_CHECK_EQUAL((const_mod_type::add(1234567890, 1234657890)), IntType(2469225780U));
+ BOOST_CHECK_EQUAL((const_mod_type::add(INT64_C(1234567890726352938), INT64_C(1234657890736453927))), IntType(INT64_C(321742217810068367)));
+ BOOST_CHECK_EQUAL((const_mod_type::add(INT64_C(2147483563652738490), 8)), IntType(0));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add64, IntType, int64_types) {
+ typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 0, 0)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 2147483562, 827364)), IntType(827364));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(2147483562, 0, 827364)), IntType(827364));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(2147483562, 2147483562, 2147483562)), IntType(INT64_C(316718523902214410)));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(1234567890, 1234657890, 1726384759)), IntType(INT64_C(1524268987855536859)));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(INT64_C(1234567890726352938), INT64_C(1234657890736453927), INT64_C(1726384759726488649))), IntType(INT64_C(1815040946744283321)));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert64, IntType, int64_types) {
+ typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
+ BOOST_CHECK_EQUAL((const_mod_type::invert(0)), IntType(0));
+ BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 0, 0)), IntType(0));
+ IntType inverse;
+ inverse = const_mod_type::invert(INT64_C(7362947769));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(7362947769), inverse)), IntType(1));
+ inverse = const_mod_type::invert(INT64_C(1263142436887493875));
+ BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(1263142436887493875), inverse)), IntType(1));
+}
+
+#endif
diff --git a/libs/random/test/test_discrete.cpp b/libs/random/test/test_discrete.cpp
new file mode 100644
index 0000000000..f4f5395f33
--- /dev/null
+++ b/libs/random/test/test_discrete.cpp
@@ -0,0 +1,123 @@
+/* test_poisson.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: test_discrete.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/discrete_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <vector>
+#include <iostream>
+#include <numeric>
+
+#include "chi_squared_test.hpp"
+
+bool do_test(int n, long long max) {
+ std::cout << "running discrete(p0, p1, ..., p" << n-1 << ")" << " " << max << " times: " << std::flush;
+
+ std::vector<double> expected;
+ {
+ boost::mt19937 egen;
+ for(int i = 0; i < n; ++i) {
+ expected.push_back(egen());
+ }
+ double sum = std::accumulate(expected.begin(), expected.end(), 0.0);
+ for(std::vector<double>::iterator iter = expected.begin(), end = expected.end(); iter != end; ++iter) {
+ *iter /= sum;
+ }
+ }
+
+ boost::random::discrete_distribution<> dist(expected);
+ boost::mt19937 gen;
+ std::vector<long long> results(expected.size());
+ for(long long i = 0; i < max; ++i) {
+ ++results[dist(gen)];
+ }
+
+ long long sum = std::accumulate(results.begin(), results.end(), 0ll);
+ if(sum != max) {
+ std::cout << "*** Failed: incorrect total: " << sum << " ***" << std::endl;
+ return false;
+ }
+ double chsqr = chi_squared_test(results, expected, max);
+
+ bool result = chsqr < 0.99;
+ const char* err = result? "" : "*";
+ std::cout << std::setprecision(17) << chsqr << err << std::endl;
+
+ std::cout << std::setprecision(6);
+
+ return result;
+}
+
+bool do_tests(int repeat, int max_n, long long trials) {
+ boost::mt19937 gen;
+ boost::uniform_int<> idist(1, max_n);
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(idist(gen), trials)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_discrete -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;
+ int max_n = 100000;
+ long long trials = 1000000ll;
+
+ 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, 'n', max_n)
+ && !handle_option(argc, argv, 't', trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat, max_n, trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/libs/random/test/test_discrete_distribution.cpp b/libs/random/test/test_discrete_distribution.cpp
new file mode 100644
index 0000000000..f505057ccc
--- /dev/null
+++ b/libs/random/test/test_discrete_distribution.cpp
@@ -0,0 +1,168 @@
+/* test_discrete_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: test_discrete_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/discrete_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/assign/list_of.hpp>
+#include <sstream>
+#include <vector>
+#include "concepts.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberDistribution;
+using boost::random::discrete_distribution;
+BOOST_CONCEPT_ASSERT((RandomNumberDistribution< discrete_distribution<> >));
+
+struct gen {
+ double operator()(double arg) {
+ if(arg < 100) return 100;
+ else if(arg < 103) return 1;
+ else if(arg < 107) return 2;
+ else if(arg < 111) return 1;
+ else if(arg < 114) return 4;
+ else return 100;
+ }
+};
+
+#define CHECK_PROBABILITIES(actual, expected) \
+ do { \
+ std::vector<double> _actual = (actual); \
+ std::vector<double> _expected = (expected); \
+ BOOST_CHECK_EQUAL_COLLECTIONS( \
+ _actual.begin(), _actual.end(), \
+ _expected.begin(), _expected.end()); \
+ } while(false)
+
+using boost::assign::list_of;
+
+BOOST_AUTO_TEST_CASE(test_constructors) {
+ boost::random::discrete_distribution<> dist;
+ CHECK_PROBABILITIES(dist.probabilities(), list_of(1.0));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::discrete_distribution<> dist_il = { 1, 2, 1, 4 };
+ CHECK_PROBABILITIES(dist_il.probabilities(), list_of(.125)(.25)(.125)(.5));
+#endif
+ std::vector<double> probs = boost::assign::list_of(1.0)(2.0)(1.0)(4.0);
+
+ boost::random::discrete_distribution<> dist_r(probs);
+ CHECK_PROBABILITIES(dist_r.probabilities(), list_of(.125)(.25)(.125)(.5));
+
+ boost::random::discrete_distribution<> dist_it(probs.begin(), probs.end());
+ CHECK_PROBABILITIES(dist_it.probabilities(), list_of(.125)(.25)(.125)(.5));
+
+ boost::random::discrete_distribution<> dist_fun(4, 99, 115, gen());
+ CHECK_PROBABILITIES(dist_fun.probabilities(), list_of(.125)(.25)(.125)(.5));
+
+ boost::random::discrete_distribution<> copy(dist);
+ BOOST_CHECK_EQUAL(dist, copy);
+ boost::random::discrete_distribution<> copy_r(dist_r);
+ BOOST_CHECK_EQUAL(dist_r, copy_r);
+
+ boost::random::discrete_distribution<> notpow2(3, 99, 111, gen());
+ BOOST_REQUIRE_EQUAL(notpow2.probabilities().size(), 3u);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.probabilities()[0], 0.25, 0.00000000001);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.probabilities()[1], 0.50, 0.00000000001);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.probabilities()[2], 0.25, 0.00000000001);
+ boost::random::discrete_distribution<> copy_notpow2(notpow2);
+ BOOST_CHECK_EQUAL(notpow2, copy_notpow2);
+}
+
+BOOST_AUTO_TEST_CASE(test_param) {
+ std::vector<double> probs = boost::assign::list_of(1.0)(2.0)(1.0)(4.0);
+ boost::random::discrete_distribution<> dist(probs);
+ boost::random::discrete_distribution<>::param_type param = dist.param();
+ CHECK_PROBABILITIES(param.probabilities(), list_of(.125)(.25)(.125)(.5));
+ boost::random::discrete_distribution<> copy1(param);
+ BOOST_CHECK_EQUAL(dist, copy1);
+ boost::random::discrete_distribution<> copy2;
+ copy2.param(param);
+ BOOST_CHECK_EQUAL(dist, copy2);
+
+ boost::random::discrete_distribution<>::param_type param_copy = param;
+ BOOST_CHECK_EQUAL(param, param_copy);
+ BOOST_CHECK(param == param_copy);
+ BOOST_CHECK(!(param != param_copy));
+ boost::random::discrete_distribution<>::param_type param_default;
+ CHECK_PROBABILITIES(param_default.probabilities(), list_of(1.0));
+ BOOST_CHECK(param != param_default);
+ BOOST_CHECK(!(param == param_default));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::discrete_distribution<>::param_type
+ parm_il = { 1, 2, 1, 4 };
+ CHECK_PROBABILITIES(parm_il.probabilities(), list_of(.125)(.25)(.125)(.5));
+#endif
+
+ boost::random::discrete_distribution<>::param_type parm_r(probs);
+ CHECK_PROBABILITIES(parm_r.probabilities(), list_of(.125)(.25)(.125)(.5));
+
+ boost::random::discrete_distribution<>::param_type
+ parm_it(probs.begin(), probs.end());
+ CHECK_PROBABILITIES(parm_it.probabilities(), list_of(.125)(.25)(.125)(.5));
+
+ boost::random::discrete_distribution<>::param_type
+ parm_fun(4, 99, 115, gen());
+ CHECK_PROBABILITIES(parm_fun.probabilities(), list_of(.125)(.25)(.125)(.5));
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max) {
+ std::vector<double> probs = boost::assign::list_of(1.0)(2.0)(1.0);
+ boost::random::discrete_distribution<> dist;
+ BOOST_CHECK_EQUAL((dist.min)(), 0);
+ BOOST_CHECK_EQUAL((dist.max)(), 0);
+ boost::random::discrete_distribution<> dist_r(probs);
+ BOOST_CHECK_EQUAL((dist_r.min)(), 0);
+ BOOST_CHECK_EQUAL((dist_r.max)(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison) {
+ std::vector<double> probs = boost::assign::list_of(1.0)(2.0)(1.0)(4.0);
+ boost::random::discrete_distribution<> dist;
+ boost::random::discrete_distribution<> dist_copy(dist);
+ boost::random::discrete_distribution<> dist_r(probs);
+ boost::random::discrete_distribution<> dist_r_copy(dist_r);
+ BOOST_CHECK(dist == dist_copy);
+ BOOST_CHECK(!(dist != dist_copy));
+ BOOST_CHECK(dist_r == dist_r_copy);
+ BOOST_CHECK(!(dist_r != dist_r_copy));
+ BOOST_CHECK(dist != dist_r);
+ BOOST_CHECK(!(dist == dist_r));
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming) {
+ std::vector<double> probs = boost::assign::list_of(1.0)(2.0)(1.0)(4.0);
+ boost::random::discrete_distribution<> dist(probs);
+ std::stringstream stream;
+ stream << dist;
+ boost::random::discrete_distribution<> restored_dist;
+ stream >> restored_dist;
+ BOOST_CHECK_EQUAL(dist, restored_dist);
+}
+
+BOOST_AUTO_TEST_CASE(test_generation) {
+ std::vector<double> probs = boost::assign::list_of(0.0)(1.0);
+ boost::minstd_rand0 gen;
+ boost::random::discrete_distribution<> dist;
+ boost::random::discrete_distribution<> dist_r(probs);
+ for(int i = 0; i < 10; ++i) {
+ int value = dist(gen);
+ BOOST_CHECK_EQUAL(value, 0);
+ int value_r = dist_r(gen);
+ BOOST_CHECK_EQUAL(value_r, 1);
+ int value_param = dist_r(gen, dist.param());
+ BOOST_CHECK_EQUAL(value_param, 0);
+ int value_r_param = dist(gen, dist_r.param());
+ BOOST_CHECK_EQUAL(value_r_param, 1);
+ }
+}
diff --git a/libs/random/test/test_distribution.ipp b/libs/random/test/test_distribution.ipp
new file mode 100644
index 0000000000..a98f3bdcde
--- /dev/null
+++ b/libs/random/test/test_distribution.ipp
@@ -0,0 +1,290 @@
+/* test_distribution.ipp
+ *
+ * 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: test_distribution.ipp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <sstream>
+#include "concepts.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberDistribution;
+BOOST_CONCEPT_ASSERT((RandomNumberDistribution< BOOST_RANDOM_DISTRIBUTION >));
+
+BOOST_AUTO_TEST_CASE(test_constructors) {
+ BOOST_RANDOM_DISTRIBUTION dist;
+ BOOST_CHECK_EQUAL(dist.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_DEFAULT);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK_EQUAL(dist.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(dist.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+ BOOST_RANDOM_DISTRIBUTION dist_one(BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(dist_one.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK_EQUAL(dist_one.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(dist_one.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_RANDOM_DISTRIBUTION dist_two(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+ BOOST_CHECK_EQUAL(dist_two.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(dist_two.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_VALUE);
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(dist_two.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_RANDOM_DISTRIBUTION dist_three(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG3_VALUE);
+ BOOST_CHECK_EQUAL(dist_three.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(dist_three.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_VALUE);
+ BOOST_CHECK_EQUAL(dist_three.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_VALUE);
+#endif
+ BOOST_RANDOM_DISTRIBUTION copy(dist);
+ BOOST_CHECK_EQUAL(dist, copy);
+ BOOST_RANDOM_DISTRIBUTION copy_one(dist_one);
+ BOOST_CHECK_EQUAL(dist_one, copy_one);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_RANDOM_DISTRIBUTION copy_two(dist_two);
+ BOOST_CHECK_EQUAL(dist_two, copy_two);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_RANDOM_DISTRIBUTION copy_three(dist_three);
+ BOOST_CHECK_EQUAL(dist_three, copy_three);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_param) {
+#if defined(BOOST_RANDOM_ARG3)
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG3_VALUE);
+#elif defined(BOOST_RANDOM_ARG2)
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+#else
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE);
+#endif
+ BOOST_RANDOM_DISTRIBUTION::param_type param = dist.param();
+ BOOST_CHECK_EQUAL(param.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK_EQUAL(param.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_VALUE);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(param.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_VALUE);
+#endif
+ BOOST_RANDOM_DISTRIBUTION copy1(param);
+ BOOST_CHECK_EQUAL(dist, copy1);
+ BOOST_RANDOM_DISTRIBUTION copy2;
+ copy2.param(param);
+ BOOST_CHECK_EQUAL(dist, copy2);
+
+ BOOST_RANDOM_DISTRIBUTION::param_type param_copy = param;
+ BOOST_CHECK_EQUAL(param, param_copy);
+ BOOST_CHECK(param == param_copy);
+ BOOST_CHECK(!(param != param_copy));
+ BOOST_RANDOM_DISTRIBUTION::param_type param_default;
+ BOOST_CHECK_EQUAL(param_default.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_DEFAULT);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK_EQUAL(param_default.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(param_default.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+ BOOST_CHECK(param != param_default);
+ BOOST_CHECK(!(param == param_default));
+ BOOST_RANDOM_DISTRIBUTION::param_type param_one(BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(param_one.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK_EQUAL(param_one.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(param_one.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK(param != param_one);
+ BOOST_CHECK(!(param == param_one));
+#endif
+ BOOST_CHECK(param_default != param_one);
+ BOOST_CHECK(!(param_default == param_one));
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_RANDOM_DISTRIBUTION::param_type param_two(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+ BOOST_CHECK_EQUAL(param_two.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(param_two.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_VALUE);
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK_EQUAL(param_two.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_DEFAULT);
+#endif
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_RANDOM_DISTRIBUTION::param_type param_three(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG3_VALUE);
+ BOOST_CHECK_EQUAL(param_three.BOOST_RANDOM_ARG1(), BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL(param_three.BOOST_RANDOM_ARG2(), BOOST_RANDOM_ARG2_VALUE);
+ BOOST_CHECK_EQUAL(param_three.BOOST_RANDOM_ARG3(), BOOST_RANDOM_ARG3_VALUE);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max) {
+ BOOST_RANDOM_DISTRIBUTION dist;
+ BOOST_CHECK_EQUAL((dist.min)(), BOOST_RANDOM_DIST0_MIN);
+ BOOST_CHECK_EQUAL((dist.max)(), BOOST_RANDOM_DIST0_MAX);
+ BOOST_RANDOM_DISTRIBUTION dist_one(BOOST_RANDOM_ARG1_VALUE);
+ BOOST_CHECK_EQUAL((dist_one.min)(), BOOST_RANDOM_DIST1_MIN);
+ BOOST_CHECK_EQUAL((dist_one.max)(), BOOST_RANDOM_DIST1_MAX);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_RANDOM_DISTRIBUTION dist_two(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+ BOOST_CHECK_EQUAL((dist_two.min)(), BOOST_RANDOM_DIST2_MIN);
+ BOOST_CHECK_EQUAL((dist_two.max)(), BOOST_RANDOM_DIST2_MAX);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_RANDOM_DISTRIBUTION dist_three(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG3_VALUE);
+ BOOST_CHECK_EQUAL((dist_three.min)(), BOOST_RANDOM_DIST3_MIN);
+ BOOST_CHECK_EQUAL((dist_three.max)(), BOOST_RANDOM_DIST3_MAX);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison) {
+ BOOST_RANDOM_DISTRIBUTION dist;
+ BOOST_RANDOM_DISTRIBUTION dist_copy(dist);
+ BOOST_RANDOM_DISTRIBUTION dist_one(BOOST_RANDOM_ARG1_VALUE);
+ BOOST_RANDOM_DISTRIBUTION dist_one_copy(dist_one);
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_RANDOM_DISTRIBUTION dist_two(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+ BOOST_RANDOM_DISTRIBUTION dist_two_copy(dist_two);
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_RANDOM_DISTRIBUTION dist_three(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG3_VALUE);
+ BOOST_RANDOM_DISTRIBUTION dist_three_copy(dist_three);
+#endif
+ 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 != dist_one);
+ BOOST_CHECK(!(dist == dist_one));
+#ifdef BOOST_RANDOM_ARG2
+ BOOST_CHECK(dist_two == dist_two_copy);
+ BOOST_CHECK(!(dist_two != dist_two_copy));
+ BOOST_CHECK(dist != dist_two);
+ BOOST_CHECK(!(dist == dist_two));
+ BOOST_CHECK(dist_one != dist_two);
+ BOOST_CHECK(!(dist_one == dist_two));
+#endif
+#ifdef BOOST_RANDOM_ARG3
+ BOOST_CHECK(dist_three == dist_three_copy);
+ BOOST_CHECK(!(dist_three != dist_three_copy));
+ BOOST_CHECK(dist != dist_three);
+ BOOST_CHECK(!(dist == dist_three));
+ BOOST_CHECK(dist_one != dist_three);
+ BOOST_CHECK(!(dist_one == dist_three));
+ BOOST_CHECK(dist_two != dist_three);
+ BOOST_CHECK(!(dist_two == dist_three));
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming) {
+#if defined(BOOST_RANDOM_ARG3)
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE, BOOST_RANDOM_ARG2_VALUE);
+#elif defined(BOOST_RANDOM_ARG2)
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE, BOOST_RANDOM_ARG2_VALUE);
+#else
+ BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_VALUE);
+#endif
+ std::stringstream stream;
+ stream << dist;
+ BOOST_RANDOM_DISTRIBUTION restored_dist;
+ stream >> restored_dist;
+ BOOST_CHECK_EQUAL(dist, restored_dist);
+}
+
+void use(BOOST_RANDOM_DISTRIBUTION::result_type) {}
+
+BOOST_AUTO_TEST_CASE(test_generation) {
+ boost::minstd_rand0 gen;
+ BOOST_RANDOM_DISTRIBUTION dist BOOST_RANDOM_TEST1_PARAMS;
+ BOOST_RANDOM_DISTRIBUTION dist_two BOOST_RANDOM_TEST2_PARAMS;
+ typedef BOOST_RANDOM_DISTRIBUTION::result_type result_type;
+ for(int i = 0; i < 10; ++i) {
+ result_type value = dist(gen);
+ use(value);
+#ifdef BOOST_RANDOM_TEST1_MIN
+ BOOST_CHECK_GE(value, BOOST_RANDOM_TEST1_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST1_MAX
+ BOOST_CHECK_LE(value, BOOST_RANDOM_TEST1_MAX);
+#endif
+ result_type value_two = dist_two(gen);
+ use(value_two);
+#ifdef BOOST_RANDOM_TEST2_MIN
+ BOOST_CHECK_GE(value_two, BOOST_RANDOM_TEST2_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST2_MAX
+ BOOST_CHECK_LE(value_two, BOOST_RANDOM_TEST2_MAX);
+#endif
+ result_type value_param = dist_two(gen, dist.param());
+ use(value_param);
+#ifdef BOOST_RANDOM_TEST1_MIN
+ BOOST_CHECK_GE(value_param, BOOST_RANDOM_TEST1_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST1_MAX
+ BOOST_CHECK_LE(value_param, BOOST_RANDOM_TEST1_MAX);
+#endif
+ result_type value_two_param = dist(gen, dist_two.param());
+ use(value_two_param);
+#ifdef BOOST_RANDOM_TEST2_MIN
+ BOOST_CHECK_GE(value_two_param, BOOST_RANDOM_TEST2_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST2_MAX
+ BOOST_CHECK_LE(value_two_param, BOOST_RANDOM_TEST2_MAX);
+#endif
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_generation_float) {
+ boost::lagged_fibonacci607 gen;
+ BOOST_RANDOM_DISTRIBUTION dist BOOST_RANDOM_TEST1_PARAMS;
+ BOOST_RANDOM_DISTRIBUTION dist_two BOOST_RANDOM_TEST2_PARAMS;
+ typedef BOOST_RANDOM_DISTRIBUTION::result_type result_type;
+ for(int i = 0; i < 10; ++i) {
+ result_type value = dist(gen);
+ use(value);
+#ifdef BOOST_RANDOM_TEST1_MIN
+ BOOST_CHECK_GE(value, BOOST_RANDOM_TEST1_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST1_MAX
+ BOOST_CHECK_LE(value, BOOST_RANDOM_TEST1_MAX);
+#endif
+ result_type value_two = dist_two(gen);
+ use(value_two);
+#ifdef BOOST_RANDOM_TEST2_MIN
+ BOOST_CHECK_GE(value_two, BOOST_RANDOM_TEST2_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST2_MAX
+ BOOST_CHECK_LE(value_two, BOOST_RANDOM_TEST2_MAX);
+#endif
+ result_type value_param = dist_two(gen, dist.param());
+ use(value_param);
+#ifdef BOOST_RANDOM_TEST1_MIN
+ BOOST_CHECK_GE(value_param, BOOST_RANDOM_TEST1_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST1_MAX
+ BOOST_CHECK_LE(value_param, BOOST_RANDOM_TEST1_MAX);
+#endif
+ result_type value_two_param = dist(gen, dist_two.param());
+ use(value_two_param);
+#ifdef BOOST_RANDOM_TEST2_MIN
+ BOOST_CHECK_GE(value_two_param, BOOST_RANDOM_TEST2_MIN);
+#endif
+#ifdef BOOST_RANDOM_TEST2_MAX
+ BOOST_CHECK_LE(value_two_param, BOOST_RANDOM_TEST2_MAX);
+#endif
+ }
+}
+
diff --git a/libs/random/test/test_ecuyer1988.cpp b/libs/random/test/test_ecuyer1988.cpp
new file mode 100644
index 0000000000..1f808c3952
--- /dev/null
+++ b/libs/random/test/test_ecuyer1988.cpp
@@ -0,0 +1,24 @@
+/* test_ecuyer1988.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: test_ecuyer1988.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/additive_combine.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ecuyer1988
+
+#define BOOST_RANDOM_SEED_WORDS 2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 2060321752U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1928563088U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 776923198U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x7AE0C087U, 0x948A8A31U, 0xBE5CCBA9U, 0x1316692CU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_exponential.cpp b/libs/random/test/test_exponential.cpp
new file mode 100644
index 0000000000..0ad9c5db62
--- /dev/null
+++ b/libs/random/test/test_exponential.cpp
@@ -0,0 +1,24 @@
+/* test_exponential.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: test_exponential.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/exponential.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::exponential_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME exponential
+#define BOOST_MATH_DISTRIBUTION boost::math::exponential
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME lambda
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.0001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_exponential_distribution.cpp b/libs/random/test/test_exponential_distribution.cpp
new file mode 100644
index 0000000000..8563ae67d5
--- /dev/null
+++ b/libs/random/test/test_exponential_distribution.cpp
@@ -0,0 +1,32 @@
+/* test_exponential_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: test_exponential_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/exponential_distribution.hpp>
+
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::exponential_distribution<>
+#define BOOST_RANDOM_ARG1 lambda
+#define BOOST_RANDOM_ARG1_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE 7.5
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0.0
+
+#define BOOST_RANDOM_TEST2_PARAMS (1000.0)
+#define BOOST_RANDOM_TEST2_MIN 0.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_extreme_value.cpp b/libs/random/test/test_extreme_value.cpp
new file mode 100644
index 0000000000..ca0b817257
--- /dev/null
+++ b/libs/random/test/test_extreme_value.cpp
@@ -0,0 +1,28 @@
+/* test_extreme_value.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: test_extreme_value.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/extreme_value_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/extreme_value.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::extreme_value_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME extreme_value
+#define BOOST_MATH_DISTRIBUTION boost::math::extreme_value
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME a
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME b
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_extreme_value_distribution.cpp b/libs/random/test/test_extreme_value_distribution.cpp
new file mode 100644
index 0000000000..64cf5d9ce8
--- /dev/null
+++ b/libs/random/test/test_extreme_value_distribution.cpp
@@ -0,0 +1,36 @@
+/* test_extreme_value_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: test_extreme_value_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/extreme_value_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::extreme_value_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 1.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 -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS (-100.0)
+#define BOOST_RANDOM_TEST1_MAX 0
+
+#define BOOST_RANDOM_TEST2_PARAMS (100.0)
+#define BOOST_RANDOM_TEST2_MIN 0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_fisher_f.cpp b/libs/random/test/test_fisher_f.cpp
new file mode 100644
index 0000000000..e4a6a7c071
--- /dev/null
+++ b/libs/random/test/test_fisher_f.cpp
@@ -0,0 +1,28 @@
+/* test_fisher_f.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: test_fisher_f.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/fisher_f_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/fisher_f.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::fisher_f_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME fisher_f
+#define BOOST_MATH_DISTRIBUTION boost::math::fisher_f
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME m
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME n
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_fisher_f_distribution.cpp b/libs/random/test/test_fisher_f_distribution.cpp
new file mode 100644
index 0000000000..b40700492b
--- /dev/null
+++ b/libs/random/test/test_fisher_f_distribution.cpp
@@ -0,0 +1,33 @@
+/* test_fisher_f_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: test_fisher_f_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/fisher_f_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::fisher_f_distribution<>
+#define BOOST_RANDOM_ARG1 m
+#define BOOST_RANDOM_ARG2 n
+#define BOOST_RANDOM_ARG1_DEFAULT 1.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 (1.0, 2.1)
+#define BOOST_RANDOM_TEST2_PARAMS (10.0, 10.0)
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_gamma.cpp b/libs/random/test/test_gamma.cpp
new file mode 100644
index 0000000000..2f5391fc19
--- /dev/null
+++ b/libs/random/test/test_gamma.cpp
@@ -0,0 +1,28 @@
+/* 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: test_gamma.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/gamma.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::gamma_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME gamma
+#define BOOST_MATH_DISTRIBUTION boost::math::gamma_distribution<>
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME alpha
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME beta
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_gamma_distribution.cpp b/libs/random/test/test_gamma_distribution.cpp
new file mode 100644
index 0000000000..7ed5cf2880
--- /dev/null
+++ b/libs/random/test/test_gamma_distribution.cpp
@@ -0,0 +1,37 @@
+/* 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: test_gamma_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/gamma_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::gamma_distribution<>
+#define BOOST_RANDOM_ARG1 alpha
+#define BOOST_RANDOM_ARG2 beta
+#define BOOST_RANDOM_ARG1_DEFAULT 1.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
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN 0
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0.0
+#define BOOST_RANDOM_TEST1_MAX 100.0
+
+#define BOOST_RANDOM_TEST2_PARAMS (1.0, 1000000.0)
+#define BOOST_RANDOM_TEST2_MIN 100.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_generate_canonical.cpp b/libs/random/test/test_generate_canonical.cpp
new file mode 100644
index 0000000000..ecf7463aa8
--- /dev/null
+++ b/libs/random/test/test_generate_canonical.cpp
@@ -0,0 +1,103 @@
+/* test_generate_canonical.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: test_generate_canonical.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/generate_canonical.hpp>
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+typedef boost::mpl::vector<
+ boost::random::minstd_rand,
+ boost::random::mt19937,
+ boost::random::lagged_fibonacci607
+> engines;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_float, Engine, engines)
+{
+ Engine eng;
+ Engine expected;
+ for(int i = 0; i < 1000; ++i) {
+ float val = boost::random::generate_canonical<float, 64>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(1000);
+ BOOST_CHECK_EQUAL(eng, expected);
+ for(int i = 0; i < 1000; ++i) {
+ float val = boost::random::generate_canonical<float, 12>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(1000);
+ BOOST_CHECK_EQUAL(eng, expected);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_double, Engine, engines)
+{
+ Engine eng;
+ Engine expected;
+ for(int i = 0; i < 1000; ++i) {
+ double val = boost::random::generate_canonical<double, 64>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(2000);
+ BOOST_CHECK_EQUAL(eng, expected);
+ for(int i = 0; i < 1000; ++i) {
+ double val = boost::random::generate_canonical<double, 12>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(1000);
+ BOOST_CHECK_EQUAL(eng, expected);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_long_double, Engine, engines)
+{
+ Engine eng;
+ Engine expected;
+ for(int i = 0; i < 1000; ++i) {
+ long double val = boost::random::generate_canonical<long double, 60>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(2000);
+ BOOST_CHECK_EQUAL(eng, expected);
+ for(int i = 0; i < 1000; ++i) {
+ long double val = boost::random::generate_canonical<long double, 12>(eng);
+ BOOST_CHECK_GE(val, 0);
+ BOOST_CHECK_LT(val, 1);
+ }
+ expected.discard(1000);
+ BOOST_CHECK_EQUAL(eng, expected);
+}
+
+struct max_engine
+{
+ typedef boost::uint32_t result_type;
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return ~boost::uint32_t(0); }
+ result_type operator()() { return (max)(); }
+};
+
+BOOST_AUTO_TEST_CASE(test_max)
+{
+ max_engine eng;
+ BOOST_CHECK_LT((boost::random::generate_canonical<float, 64>(eng)), 1);
+ BOOST_CHECK_LT((boost::random::generate_canonical<double, 64>(eng)), 1);
+ BOOST_CHECK_LT((boost::random::generate_canonical<long double, 64>(eng)), 1);
+}
diff --git a/libs/random/test/test_generator.ipp b/libs/random/test/test_generator.ipp
new file mode 100644
index 0000000000..98a6220909
--- /dev/null
+++ b/libs/random/test/test_generator.ipp
@@ -0,0 +1,246 @@
+/* test_generator.ipp
+ *
+ * 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: test_generator.ipp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include "concepts.hpp"
+#include <boost/random/seed_seq.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberEngine;
+BOOST_CONCEPT_ASSERT((RandomNumberEngine< BOOST_RANDOM_URNG >));
+
+typedef BOOST_RANDOM_URNG::result_type result_type;
+typedef boost::random::detail::seed_type<result_type>::type seed_type;
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#endif
+
+template<class Converted, class URNG, class T>
+void test_seed_conversion(URNG & urng, const T & t)
+{
+ Converted c = static_cast<Converted>(t);
+ if(static_cast<T>(c) == t) {
+ URNG urng2(c);
+ std::ostringstream msg;
+ msg << "Testing seed: type " << typeid(Converted).name() << ", value " << c;
+ BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
+ urng2.seed(c);
+ BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
+ }
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+void test_seed(seed_type value)
+{
+ BOOST_RANDOM_URNG urng(value);
+
+ // integral types
+ test_seed_conversion<char>(urng, value);
+ test_seed_conversion<signed char>(urng, value);
+ test_seed_conversion<unsigned char>(urng, value);
+ test_seed_conversion<short>(urng, value);
+ test_seed_conversion<unsigned short>(urng, value);
+ test_seed_conversion<int>(urng, value);
+ test_seed_conversion<unsigned int>(urng, value);
+ test_seed_conversion<long>(urng, value);
+ test_seed_conversion<unsigned long>(urng, value);
+#if !defined(BOOST_NO_INT64_T)
+ test_seed_conversion<boost::int64_t>(urng, value);
+ test_seed_conversion<boost::uint64_t>(urng, value);
+#endif
+
+ // floating point types
+ test_seed_conversion<float>(urng, value);
+ test_seed_conversion<double>(urng, value);
+ test_seed_conversion<long double>(urng, value);
+}
+
+BOOST_AUTO_TEST_CASE(test_default_seed)
+{
+ BOOST_RANDOM_URNG urng;
+ BOOST_RANDOM_URNG urng2;
+ urng2();
+ BOOST_CHECK_NE(urng, urng2);
+ urng2.seed();
+ BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_arithmetic_seed)
+{
+ test_seed(static_cast<seed_type>(0));
+ test_seed(static_cast<seed_type>(127));
+ test_seed(static_cast<seed_type>(539157235));
+ test_seed(static_cast<seed_type>(~0u));
+}
+
+BOOST_AUTO_TEST_CASE(test_iterator_seed)
+{
+ const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
+ std::vector<int>::const_iterator it = v.begin();
+ std::vector<int>::const_iterator it_end = v.end();
+ BOOST_RANDOM_URNG urng(it, it_end);
+ BOOST_CHECK(it != v.begin());
+ std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
+ BOOST_CHECK_GT(n_words, 0);
+ BOOST_CHECK_EQUAL(n_words, BOOST_RANDOM_SEED_WORDS);
+
+ it = v.begin();
+ BOOST_RANDOM_URNG urng2;
+ urng2.seed(it, it_end);
+ std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words2 = (it - v.begin());
+ BOOST_CHECK_EQUAL(n_words, n_words2);
+ BOOST_CHECK_EQUAL(urng, urng2);
+
+ it = v.end();
+ BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
+ BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
+
+ if(n_words > 1) {
+ it = v.end();
+ --it;
+ BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
+ it = v.end();
+ --it;
+ BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_seed_seq_seed)
+{
+ boost::random::seed_seq q;
+ BOOST_RANDOM_URNG urng(q);
+ BOOST_RANDOM_URNG urng2;
+ BOOST_CHECK_NE(urng, urng2);
+ urng2.seed(q);
+ BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+template<class CharT>
+void do_test_streaming(const BOOST_RANDOM_URNG& urng)
+{
+ BOOST_RANDOM_URNG urng2;
+ std::basic_ostringstream<CharT> output;
+ output << urng;
+ BOOST_CHECK_NE(urng, urng2);
+ // restore old state
+ std::basic_istringstream<CharT> input(output.str());
+ input >> urng2;
+ BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming)
+{
+ BOOST_RANDOM_URNG urng;
+ urng.discard(9307);
+ do_test_streaming<char>(urng);
+#if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
+ do_test_streaming<wchar_t>(urng);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_discard)
+{
+ BOOST_RANDOM_URNG urng;
+ BOOST_RANDOM_URNG urng2;
+ BOOST_CHECK_EQUAL(urng, urng2);
+ for(int i = 0; i < 9307; ++i)
+ urng();
+ BOOST_CHECK_NE(urng, urng2);
+ urng2.discard(9307);
+ BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy)
+{
+ BOOST_RANDOM_URNG urng;
+ urng.discard(9307);
+ {
+ BOOST_RANDOM_URNG urng2 = urng;
+ BOOST_CHECK_EQUAL(urng, urng2);
+ }
+ {
+ BOOST_RANDOM_URNG urng2(urng);
+ BOOST_CHECK_EQUAL(urng, urng2);
+ }
+ {
+ BOOST_RANDOM_URNG urng2;
+ urng2 = urng;
+ BOOST_CHECK_EQUAL(urng, urng2);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max)
+{
+ BOOST_RANDOM_URNG urng;
+ for(int i = 0; i < 10000; ++i) {
+ result_type value = urng();
+ BOOST_CHECK_GE(value, (BOOST_RANDOM_URNG::min)());
+ BOOST_CHECK_LE(value, (BOOST_RANDOM_URNG::max)());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison)
+{
+ BOOST_RANDOM_URNG urng;
+ BOOST_RANDOM_URNG urng2;
+ BOOST_CHECK(urng == urng2);
+ BOOST_CHECK(!(urng != urng2));
+ urng();
+ BOOST_CHECK(urng != urng2);
+ BOOST_CHECK(!(urng == urng2));
+}
+
+BOOST_AUTO_TEST_CASE(validate)
+{
+ BOOST_RANDOM_URNG urng;
+ for(int i = 0; i < 9999; ++i) {
+ urng();
+ }
+ BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_VALIDATION_VALUE);
+}
+
+BOOST_AUTO_TEST_CASE(validate_seed_seq)
+{
+ boost::random::seed_seq seed;
+ BOOST_RANDOM_URNG urng(seed);
+ for(int i = 0; i < 9999; ++i) {
+ urng();
+ }
+ BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE);
+}
+
+BOOST_AUTO_TEST_CASE(validate_iter)
+{
+ const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
+ std::vector<int>::const_iterator it = v.begin();
+ std::vector<int>::const_iterator it_end = v.end();
+ BOOST_RANDOM_URNG urng(it, it_end);
+ for(int i = 0; i < 9999; ++i) {
+ urng();
+ }
+ BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_ITERATOR_VALIDATION_VALUE);
+}
+
+BOOST_AUTO_TEST_CASE(test_generate)
+{
+ BOOST_RANDOM_URNG urng;
+ boost::uint32_t expected[] = BOOST_RANDOM_GENERATE_VALUES;
+ static const std::size_t N = sizeof(expected)/sizeof(expected[0]);
+ boost::uint32_t actual[N];
+ urng.generate(&actual[0], &actual[0] + N);
+ BOOST_CHECK_EQUAL_COLLECTIONS(actual, actual + N, expected, expected + N);
+}
diff --git a/libs/random/test/test_geometric.cpp b/libs/random/test/test_geometric.cpp
new file mode 100644
index 0000000000..d8ba2466b5
--- /dev/null
+++ b/libs/random/test/test_geometric.cpp
@@ -0,0 +1,26 @@
+/* test_geometric.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: test_geometric.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/geometric.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::geometric_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME geometric
+#define BOOST_MATH_DISTRIBUTION boost::math::geometric
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME p
+#define BOOST_RANDOM_ARG1_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.0001, 0.9999)
+#define BOOST_RANDOM_DISTRIBUTION_MAX boost::numeric_cast<int>(-5 / std::log(1-p))
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_geometric_distribution.cpp b/libs/random/test/test_geometric_distribution.cpp
new file mode 100644
index 0000000000..833e8f0d5d
--- /dev/null
+++ b/libs/random/test/test_geometric_distribution.cpp
@@ -0,0 +1,31 @@
+/* test_geometric_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: test_geometric_distribution.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/geometric_distribution.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::geometric_distribution<>
+#define BOOST_RANDOM_ARG1 p
+#define BOOST_RANDOM_ARG1_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_VALUE 0.25
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<int>::max)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<int>::max)()
+
+#define BOOST_RANDOM_TEST1_PARAMS (0.9999)
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 0
+
+#define BOOST_RANDOM_TEST2_PARAMS (0.0001)
+#define BOOST_RANDOM_TEST2_MIN 1
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_hellekalek1995.cpp b/libs/random/test/test_hellekalek1995.cpp
new file mode 100644
index 0000000000..064fceb919
--- /dev/null
+++ b/libs/random/test/test_hellekalek1995.cpp
@@ -0,0 +1,24 @@
+/* test_mt19937.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: test_hellekalek1995.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/inversive_congruential.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::hellekalek1995
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+#define BOOST_RANDOM_VALIDATION_VALUE 1187812169U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1912573642U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 618743552U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5642A47BU, 0x1F6987E8U, 0xD35860E7U, 0xC8C661ABU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_independent_bits31.cpp b/libs/random/test/test_independent_bits31.cpp
new file mode 100644
index 0000000000..0b44730595
--- /dev/null
+++ b/libs/random/test/test_independent_bits31.cpp
@@ -0,0 +1,26 @@
+/* test_independent_bits31.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: test_independent_bits31.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/independent_bits.hpp>
+#include <boost/random/linear_congruential.hpp>
+
+typedef boost::random::independent_bits_engine<boost::random::minstd_rand0, 31, boost::uint32_t> independent_bits31;
+#define BOOST_RANDOM_URNG independent_bits31
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+#define BOOST_RANDOM_VALIDATION_VALUE 26292962U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 364481529U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1399154219U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC1A63AF0U, 0xD66C0614U, 0xADE076B1U, 0xC1DAE13FU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_independent_bits32.cpp b/libs/random/test/test_independent_bits32.cpp
new file mode 100644
index 0000000000..48972e5f04
--- /dev/null
+++ b/libs/random/test/test_independent_bits32.cpp
@@ -0,0 +1,26 @@
+/* test_independent_bits32.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: test_independent_bits32.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/independent_bits.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
+typedef boost::random::independent_bits_engine<boost::random::mt19937, 32, boost::uint32_t> independent_bits32;
+#define BOOST_RANDOM_URNG independent_bits32
+
+#define BOOST_RANDOM_SEED_WORDS 624
+
+#define BOOST_RANDOM_VALIDATION_VALUE 4123659995U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 666528879U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3408548740U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xD091BB5CU, 0x22AE9EF6U, 0xE7E1FAEEU, 0xD5C31F79U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_knuth_b.cpp b/libs/random/test/test_knuth_b.cpp
new file mode 100644
index 0000000000..df924b0293
--- /dev/null
+++ b/libs/random/test/test_knuth_b.cpp
@@ -0,0 +1,26 @@
+/* test_knuth_b.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: test_knuth_b.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/shuffle_order.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::knuth_b
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+// validation from the C++0x draft (n3090)
+#define BOOST_RANDOM_VALIDATION_VALUE 1112339016U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 202352021U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1692601883U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5D189C63U, 0xD0544F0EU, 0x15B0E78FU, 0xD814D654U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_kreutzer1986.cpp b/libs/random/test/test_kreutzer1986.cpp
new file mode 100644
index 0000000000..0ebbfacfb5
--- /dev/null
+++ b/libs/random/test/test_kreutzer1986.cpp
@@ -0,0 +1,26 @@
+/* test_kreutzer1986.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: test_kreutzer1986.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/shuffle_order.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::kreutzer1986
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+// validation by experiment from Harry Erwin's generator.h (private e-mail)
+#define BOOST_RANDOM_VALIDATION_VALUE 139726U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 589731U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 163138U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x3EADAB08U, 0x85E481CEU, 0xCF84AEA5U, 0x39D4395BU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci.cpp b/libs/random/test/test_lagged_fibonacci.cpp
new file mode 100644
index 0000000000..9d4bbe6d55
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci.cpp
@@ -0,0 +1,25 @@
+/* test_lagged_fibonacci.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: test_lagged_fibonacci.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+typedef boost::random::lagged_fibonacci_engine<boost::uint32_t, 24, 607, 273> lagged_fibonacci;
+#define BOOST_RANDOM_URNG lagged_fibonacci
+
+#define BOOST_RANDOM_SEED_WORDS 607
+
+#define BOOST_RANDOM_VALIDATION_VALUE 3543833U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1364481U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 4372778U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xF61A5094U, 0xFC4BA046U, 0xF1C41E92U, 0x3D82FE61U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci1279.cpp b/libs/random/test/test_lagged_fibonacci1279.cpp
new file mode 100644
index 0000000000..8ab1ea220f
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci1279.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci1279.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: test_lagged_fibonacci1279.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci1279
+
+#define BOOST_RANDOM_SEED_WORDS 1279*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.39647253381274083
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.97108839261370505
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.56042480761195179
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4D102C47U, 0xC4E610D7U, 0xF29333BEU, 0x6E45EBE7U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci19937.cpp b/libs/random/test/test_lagged_fibonacci19937.cpp
new file mode 100644
index 0000000000..53235e136d
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci19937.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci19937.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: test_lagged_fibonacci19937.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci19937
+
+#define BOOST_RANDOM_SEED_WORDS 19937*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.24396310480293693
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.95892429604358043
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0029754638678802792
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5CE9850CU, 0xAA20067BU, 0x4E48643BU, 0xA4A59F4BU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci2281.cpp b/libs/random/test/test_lagged_fibonacci2281.cpp
new file mode 100644
index 0000000000..9fdac23578
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci2281.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci2281.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: test_lagged_fibonacci2281.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci2281
+
+#define BOOST_RANDOM_SEED_WORDS 2281*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.91955231927349246
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.4447517699440553
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.087280273457821522
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x7EB0882AU, 0xCE09BE60U, 0xD53046CFU, 0x93257E41U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci23209.cpp b/libs/random/test/test_lagged_fibonacci23209.cpp
new file mode 100644
index 0000000000..566eec4462
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci23209.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci23209.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: test_lagged_fibonacci23209.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci23209
+
+#define BOOST_RANDOM_SEED_WORDS 23209*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.086299988971202168
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.63611281281476195
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0019836425785868528
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4301DE0AU, 0xAD2584E3U, 0x7C28463CU, 0x74848542U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci3217.cpp b/libs/random/test/test_lagged_fibonacci3217.cpp
new file mode 100644
index 0000000000..8f87e3a354
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci3217.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci3217.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: test_lagged_fibonacci3217.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci3217
+
+#define BOOST_RANDOM_SEED_WORDS 3217*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.54223093970093927
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.073852702370395207
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.1805114746514036
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4938F127U, 0x86C65CFEU, 0x65356579U, 0xA6CDC325U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci4423.cpp b/libs/random/test/test_lagged_fibonacci4423.cpp
new file mode 100644
index 0000000000..99b3d74a16
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci4423.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci4423.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: test_lagged_fibonacci4423.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci4423
+
+#define BOOST_RANDOM_SEED_WORDS 4423*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.23188533286820601
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.3872440622693567
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.012893676760814543
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x6D4DBAFU, 0x8039C1A9U, 0x3DA53D58U, 0x95155BE5U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci44497.cpp b/libs/random/test/test_lagged_fibonacci44497.cpp
new file mode 100644
index 0000000000..bff33b5eac
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci44497.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci44497.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: test_lagged_fibonacci44497.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci44497
+
+#define BOOST_RANDOM_SEED_WORDS 44497*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.12519369894159738
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.92285669730527431
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0019836425785868528
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x6A2DCEA9U, 0x4668EFB4U, 0x711E352FU, 0xA963C43BU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci607.cpp b/libs/random/test/test_lagged_fibonacci607.cpp
new file mode 100644
index 0000000000..79bccea3bb
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci607.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci607.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: test_lagged_fibonacci607.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci607
+
+#define BOOST_RANDOM_SEED_WORDS 607*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.039230772001715764
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.73105942788451372
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.72330291632639643
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x78EB0905U, 0x61766547U, 0xCB507F64U, 0x94FA3EC0U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lagged_fibonacci9689.cpp b/libs/random/test/test_lagged_fibonacci9689.cpp
new file mode 100644
index 0000000000..8204b54f5a
--- /dev/null
+++ b/libs/random/test/test_lagged_fibonacci9689.cpp
@@ -0,0 +1,24 @@
+/* test_lagged_fibonacci9689.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: test_lagged_fibonacci9689.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/lagged_fibonacci.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci9689
+
+#define BOOST_RANDOM_SEED_WORDS 9689*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.059230573043926427
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.80900890657466462
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0039672851571737056
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x32EF18BEU, 0x79277C11U, 0xA383438U, 0x32155952U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_linear_feedback_shift.cpp b/libs/random/test/test_linear_feedback_shift.cpp
new file mode 100644
index 0000000000..e98322fbd3
--- /dev/null
+++ b/libs/random/test/test_linear_feedback_shift.cpp
@@ -0,0 +1,25 @@
+/* test_linear_feedback_shift.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: test_linear_feedback_shift.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/linear_feedback_shift.hpp>
+
+typedef boost::random::linear_feedback_shift_engine<boost::uint32_t, 32, 31, 13, 12> linear_feedback_shift;
+#define BOOST_RANDOM_URNG linear_feedback_shift
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+#define BOOST_RANDOM_VALIDATION_VALUE 981440277U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 3709603036U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3112279337U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x154005U, 0x54005502U, 0x5502BD4U, 0x2BD4005U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_lognormal.cpp b/libs/random/test/test_lognormal.cpp
new file mode 100644
index 0000000000..cd92e2e891
--- /dev/null
+++ b/libs/random/test/test_lognormal.cpp
@@ -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: test_lognormal.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#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"
diff --git a/libs/random/test/test_lognormal_distribution.cpp b/libs/random/test/test_lognormal_distribution.cpp
new file mode 100644
index 0000000000..a27b8baa65
--- /dev/null
+++ b/libs/random/test/test_lognormal_distribution.cpp
@@ -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: test_lognormal_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#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"
diff --git a/libs/random/test/test_minstd_rand.cpp b/libs/random/test/test_minstd_rand.cpp
new file mode 100644
index 0000000000..a59a8c6816
--- /dev/null
+++ b/libs/random/test/test_minstd_rand.cpp
@@ -0,0 +1,26 @@
+/* test_minstd_rand.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: test_minstd_rand.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::minstd_rand
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+// validation values from the publications
+#define BOOST_RANDOM_VALIDATION_VALUE 399268537U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1000962296U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 182651141U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x8400BC8EU, 0xF45B895FU, 0x145F0F91U, 0xE5F8F088U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_minstd_rand0.cpp b/libs/random/test/test_minstd_rand0.cpp
new file mode 100644
index 0000000000..86717570f3
--- /dev/null
+++ b/libs/random/test/test_minstd_rand0.cpp
@@ -0,0 +1,26 @@
+/* test_minstd_rand0.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: test_minstd_rand0.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::minstd_rand0
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+// validation values from the publications
+#define BOOST_RANDOM_VALIDATION_VALUE 1043618065U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1274759829U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1263181168U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC00041A6U, 0xCD8358EBU, 0x430A4B7AU, 0x31B781ADU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_mt11213b.cpp b/libs/random/test/test_mt11213b.cpp
new file mode 100644
index 0000000000..a26ec79b41
--- /dev/null
+++ b/libs/random/test/test_mt11213b.cpp
@@ -0,0 +1,24 @@
+/* test_mt11213b.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: test_mt11213b.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/mersenne_twister.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::mt11213b
+
+#define BOOST_RANDOM_SEED_WORDS 351
+
+#define BOOST_RANDOM_VALIDATION_VALUE 3809585648U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 2936939529U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 2434563197U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xEF3F3F3FU, 0x70082175U, 0xDAF6EAF5U, 0x2A16A63EU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_mt19937.cpp b/libs/random/test/test_mt19937.cpp
new file mode 100644
index 0000000000..94928e5ef5
--- /dev/null
+++ b/libs/random/test/test_mt19937.cpp
@@ -0,0 +1,78 @@
+/* test_mt19937.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: test_mt19937.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/mersenne_twister.hpp>
+#include <algorithm>
+#include <vector>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::mt19937
+
+#define BOOST_RANDOM_SEED_WORDS 624
+
+// validation by experiment from mt19937.c
+#define BOOST_RANDOM_VALIDATION_VALUE 4123659995U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 666528879U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3408548740U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xD091BB5CU, 0x22AE9EF6U, 0xE7E1FAEEU, 0xD5C31F79U }
+
+#include "test_generator.ipp"
+
+struct seed_seq_0 {
+ template<class It>
+ void generate(It begin, It end) const {
+ std::fill(begin, end, boost::uint32_t(0));
+ }
+};
+
+struct seed_seq_1 {
+ template<class It>
+ void generate(It begin, It end) const {
+ std::fill(begin, end, boost::uint32_t(0));
+ *(end - 1) = 1;
+ }
+};
+
+BOOST_AUTO_TEST_CASE(test_special_seed) {
+ {
+ seed_seq_1 seed;
+ std::vector<boost::uint32_t> vec(624);
+ seed.generate(vec.begin(), vec.end());
+
+ std::vector<boost::uint32_t>::iterator it = vec.begin();
+ boost::mt19937 gen1(it, vec.end());
+ BOOST_CHECK_EQUAL(gen1(), 0);
+ BOOST_CHECK_EQUAL(gen1(), 0);
+
+ boost::mt19937 gen2(seed);
+ BOOST_CHECK_EQUAL(gen2(), 0);
+ BOOST_CHECK_EQUAL(gen2(), 0);
+
+ BOOST_CHECK_EQUAL(gen1, gen2);
+ }
+ {
+ seed_seq_0 seed;
+ std::vector<boost::uint32_t> vec(624);
+ seed.generate(vec.begin(), vec.end());
+
+ std::vector<boost::uint32_t>::iterator it = vec.begin();
+ boost::mt19937 gen1(it, vec.end());
+ BOOST_CHECK_EQUAL(gen1(), 1141379330u);
+ BOOST_CHECK_EQUAL(gen1(), 0);
+
+ boost::mt19937 gen2(seed);
+ BOOST_CHECK_EQUAL(gen2(), 1141379330u);
+ BOOST_CHECK_EQUAL(gen2(), 0);
+
+ BOOST_CHECK_EQUAL(gen1, gen2);
+ }
+}
diff --git a/libs/random/test/test_mt19937_64.cpp b/libs/random/test/test_mt19937_64.cpp
new file mode 100644
index 0000000000..bd3510dee9
--- /dev/null
+++ b/libs/random/test/test_mt19937_64.cpp
@@ -0,0 +1,26 @@
+/* test_mt119937_64.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: test_mt19937_64.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::mt19937_64
+
+#define BOOST_RANDOM_SEED_WORDS 624
+
+// validation from the C++0x draft (n3090)
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(9981545732273789042)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(12176471137395770412)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(13543700832025962283)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xF6F6AEA6U, 0xC96D191CU, 0x8BC80F1CU, 0x401F7AC7U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_negative_binomial.cpp b/libs/random/test/test_negative_binomial.cpp
new file mode 100644
index 0000000000..552916f7c9
--- /dev/null
+++ b/libs/random/test/test_negative_binomial.cpp
@@ -0,0 +1,30 @@
+/* test_negative_binomial.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: test_negative_binomial.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/negative_binomial_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/math/distributions/negative_binomial.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::negative_binomial_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME negative_binomial
+#define BOOST_MATH_DISTRIBUTION boost::math::negative_binomial
+#define BOOST_RANDOM_ARG1_TYPE int
+#define BOOST_RANDOM_ARG1_NAME n
+#define BOOST_RANDOM_ARG1_DEFAULT 100000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_int<>(0, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME p
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_01<>()
+#define BOOST_RANDOM_DISTRIBUTION_MAX n
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_negative_binomial_distribution.cpp b/libs/random/test/test_negative_binomial_distribution.cpp
new file mode 100644
index 0000000000..8bf041db27
--- /dev/null
+++ b/libs/random/test/test_negative_binomial_distribution.cpp
@@ -0,0 +1,37 @@
+/* test_negative_binomial_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: test_negative_binomial_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/negative_binomial_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::negative_binomial_distribution<>
+#define BOOST_RANDOM_ARG1 k
+#define BOOST_RANDOM_ARG2 p
+#define BOOST_RANDOM_ARG1_DEFAULT 1
+#define BOOST_RANDOM_ARG2_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_VALUE 10
+#define BOOST_RANDOM_ARG2_VALUE 0.25
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<int>::max)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<int>::max)()
+#define BOOST_RANDOM_DIST2_MIN 0
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<int>::max)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 10
+
+#define BOOST_RANDOM_TEST2_PARAMS (100, 0.5)
+#define BOOST_RANDOM_TEST2_MIN 50
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_normal.cpp b/libs/random/test/test_normal.cpp
new file mode 100644
index 0000000000..eab52a699a
--- /dev/null
+++ b/libs/random/test/test_normal.cpp
@@ -0,0 +1,28 @@
+/* test_normal.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: test_normal.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/normal.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::normal_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME normal
+#define BOOST_MATH_DISTRIBUTION boost::math::normal
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME m
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.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 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_normal_distribution.cpp b/libs/random/test/test_normal_distribution.cpp
new file mode 100644
index 0000000000..ab3b683785
--- /dev/null
+++ b/libs/random/test/test_normal_distribution.cpp
@@ -0,0 +1,36 @@
+/* test_normal_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: test_normal_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/normal_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::normal_distribution<>
+#define BOOST_RANDOM_ARG1 mean
+#define BOOST_RANDOM_ARG2 sigma
+#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 -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS (-100.0)
+#define BOOST_RANDOM_TEST1_MAX 0
+
+#define BOOST_RANDOM_TEST2_PARAMS (100.0)
+#define BOOST_RANDOM_TEST2_MIN 0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_old_uniform_int.cpp b/libs/random/test/test_old_uniform_int.cpp
new file mode 100644
index 0000000000..7124238e88
--- /dev/null
+++ b/libs/random/test/test_old_uniform_int.cpp
@@ -0,0 +1,26 @@
+/* test_old_uniform_int.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: test_old_uniform_int.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_int.hpp>
+#include <boost/math/distributions/uniform.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::uniform_int<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME uniform_int
+#define BOOST_MATH_DISTRIBUTION boost::math::uniform
+#define BOOST_RANDOM_ARG1_TYPE int
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 1000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_int<>(0, n)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0, b)
+#define BOOST_MATH_DISTRIBUTION_INIT (0, b+1)
+#define BOOST_RANDOM_DISTRIBUTION_MAX b
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_old_uniform_int_distribution.cpp b/libs/random/test/test_old_uniform_int_distribution.cpp
new file mode 100644
index 0000000000..27e630ffad
--- /dev/null
+++ b/libs/random/test/test_old_uniform_int_distribution.cpp
@@ -0,0 +1,76 @@
+/* test_old_uniform_int_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: test_old_uniform_int_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_int.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::uniform_int<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 0
+#define BOOST_RANDOM_ARG2_DEFAULT 9
+#define BOOST_RANDOM_ARG1_VALUE 5
+#define BOOST_RANDOM_ARG2_VALUE 250
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX 9
+#define BOOST_RANDOM_DIST1_MIN 5
+#define BOOST_RANDOM_DIST1_MAX 9
+#define BOOST_RANDOM_DIST2_MIN 5
+#define BOOST_RANDOM_DIST2_MAX 250
+
+#define BOOST_RANDOM_TEST1_PARAMS (0, 9)
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 9
+
+#define BOOST_RANDOM_TEST2_PARAMS (10, 19)
+#define BOOST_RANDOM_TEST2_MIN 10
+#define BOOST_RANDOM_TEST2_MAX 19
+
+#include "test_distribution.ipp"
+
+#define BOOST_RANDOM_UNIFORM_INT boost::uniform_int
+
+#include "test_uniform_int.ipp"
+
+#include <algorithm>
+#include <boost/random/random_number_generator.hpp>
+
+// Test that uniform_int<> can be used with std::random_shuffle
+// Author: Jos Hickson
+BOOST_AUTO_TEST_CASE(test_random_shuffle)
+{
+ typedef boost::uniform_int<> distribution_type;
+ typedef boost::variate_generator<boost::mt19937 &, distribution_type> generator_type;
+
+ boost::mt19937 engine1(1234);
+ boost::mt19937 engine2(1234);
+
+ boost::random::random_number_generator<boost::mt19937> referenceRand(engine1);
+
+ distribution_type dist(0,10);
+ generator_type testRand(engine2, dist);
+
+ std::vector<int> referenceVec;
+
+ for (int i = 0; i < 200; ++i) {
+ referenceVec.push_back(i);
+ }
+
+ std::vector<int> testVec(referenceVec);
+
+ std::random_shuffle(referenceVec.begin(), referenceVec.end(), referenceRand);
+ std::random_shuffle(testVec.begin(), testVec.end(), testRand);
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ testVec.begin(), testVec.end(),
+ referenceVec.begin(), referenceVec.end());
+}
diff --git a/libs/random/test/test_old_uniform_real.cpp b/libs/random/test/test_old_uniform_real.cpp
new file mode 100644
index 0000000000..84e884b09c
--- /dev/null
+++ b/libs/random/test/test_old_uniform_real.cpp
@@ -0,0 +1,25 @@
+/* test_old_uniform_real.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: test_old_uniform_real.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/uniform.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::uniform_real<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME uniform_real
+#define BOOST_MATH_DISTRIBUTION boost::math::uniform
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 1000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0, n)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0, b)
+#define BOOST_MATH_DISTRIBUTION_INIT (0, b)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_old_uniform_real_distribution.cpp b/libs/random/test/test_old_uniform_real_distribution.cpp
new file mode 100644
index 0000000000..00ad48169a
--- /dev/null
+++ b/libs/random/test/test_old_uniform_real_distribution.cpp
@@ -0,0 +1,38 @@
+/* test_old_uniform_real_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: test_old_uniform_real_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_real.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::uniform_real<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 0.0
+#define BOOST_RANDOM_ARG2_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE -0.5
+#define BOOST_RANDOM_ARG2_VALUE 1.5
+
+#define BOOST_RANDOM_DIST0_MIN 0.0
+#define BOOST_RANDOM_DIST0_MAX 1.0
+#define BOOST_RANDOM_DIST1_MIN -0.5
+#define BOOST_RANDOM_DIST1_MAX 1.0
+#define BOOST_RANDOM_DIST2_MIN -0.5
+#define BOOST_RANDOM_DIST2_MAX 1.5
+
+#define BOOST_RANDOM_TEST1_PARAMS (-1.0, 0.0)
+#define BOOST_RANDOM_TEST1_MIN -1.0
+#define BOOST_RANDOM_TEST1_MAX 0.0
+
+#define BOOST_RANDOM_TEST2_PARAMS
+#define BOOST_RANDOM_TEST2_MIN 0.0
+#define BOOST_RANDOM_TEST2_MAX 1.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_piecewise_constant.cpp b/libs/random/test/test_piecewise_constant.cpp
new file mode 100644
index 0000000000..909470941b
--- /dev/null
+++ b/libs/random/test/test_piecewise_constant.cpp
@@ -0,0 +1,158 @@
+/* test_piecewise_constant.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: test_piecewise_constant.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/piecewise_constant_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/range/algorithm/lower_bound.hpp>
+#include <boost/range/numeric.hpp>
+#include <vector>
+#include <iostream>
+#include <iomanip>
+
+#include "statistic_tests.hpp"
+
+class piecewise_constant
+{
+public:
+ piecewise_constant(const std::vector<double>& intervals, const std::vector<double>& weights)
+ : intervals(intervals),
+ cumulative(1, 0.0)
+ {
+ boost::partial_sum(weights, std::back_inserter(cumulative));
+ for(std::vector<double>::iterator iter = cumulative.begin(), end = cumulative.end();
+ iter != end; ++iter)
+ {
+ *iter /= cumulative.back();
+ }
+ }
+
+ double cdf(double x) const
+ {
+ std::size_t index = boost::lower_bound(intervals, x) - intervals.begin();
+ if(index == 0) return 0;
+ else if(index == intervals.size()) return 1;
+ else {
+ double lower_weight = cumulative[index - 1];
+ double upper_weight = cumulative[index];
+ double lower = intervals[index - 1];
+ double upper = intervals[index];
+ return lower_weight + (x - lower) / (upper - lower) * (upper_weight - lower_weight);
+ }
+ }
+private:
+ std::vector<double> intervals;
+ std::vector<double> cumulative;
+};
+
+double cdf(const piecewise_constant& dist, double x)
+{
+ return dist.cdf(x);
+}
+
+bool do_test(int n, int max) {
+ std::cout << "running piecewise_constant(p0, p1, ..., p" << n-1 << ")" << " " << max << " times: " << std::flush;
+
+ std::vector<double> weights;
+ {
+ boost::mt19937 egen;
+ for(int i = 0; i < n; ++i) {
+ weights.push_back(egen());
+ }
+ }
+ std::vector<double> intervals;
+ for(int i = 0; i <= n; ++i) {
+ intervals.push_back(i);
+ }
+
+ piecewise_constant expected(intervals, weights);
+
+ boost::random::piecewise_constant_distribution<> dist(intervals, weights);
+ boost::mt19937 gen;
+ kolmogorov_experiment test(max);
+ boost::variate_generator<boost::mt19937&, boost::random::piecewise_constant_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, int max_n, int trials) {
+ boost::mt19937 gen;
+ boost::uniform_int<> idist(1, max_n);
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(idist(gen), trials)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_piecewise_constant -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;
+ int max_n = 10;
+ 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, 'n', max_n)
+ && !handle_option(argc, argv, 't', trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat, max_n, trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/libs/random/test/test_piecewise_constant_distribution.cpp b/libs/random/test/test_piecewise_constant_distribution.cpp
new file mode 100644
index 0000000000..6d19a9b6f2
--- /dev/null
+++ b/libs/random/test/test_piecewise_constant_distribution.cpp
@@ -0,0 +1,246 @@
+/* test_piecewise_constant_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: test_piecewise_constant_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/piecewise_constant_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/assign/list_of.hpp>
+#include <sstream>
+#include <vector>
+#include "concepts.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberDistribution;
+using boost::random::piecewise_constant_distribution;
+BOOST_CONCEPT_ASSERT((RandomNumberDistribution< piecewise_constant_distribution<> >));
+
+struct gen {
+ double operator()(double arg) {
+ if(arg < 100) return 100;
+ else if(arg < 103) return 1;
+ else if(arg < 107) return 2;
+ else if(arg < 111) return 1;
+ else if(arg < 114) return 4;
+ else return 100;
+ }
+};
+
+#define CHECK_SEQUENCE(actual, expected) \
+ do { \
+ std::vector<double> _actual = (actual); \
+ std::vector<double> _expected = (expected); \
+ BOOST_CHECK_EQUAL_COLLECTIONS( \
+ _actual.begin(), _actual.end(), \
+ _expected.begin(), _expected.end()); \
+ } while(false)
+
+using boost::assign::list_of;
+
+BOOST_AUTO_TEST_CASE(test_constructors) {
+ boost::random::piecewise_constant_distribution<> dist;
+ CHECK_SEQUENCE(dist.densities(), list_of(1.0));
+ CHECK_SEQUENCE(dist.intervals(), list_of(0.0)(1.0));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::piecewise_constant_distribution<> dist_il = {
+ { 99, 103, 107, 111, 115 },
+ gen()
+ };
+ CHECK_SEQUENCE(dist_il.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(dist_il.densities(), list_of(.03125)(.0625)(.03125)(.125));
+
+ boost::random::piecewise_constant_distribution<> dist_il2 = {
+ { 99 },
+ gen()
+ };
+ CHECK_SEQUENCE(dist_il2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_il2.densities(), list_of(1.0));
+#endif
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(1)(2)(1)(4);
+ std::vector<double> intervals2 = boost::assign::list_of(99);
+ std::vector<double> weights2;
+
+ boost::random::piecewise_constant_distribution<> dist_r(intervals, weights);
+ CHECK_SEQUENCE(dist_r.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(dist_r.densities(), list_of(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_constant_distribution<>
+ dist_r2(intervals2, weights2);
+ CHECK_SEQUENCE(dist_r2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_r2.densities(), list_of(1.0));
+
+ boost::random::piecewise_constant_distribution<> dist_it(
+ intervals.begin(), intervals.end(), weights.begin());
+ CHECK_SEQUENCE(dist_it.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(dist_it.densities(), list_of(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_constant_distribution<> dist_it2(
+ intervals2.begin(), intervals2.end(), weights2.begin());
+ CHECK_SEQUENCE(dist_it2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_it2.densities(), list_of(1.0));
+
+ boost::random::piecewise_constant_distribution<> dist_fun(4, 99,115, gen());
+ CHECK_SEQUENCE(dist_fun.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(dist_fun.densities(), list_of(.03125)(.0625)(.03125)(.125));
+
+ boost::random::piecewise_constant_distribution<>
+ dist_fun2(1, 99, 115, gen());
+ CHECK_SEQUENCE(dist_fun2.intervals(), list_of(99)(115));
+ CHECK_SEQUENCE(dist_fun2.densities(), list_of(0.0625));
+
+ boost::random::piecewise_constant_distribution<> copy(dist);
+ BOOST_CHECK_EQUAL(dist, copy);
+ boost::random::piecewise_constant_distribution<> copy_r(dist_r);
+ BOOST_CHECK_EQUAL(dist_r, copy_r);
+
+ boost::random::piecewise_constant_distribution<> notpow2(3, 99, 111, gen());
+ BOOST_REQUIRE_EQUAL(notpow2.densities().size(), 3u);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[0], 0.0625, 0.00000000001);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[1], 0.125, 0.00000000001);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[2], 0.0625, 0.00000000001);
+ boost::random::piecewise_constant_distribution<> copy_notpow2(notpow2);
+ BOOST_CHECK_EQUAL(notpow2, copy_notpow2);
+}
+
+BOOST_AUTO_TEST_CASE(test_param) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(1)(2)(1)(4);
+ std::vector<double> intervals2 = boost::assign::list_of(0);
+ std::vector<double> weights2;
+ boost::random::piecewise_constant_distribution<> dist(intervals, weights);
+ boost::random::piecewise_constant_distribution<>::param_type
+ param = dist.param();
+ CHECK_SEQUENCE(param.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(param.densities(), list_of(.125)(.25)(.125)(.25));
+ boost::random::piecewise_constant_distribution<> copy1(param);
+ BOOST_CHECK_EQUAL(dist, copy1);
+ boost::random::piecewise_constant_distribution<> copy2;
+ copy2.param(param);
+ BOOST_CHECK_EQUAL(dist, copy2);
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ param_copy = param;
+ BOOST_CHECK_EQUAL(param, param_copy);
+ BOOST_CHECK(param == param_copy);
+ BOOST_CHECK(!(param != param_copy));
+ boost::random::piecewise_constant_distribution<>::param_type param_default;
+ CHECK_SEQUENCE(param_default.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(param_default.densities(), list_of(1.0));
+ BOOST_CHECK(param != param_default);
+ BOOST_CHECK(!(param == param_default));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::piecewise_constant_distribution<>::param_type parm_il = {
+ { 99, 103, 107, 111, 115 },
+ gen()
+ };
+ CHECK_SEQUENCE(parm_il.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(parm_il.densities(), list_of(.03125)(.0625)(.03125)(.125));
+
+ boost::random::piecewise_constant_distribution<>::param_type parm_il2 = {
+ { 99 },
+ gen()
+ };
+ CHECK_SEQUENCE(parm_il2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_il2.densities(), list_of(1.0));
+#endif
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_r(intervals, weights);
+ CHECK_SEQUENCE(parm_r.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(parm_r.densities(), list_of(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_r2(intervals2, weights2);
+ CHECK_SEQUENCE(parm_r2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_r2.densities(), list_of(1.0));
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_it(intervals.begin(), intervals.end(), weights.begin());
+ CHECK_SEQUENCE(parm_it.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(parm_it.densities(), list_of(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_it2(intervals2.begin(), intervals2.end(), weights2.begin());
+ CHECK_SEQUENCE(parm_it2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_it2.densities(), list_of(1.0));
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_fun(4, 99, 115, gen());
+ CHECK_SEQUENCE(parm_fun.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(parm_fun.densities(), list_of(.03125)(.0625)(.03125)(.125));
+
+ boost::random::piecewise_constant_distribution<>::param_type
+ parm_fun2(1, 99, 115, gen());
+ CHECK_SEQUENCE(parm_fun2.intervals(), list_of(99)(115));
+ CHECK_SEQUENCE(parm_fun2.densities(), list_of(0.0625));
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(1)(2)(1)(4);
+ boost::random::piecewise_constant_distribution<> dist;
+ BOOST_CHECK_EQUAL((dist.min)(), 0.0);
+ BOOST_CHECK_EQUAL((dist.max)(), 1.0);
+ boost::random::piecewise_constant_distribution<> dist_r(intervals, weights);
+ BOOST_CHECK_EQUAL((dist_r.min)(), 0.0);
+ BOOST_CHECK_EQUAL((dist_r.max)(), 5.0);
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(1)(2)(1)(4);
+ boost::random::piecewise_constant_distribution<> dist;
+ boost::random::piecewise_constant_distribution<> dist_copy(dist);
+ boost::random::piecewise_constant_distribution<> dist_r(intervals, weights);
+ boost::random::piecewise_constant_distribution<> dist_r_copy(dist_r);
+ BOOST_CHECK(dist == dist_copy);
+ BOOST_CHECK(!(dist != dist_copy));
+ BOOST_CHECK(dist_r == dist_r_copy);
+ BOOST_CHECK(!(dist_r != dist_r_copy));
+ BOOST_CHECK(dist != dist_r);
+ BOOST_CHECK(!(dist == dist_r));
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(1)(2)(1)(4);
+ boost::random::piecewise_constant_distribution<> dist(intervals, weights);
+ std::stringstream stream;
+ stream << dist;
+ boost::random::piecewise_constant_distribution<> restored_dist;
+ stream >> restored_dist;
+ BOOST_CHECK_EQUAL(dist, restored_dist);
+}
+
+BOOST_AUTO_TEST_CASE(test_generation) {
+ std::vector<double> intervals = boost::assign::list_of(1)(2);
+ std::vector<double> weights = boost::assign::list_of(1);
+ boost::minstd_rand0 gen;
+ boost::random::piecewise_constant_distribution<> dist;
+ boost::random::piecewise_constant_distribution<> dist_r(intervals, weights);
+ for(int i = 0; i < 10; ++i) {
+ double value = dist(gen);
+ BOOST_CHECK_GE(value, 0.0);
+ BOOST_CHECK_LT(value, 1.0);
+ double value_r = dist_r(gen);
+ BOOST_CHECK_GE(value_r, 1.0);
+ BOOST_CHECK_LT(value_r, 2.0);
+ double value_param = dist_r(gen, dist.param());
+ BOOST_CHECK_GE(value_param, 0.0);
+ BOOST_CHECK_LT(value_param, 1.0);
+ double value_r_param = dist(gen, dist_r.param());
+ BOOST_CHECK_GE(value_r_param, 1.0);
+ BOOST_CHECK_LT(value_r_param, 2.0);
+ }
+}
diff --git a/libs/random/test/test_piecewise_linear.cpp b/libs/random/test/test_piecewise_linear.cpp
new file mode 100644
index 0000000000..8a3589fb02
--- /dev/null
+++ b/libs/random/test/test_piecewise_linear.cpp
@@ -0,0 +1,175 @@
+/* test_piecewise_linear.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: test_piecewise_linear.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/piecewise_linear_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/variate_generator.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/range/algorithm/lower_bound.hpp>
+#include <boost/range/numeric.hpp>
+#include <vector>
+#include <iostream>
+#include <iomanip>
+
+#include "statistic_tests.hpp"
+
+class piecewise_linear
+{
+public:
+ piecewise_linear(const std::vector<double>& intervals, const std::vector<double>& weights)
+ : intervals(intervals),
+ weights(weights),
+ cumulative(1, 0.0)
+ {
+ for(std::size_t i = 0; i < weights.size() - 1; ++i) {
+ cumulative.push_back((weights[i] + weights[i + 1]) / 2);
+ }
+ boost::partial_sum(cumulative, cumulative.begin());
+ double sum = cumulative.back();
+ for(std::vector<double>::iterator iter = cumulative.begin(), end = cumulative.end();
+ iter != end; ++iter)
+ {
+ *iter /= sum;
+ }
+ for(std::vector<double>::iterator iter = this->weights.begin(), end = this->weights.end();
+ iter != end; ++iter)
+ {
+ *iter /= sum;
+ }
+ assert(this->weights.size() == this->intervals.size());
+ assert(this->weights.size() == this->cumulative.size());
+ }
+
+ double cdf(double x) const
+ {
+ std::size_t index = boost::lower_bound(intervals, x) - intervals.begin();
+ if(index == 0) return 0;
+ else if(index == intervals.size()) return 1;
+ else {
+ double start = cumulative[index - 1];
+ double lower_weight = weights[index - 1];
+ double upper_weight = weights[index];
+ double lower = intervals[index - 1];
+ double upper = intervals[index];
+ double mid_weight = (lower_weight * (upper - x) + upper_weight * (x - lower)) / (upper - lower);
+ double segment_area = (x - lower) * (mid_weight + lower_weight) / 2;
+ return start + segment_area;
+ }
+ }
+private:
+ std::vector<double> intervals;
+ std::vector<double> weights;
+ std::vector<double> cumulative;
+};
+
+double cdf(const piecewise_linear& dist, double x)
+{
+ return dist.cdf(x);
+}
+
+bool do_test(int n, int max) {
+ std::cout << "running piecewise_linear(p0, p1, ..., p" << n-1 << ")" << " " << max << " times: " << std::flush;
+
+ std::vector<double> weights;
+ {
+ boost::mt19937 egen;
+ for(int i = 0; i < n; ++i) {
+ weights.push_back(egen());
+ }
+ }
+ std::vector<double> intervals;
+ for(int i = 0; i < n; ++i) {
+ intervals.push_back(i);
+ }
+
+ piecewise_linear expected(intervals, weights);
+
+ boost::random::piecewise_linear_distribution<> dist(intervals, weights);
+ boost::mt19937 gen;
+ kolmogorov_experiment test(max);
+ boost::variate_generator<boost::mt19937&, boost::random::piecewise_linear_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, int max_n, int trials) {
+ boost::mt19937 gen;
+ boost::uniform_int<> idist(2, max_n);
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(idist(gen), trials)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_piecewise_linear -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;
+ int max_n = 10;
+ 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, 'n', max_n)
+ && !handle_option(argc, argv, 't', trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat, max_n, trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/libs/random/test/test_piecewise_linear_distribution.cpp b/libs/random/test/test_piecewise_linear_distribution.cpp
new file mode 100644
index 0000000000..7818c694ce
--- /dev/null
+++ b/libs/random/test/test_piecewise_linear_distribution.cpp
@@ -0,0 +1,252 @@
+/* test_piecewise_linear_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: test_piecewise_linear_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/piecewise_linear_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/assign/list_of.hpp>
+#include <sstream>
+#include <vector>
+#include "concepts.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberDistribution;
+using boost::random::piecewise_linear_distribution;
+BOOST_CONCEPT_ASSERT((RandomNumberDistribution< piecewise_linear_distribution<> >));
+
+struct gen {
+ double operator()(double arg) {
+ if(arg < 97) return 100;
+ else if(arg < 101) return 3;
+ else if(arg < 105) return 1;
+ else if(arg < 109) return 2;
+ else if(arg < 113) return 1;
+ else if(arg < 117) return 5;
+ else return 100;
+ }
+};
+
+#define CHECK_SEQUENCE(actual, expected) \
+ do { \
+ std::vector<double> _actual = (actual); \
+ std::vector<double> _expected = (expected); \
+ BOOST_CHECK_EQUAL_COLLECTIONS( \
+ _actual.begin(), _actual.end(), \
+ _expected.begin(), _expected.end()); \
+ } while(false)
+
+using boost::assign::list_of;
+
+BOOST_AUTO_TEST_CASE(test_constructors) {
+ boost::random::piecewise_linear_distribution<> dist;
+ CHECK_SEQUENCE(dist.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist.densities(), list_of(1.0)(1.0));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::piecewise_linear_distribution<> dist_il = {
+ { 99, 103, 107, 111, 115 },
+ gen()
+ };
+ CHECK_SEQUENCE(dist_il.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(dist_il.densities(),
+ list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
+
+ boost::random::piecewise_linear_distribution<> dist_il2 = {
+ { 99 },
+ gen()
+ };
+ CHECK_SEQUENCE(dist_il2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_il2.densities(), list_of(1.0)(1.0));
+#endif
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
+ std::vector<double> intervals2 = boost::assign::list_of(99);
+ std::vector<double> weights2 = boost::assign::list_of(2);
+
+ boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
+ CHECK_SEQUENCE(dist_r.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(dist_r.densities(), list_of(.375)(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_linear_distribution<>
+ dist_r2(intervals2, weights2);
+ CHECK_SEQUENCE(dist_r2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_r2.densities(), list_of(1.0)(1.0));
+
+ boost::random::piecewise_linear_distribution<> dist_it(
+ intervals.begin(), intervals.end(), weights.begin());
+ CHECK_SEQUENCE(dist_it.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(dist_it.densities(), list_of(.375)(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_linear_distribution<> dist_it2(
+ intervals2.begin(), intervals2.end(), weights2.begin());
+ CHECK_SEQUENCE(dist_it2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(dist_it2.densities(), list_of(1.0)(1.0));
+
+ boost::random::piecewise_linear_distribution<> dist_fun(4, 99,115, gen());
+ CHECK_SEQUENCE(dist_fun.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(dist_fun.densities(),
+ list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
+
+ boost::random::piecewise_linear_distribution<>
+ dist_fun2(1, 99, 115, gen());
+ CHECK_SEQUENCE(dist_fun2.intervals(), list_of(99)(115));
+ CHECK_SEQUENCE(dist_fun2.densities(), list_of(0.046875)(0.078125));
+
+ boost::random::piecewise_linear_distribution<> copy(dist);
+ BOOST_CHECK_EQUAL(dist, copy);
+ boost::random::piecewise_linear_distribution<> copy_r(dist_r);
+ BOOST_CHECK_EQUAL(dist_r, copy_r);
+
+ boost::random::piecewise_linear_distribution<> notpow2(3, 99, 111, gen());
+ BOOST_REQUIRE_EQUAL(notpow2.densities().size(), 4u);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[0], 0.15, 1e-12);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[1], 0.05, 1e-12);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[2], 0.1, 1e-12);
+ BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[3], 0.05, 1e-12);
+ boost::random::piecewise_linear_distribution<> copy_notpow2(notpow2);
+ BOOST_CHECK_EQUAL(notpow2, copy_notpow2);
+}
+
+BOOST_AUTO_TEST_CASE(test_param) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
+ std::vector<double> intervals2 = boost::assign::list_of(99);
+ std::vector<double> weights2 = boost::assign::list_of(2);
+ boost::random::piecewise_linear_distribution<> dist(intervals, weights);
+ boost::random::piecewise_linear_distribution<>::param_type
+ param = dist.param();
+ CHECK_SEQUENCE(param.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(param.densities(), list_of(.375)(.125)(.25)(.125)(.25));
+ boost::random::piecewise_linear_distribution<> copy1(param);
+ BOOST_CHECK_EQUAL(dist, copy1);
+ boost::random::piecewise_linear_distribution<> copy2;
+ copy2.param(param);
+ BOOST_CHECK_EQUAL(dist, copy2);
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ param_copy = param;
+ BOOST_CHECK_EQUAL(param, param_copy);
+ BOOST_CHECK(param == param_copy);
+ BOOST_CHECK(!(param != param_copy));
+ boost::random::piecewise_linear_distribution<>::param_type param_default;
+ CHECK_SEQUENCE(param_default.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(param_default.densities(), list_of(1.0)(1.0));
+ BOOST_CHECK(param != param_default);
+ BOOST_CHECK(!(param == param_default));
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ boost::random::piecewise_linear_distribution<>::param_type parm_il = {
+ { 99, 103, 107, 111, 115 },
+ gen()
+ };
+ CHECK_SEQUENCE(parm_il.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(parm_il.densities(),
+ list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
+
+ boost::random::piecewise_linear_distribution<>::param_type parm_il2 = {
+ { 99 },
+ gen()
+ };
+ CHECK_SEQUENCE(parm_il2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_il2.densities(), list_of(1.0)(1.0));
+#endif
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_r(intervals, weights);
+ CHECK_SEQUENCE(parm_r.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(parm_r.densities(), list_of(.375)(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_r2(intervals2, weights2);
+ CHECK_SEQUENCE(parm_r2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_r2.densities(), list_of(1.0)(1.0));
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_it(intervals.begin(), intervals.end(), weights.begin());
+ CHECK_SEQUENCE(parm_it.intervals(), list_of(0)(1)(2)(3)(5));
+ CHECK_SEQUENCE(parm_it.densities(), list_of(.375)(.125)(.25)(.125)(.25));
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_it2(intervals2.begin(), intervals2.end(), weights2.begin());
+ CHECK_SEQUENCE(parm_it2.intervals(), list_of(0.0)(1.0));
+ CHECK_SEQUENCE(parm_it2.densities(), list_of(1.0)(1.0));
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_fun(4, 99, 115, gen());
+ CHECK_SEQUENCE(parm_fun.intervals(), list_of(99)(103)(107)(111)(115));
+ CHECK_SEQUENCE(parm_fun.densities(),
+ list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
+
+ boost::random::piecewise_linear_distribution<>::param_type
+ parm_fun2(1, 99, 115, gen());
+ CHECK_SEQUENCE(parm_fun2.intervals(), list_of(99)(115));
+ CHECK_SEQUENCE(parm_fun2.densities(), list_of(0.046875)(0.078125));
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
+ boost::random::piecewise_linear_distribution<> dist;
+ BOOST_CHECK_EQUAL((dist.min)(), 0.0);
+ BOOST_CHECK_EQUAL((dist.max)(), 1.0);
+ boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
+ BOOST_CHECK_EQUAL((dist_r.min)(), 0.0);
+ BOOST_CHECK_EQUAL((dist_r.max)(), 5.0);
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
+ boost::random::piecewise_linear_distribution<> dist;
+ boost::random::piecewise_linear_distribution<> dist_copy(dist);
+ boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
+ boost::random::piecewise_linear_distribution<> dist_r_copy(dist_r);
+ BOOST_CHECK(dist == dist_copy);
+ BOOST_CHECK(!(dist != dist_copy));
+ BOOST_CHECK(dist_r == dist_r_copy);
+ BOOST_CHECK(!(dist_r != dist_r_copy));
+ BOOST_CHECK(dist != dist_r);
+ BOOST_CHECK(!(dist == dist_r));
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming) {
+ std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
+ std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
+ boost::random::piecewise_linear_distribution<> dist(intervals, weights);
+ std::stringstream stream;
+ stream << dist;
+ boost::random::piecewise_linear_distribution<> restored_dist;
+ stream >> restored_dist;
+ BOOST_CHECK_EQUAL(dist, restored_dist);
+}
+
+BOOST_AUTO_TEST_CASE(test_generation) {
+ std::vector<double> intervals = boost::assign::list_of(1)(2);
+ std::vector<double> weights = boost::assign::list_of(1)(1);
+ boost::minstd_rand0 gen;
+ boost::random::piecewise_linear_distribution<> dist;
+ boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
+ for(int i = 0; i < 10; ++i) {
+ double value = dist(gen);
+ BOOST_CHECK_GE(value, 0.0);
+ BOOST_CHECK_LT(value, 1.0);
+ double value_r = dist_r(gen);
+ BOOST_CHECK_GE(value_r, 1.0);
+ BOOST_CHECK_LT(value_r, 2.0);
+ double value_param = dist_r(gen, dist.param());
+ BOOST_CHECK_GE(value_param, 0.0);
+ BOOST_CHECK_LT(value_param, 1.0);
+ double value_r_param = dist(gen, dist_r.param());
+ BOOST_CHECK_GE(value_r_param, 1.0);
+ BOOST_CHECK_LT(value_r_param, 2.0);
+ }
+}
diff --git a/libs/random/test/test_poisson.cpp b/libs/random/test/test_poisson.cpp
new file mode 100644
index 0000000000..576d0c381c
--- /dev/null
+++ b/libs/random/test/test_poisson.cpp
@@ -0,0 +1,25 @@
+/* test_poisson.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: test_poisson.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/poisson.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::poisson_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME poisson
+#define BOOST_MATH_DISTRIBUTION boost::math::poisson
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME mean
+#define BOOST_RANDOM_ARG1_DEFAULT 100000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(1e-15, n)
+#define BOOST_RANDOM_DISTRIBUTION_MAX static_cast<int>(mean * 4)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_poisson_distribution.cpp b/libs/random/test/test_poisson_distribution.cpp
new file mode 100644
index 0000000000..c8fd4421c9
--- /dev/null
+++ b/libs/random/test/test_poisson_distribution.cpp
@@ -0,0 +1,33 @@
+/* test_poisson_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: test_poisson_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/poisson_distribution.hpp>
+
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::poisson_distribution<>
+#define BOOST_RANDOM_ARG1 mean
+#define BOOST_RANDOM_ARG1_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE 7.5
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<int>::max)()
+#define BOOST_RANDOM_DIST1_MIN 0
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<int>::max)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+#define BOOST_RANDOM_TEST1_MIN 0.0
+#define BOOST_RANDOM_TEST1_MAX 10.0
+
+#define BOOST_RANDOM_TEST2_PARAMS (1000.0)
+#define BOOST_RANDOM_TEST2_MIN 10.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_rand48.cpp b/libs/random/test/test_rand48.cpp
new file mode 100644
index 0000000000..19f4f2322e
--- /dev/null
+++ b/libs/random/test/test_rand48.cpp
@@ -0,0 +1,26 @@
+/* test_rand48.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: test_rand48.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/linear_congruential.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::rand48
+
+#define BOOST_RANDOM_SEED_WORDS 2
+
+// by experiment from lrand48()
+#define BOOST_RANDOM_VALIDATION_VALUE 1993516219U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1286950069U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 839037874U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55424A4U, 0x3A2CCEF5U, 0x6ADB4A65U, 0x2B019719U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_random_device.cpp b/libs/random/test/test_random_device.cpp
new file mode 100644
index 0000000000..f526cfa67b
--- /dev/null
+++ b/libs/random/test/test_random_device.cpp
@@ -0,0 +1,29 @@
+/* boost random_test.cpp various tests
+ *
+ * Copyright (c) 2010 Steven Watanabe
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENCE_1_0.txt)
+ *
+ * $Id: test_random_device.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#include <boost/random/random_device.hpp>
+
+#include <boost/test/test_tools.hpp>
+#include <boost/test/included/test_exec_monitor.hpp>
+
+int test_main(int, char**) {
+ boost::random_device rng;
+ double entropy = rng.entropy();
+ BOOST_CHECK_GE(entropy, 0);
+ for(int i = 0; i < 100; ++i) {
+ boost::random_device::result_type val = rng();
+ BOOST_CHECK_GE(val, (rng.min)());
+ BOOST_CHECK_LE(val, (rng.max)());
+ }
+
+ boost::uint32_t a[10];
+ rng.generate(a, a + 10);
+ return 0;
+}
diff --git a/libs/random/test/test_random_number_generator.cpp b/libs/random/test/test_random_number_generator.cpp
new file mode 100644
index 0000000000..f76c5f24dc
--- /dev/null
+++ b/libs/random/test/test_random_number_generator.cpp
@@ -0,0 +1,33 @@
+/* boost test_random_number_generator.cpp
+ *
+ * Copyright Jens Maurer 2000
+ * 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: test_random_number_generator.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#include <boost/random/random_number_generator.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
+#include <algorithm>
+#include <vector>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_CASE(test_random_shuffle)
+{
+ boost::mt19937 engine(1234);
+ boost::random::random_number_generator<boost::mt19937> generator(engine);
+
+ std::vector<int> testVec;
+
+ for (int i = 0; i < 200; ++i) {
+ testVec.push_back(i);
+ }
+
+ std::random_shuffle(testVec.begin(), testVec.end(), generator);
+}
diff --git a/libs/random/test/test_ranlux24.cpp b/libs/random/test/test_ranlux24.cpp
new file mode 100644
index 0000000000..587e55e511
--- /dev/null
+++ b/libs/random/test/test_ranlux24.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux24.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: test_ranlux24.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux24
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// validation from the C++0x draft (n3090)
+#define BOOST_RANDOM_VALIDATION_VALUE 9901578U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 10086048U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3888733U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux24_base.cpp b/libs/random/test/test_ranlux24_base.cpp
new file mode 100644
index 0000000000..c63c91e671
--- /dev/null
+++ b/libs/random/test/test_ranlux24_base.cpp
@@ -0,0 +1,25 @@
+/* test_ranlux24_base.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: test_ranlux24_base.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux24_base
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// validation from the C++0x draft (n3126).
+#define BOOST_RANDOM_VALIDATION_VALUE 7937952U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 14368281U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 7739608U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux3.cpp b/libs/random/test/test_ranlux3.cpp
new file mode 100644
index 0000000000..3077e3db84
--- /dev/null
+++ b/libs/random/test/test_ranlux3.cpp
@@ -0,0 +1,25 @@
+/* test_ranlux3.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: test_ranlux3.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux3
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE 5957620U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 11848780U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 11620328U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux3_01.cpp b/libs/random/test/test_ranlux3_01.cpp
new file mode 100644
index 0000000000..b99d8bd985
--- /dev/null
+++ b/libs/random/test/test_ranlux3_01.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux3_01.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: test_ranlux3_01.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux3_01
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE 5957620/std::pow(2.0f,24)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 11848780/std::pow(2.0f,24)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 11620328/std::pow(2.0f,24)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux4.cpp b/libs/random/test/test_ranlux4.cpp
new file mode 100644
index 0000000000..5367f3ff19
--- /dev/null
+++ b/libs/random/test/test_ranlux4.cpp
@@ -0,0 +1,25 @@
+/* test_ranlux4.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: test_ranlux4.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux4
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE 8587295U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 10794046U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 4515722U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux48.cpp b/libs/random/test/test_ranlux48.cpp
new file mode 100644
index 0000000000..f169782e8e
--- /dev/null
+++ b/libs/random/test/test_ranlux48.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux48.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: test_ranlux48.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux48
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// validation from the C++0x draft (n3090)
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(249142670248501)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(130319672235788)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(154356577406237)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xFCE57B2CU, 0xF2DF1555U, 0x1A0C0CD9U, 0x490109FAU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux48_base.cpp b/libs/random/test/test_ranlux48_base.cpp
new file mode 100644
index 0000000000..055baa8f73
--- /dev/null
+++ b/libs/random/test/test_ranlux48_base.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux48_base.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: test_ranlux48_base.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux48_base
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// validation from the C++0x draft (n3126).
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(61839128582725)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(15556320400833)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(172853405006548)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xFCE57B2CU, 0xF2DF1555U, 0x1A0C0CD9U, 0x490109FAU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux4_01.cpp b/libs/random/test/test_ranlux4_01.cpp
new file mode 100644
index 0000000000..153046bb96
--- /dev/null
+++ b/libs/random/test/test_ranlux4_01.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux4_01.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: test_ranlux4_01.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux4_01
+
+#define BOOST_RANDOM_SEED_WORDS 24
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE 8587295/std::pow(2.0f,24)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 10794046/std::pow(2.0f,24)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 4515722/std::pow(2.0f,24)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux64_3.cpp b/libs/random/test/test_ranlux64_3.cpp
new file mode 100644
index 0000000000..8feda0da65
--- /dev/null
+++ b/libs/random/test/test_ranlux64_3.cpp
@@ -0,0 +1,27 @@
+/* test_ranlux64_3.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: test_ranlux64_3.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <boost/cstdint.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux64_3
+
+#define BOOST_RANDOM_SEED_WORDS 48
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(141789170949364)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(85538657982635)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(101724473226966)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux64_3_01.cpp b/libs/random/test/test_ranlux64_3_01.cpp
new file mode 100644
index 0000000000..ce16037467
--- /dev/null
+++ b/libs/random/test/test_ranlux64_3_01.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux64_3_01.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: test_ranlux64_3_01.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux64_3_01
+
+#define BOOST_RANDOM_SEED_WORDS 48
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE INT64_C(141789170949364)/std::pow(2.0, 48)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(85538657982635)/std::pow(2.0, 48)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(101724473226966)/std::pow(2.0, 48)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux64_4.cpp b/libs/random/test/test_ranlux64_4.cpp
new file mode 100644
index 0000000000..cd0c51ed8b
--- /dev/null
+++ b/libs/random/test/test_ranlux64_4.cpp
@@ -0,0 +1,27 @@
+/* test_ranlux64_4.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: test_ranlux64_4.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <boost/cstdint.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux64_4
+
+#define BOOST_RANDOM_SEED_WORDS 48
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(199461971133682)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(160535400540538)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(40074210927900)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_ranlux64_4_01.cpp b/libs/random/test/test_ranlux64_4_01.cpp
new file mode 100644
index 0000000000..d40088ef62
--- /dev/null
+++ b/libs/random/test/test_ranlux64_4_01.cpp
@@ -0,0 +1,26 @@
+/* test_ranlux64_4_01.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: test_ranlux64_4_01.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/ranlux.hpp>
+#include <cmath>
+
+#define BOOST_RANDOM_URNG boost::random::ranlux64_4_01
+
+#define BOOST_RANDOM_SEED_WORDS 48
+
+// principal operation validated with CLHEP, values by experiment
+#define BOOST_RANDOM_VALIDATION_VALUE INT64_C(199461971133682)/std::pow(2.0, 48)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(160535400540538)/std::pow(2.0, 48)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(40074210927900)/std::pow(2.0, 48)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_real_distribution.ipp b/libs/random/test/test_real_distribution.ipp
new file mode 100644
index 0000000000..acba625a71
--- /dev/null
+++ b/libs/random/test/test_real_distribution.ipp
@@ -0,0 +1,195 @@
+/* test_real_distribution.ipp
+ *
+ * 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: test_real_distribution.ipp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#ifndef BOOST_MATH_DISTRIBUTION_INIT
+#ifdef BOOST_RANDOM_ARG2_TYPE
+#define BOOST_MATH_DISTRIBUTION_INIT (BOOST_RANDOM_ARG1_NAME, BOOST_RANDOM_ARG2_NAME)
+#else
+#define BOOST_MATH_DISTRIBUTION_INIT (BOOST_RANDOM_ARG1_NAME)
+#endif
+#endif
+
+#ifndef BOOST_RANDOM_DISTRIBUTION_INIT
+#ifdef BOOST_RANDOM_ARG2_TYPE
+#define BOOST_RANDOM_DISTRIBUTION_INIT (BOOST_RANDOM_ARG1_NAME, BOOST_RANDOM_ARG2_NAME)
+#else
+#define BOOST_RANDOM_DISTRIBUTION_INIT (BOOST_RANDOM_ARG1_NAME)
+#endif
+#endif
+
+#ifndef BOOST_RANDOM_P_CUTOFF
+#define BOOST_RANDOM_P_CUTOFF 0.99
+#endif
+
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/range/numeric.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <iostream>
+#include <vector>
+
+#include "statistic_tests.hpp"
+#include "chi_squared_test.hpp"
+
+bool do_test(BOOST_RANDOM_ARG1_TYPE BOOST_RANDOM_ARG1_NAME,
+#ifdef BOOST_RANDOM_ARG2_TYPE
+ BOOST_RANDOM_ARG2_TYPE BOOST_RANDOM_ARG2_NAME,
+#endif
+ long long max, boost::mt19937& gen) {
+ std::cout << "running " BOOST_PP_STRINGIZE(BOOST_RANDOM_DISTRIBUTION_NAME) "("
+ << BOOST_RANDOM_ARG1_NAME;
+#ifdef BOOST_RANDOM_ARG2_NAME
+ std::cout << ", " << BOOST_RANDOM_ARG2_NAME;
+#endif
+ std::cout << ")" << " " << max << " times: " << std::flush;
+
+ BOOST_MATH_DISTRIBUTION expected BOOST_MATH_DISTRIBUTION_INIT;
+
+ BOOST_RANDOM_DISTRIBUTION dist BOOST_RANDOM_DISTRIBUTION_INIT;
+
+#ifdef BOOST_RANDOM_DISTRIBUTION_MAX
+
+ BOOST_RANDOM_DISTRIBUTION::result_type max_value = BOOST_RANDOM_DISTRIBUTION_MAX;
+
+ std::vector<double> expected_pdf(max_value+1);
+ {
+ for(int i = 0; i <= max_value; ++i) {
+ expected_pdf[i] = pdf(expected, i);
+ }
+ expected_pdf.back() += 1 - boost::accumulate(expected_pdf, 0.0);
+ }
+
+ std::vector<long long> results(max_value + 1);
+ for(long long i = 0; i < max; ++i) {
+ ++results[(std::min)(dist(gen), max_value)];
+ }
+
+ long long sum = boost::accumulate(results, 0ll);
+ if(sum != max) {
+ std::cout << "*** Failed: incorrect total: " << sum << " ***" << std::endl;
+ return false;
+ }
+ double prob = chi_squared_test(results, expected_pdf, max);
+
+#else
+
+ kolmogorov_experiment test(boost::numeric_cast<int>(max));
+ boost::variate_generator<boost::mt19937&, BOOST_RANDOM_DISTRIBUTION > vgen(gen, dist);
+
+ double prob = test.probability(test.run(vgen, expected));
+
+#endif
+
+ bool result = prob < BOOST_RANDOM_P_CUTOFF;
+ const char* err = result? "" : "*";
+ std::cout << std::setprecision(17) << prob << err << std::endl;
+
+ std::cout << std::setprecision(6);
+
+ return result;
+}
+
+template<class Dist1
+#ifdef BOOST_RANDOM_ARG2_NAME
+ , class Dist2
+#endif
+>
+bool do_tests(int repeat, Dist1 d1,
+#ifdef BOOST_RANDOM_ARG2_NAME
+ Dist2 d2,
+#endif
+ long long trials) {
+ boost::mt19937 gen;
+ int errors = 0;
+ for(int i = 0; i < repeat; ++i) {
+ if(!do_test(d1(gen),
+#ifdef BOOST_RANDOM_ARG2_NAME
+ d2(gen),
+#endif
+ trials, gen)) {
+ ++errors;
+ }
+ }
+ if(errors != 0) {
+ std::cout << "*** " << errors << " errors detected ***" << std::endl;
+ }
+ return errors == 0;
+}
+
+int usage() {
+ std::cerr << "Usage: test_" BOOST_PP_STRINGIZE(BOOST_RANDOM_DISTRIBUTION_NAME)
+ " -r <repeat>"
+ " -" BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG1_NAME)
+ " <max " BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG1_NAME) ">"
+#ifdef BOOST_RANDOM_ARG2_NAME
+ " -" BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG2_NAME)
+ " <max " BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG2_NAME) ">"
+#endif
+ " -t <trials>" << std::endl;
+ return 2;
+}
+
+template<class T>
+bool handle_option(int& argc, char**& argv, const char* opt, T& value) {
+ if(std::strcmp(argv[0], opt) == 0 && argc > 1) {
+ --argc;
+ ++argv;
+ value = boost::lexical_cast<T>(argv[0]);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int main(int argc, char** argv) {
+ int repeat = 1;
+ BOOST_RANDOM_ARG1_TYPE max_arg1 = BOOST_RANDOM_ARG1_DEFAULT;
+#ifdef BOOST_RANDOM_ARG2_TYPE
+ BOOST_RANDOM_ARG2_TYPE max_arg2 = BOOST_RANDOM_ARG2_DEFAULT;
+#endif
+ long long trials = 100000;
+
+ 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, "-" BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG1_NAME), max_arg1)
+#ifdef BOOST_RANDOM_ARG2_TYPE
+ && !handle_option(argc, argv, "-" BOOST_PP_STRINGIZE(BOOST_RANDOM_ARG2_NAME), max_arg2)
+#endif
+ && !handle_option(argc, argv, "-t", trials)) {
+ return usage();
+ }
+ --argc;
+ ++argv;
+ }
+
+ try {
+ if(do_tests(repeat,
+ BOOST_RANDOM_ARG1_DISTRIBUTION(max_arg1),
+#ifdef BOOST_RANDOM_ARG2_TYPE
+ BOOST_RANDOM_ARG2_DISTRIBUTION(max_arg2),
+#endif
+ trials)) {
+ return 0;
+ } else {
+ return EXIT_FAILURE;
+ }
+ } catch(...) {
+ std::cerr << boost::current_exception_diagnostic_information() << std::endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/libs/random/test/test_seed_seq.cpp b/libs/random/test/test_seed_seq.cpp
new file mode 100644
index 0000000000..c14593062f
--- /dev/null
+++ b/libs/random/test/test_seed_seq.cpp
@@ -0,0 +1,113 @@
+/* boost test_seed_seq.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: test_seed_seq.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ */
+
+#include <boost/random/seed_seq.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/config.hpp>
+#include <vector>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::assign::list_of;
+
+BOOST_AUTO_TEST_CASE(test_seed_seq) {
+ boost::uint32_t expected_param[4] = { 2, 3, 4, 0xdeadbeaf };
+ boost::uint32_t param[4] = { 2, 3, 4, 0xdeadbeaf };
+ boost::uint32_t store32[10];
+ boost::uint64_t store64[10];
+ boost::uint32_t expected[10] = {
+ 3155793538u,
+ 2047427591u,
+ 2886057794u,
+ 280666868u,
+ 2184015838u,
+ 4035763234u,
+ 808987374u,
+ 3177165994u,
+ 2993445429u,
+ 3110180644u
+ };
+ std::fill_n(&store32[0], 10, 0);
+ std::fill_n(&store64[0], 10, 0);
+ boost::random::seed_seq seq;
+ seq.generate(&store32[0], &store32[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store32[0], &store32[0] + 10, &expected[0], &expected[0] + 10);
+ seq.generate(&store64[0], &store64[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store64[0], &store64[0] + 10, &expected[0], &expected[0] + 10);
+ BOOST_CHECK_EQUAL(seq.size(), 0u);
+ seq.param(&param[0]);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &param[0], &param[0] + 4, &expected_param[0], &expected_param[0] + 4);
+
+ boost::uint32_t expected_r[10] = {
+ 2681148375u,
+ 3302224839u,
+ 249244011u,
+ 1549723892u,
+ 3429166360u,
+ 2812310274u,
+ 3902694127u,
+ 1014283089u,
+ 1122383019u,
+ 494552679u
+ };
+
+ std::vector<int> data = list_of(2)(3)(4);
+
+ std::fill_n(&store32[0], 10, 0);
+ std::fill_n(&store64[0], 10, 0);
+ std::fill_n(&param[0], 3, 0);
+ boost::random::seed_seq seq_r(data);
+ seq_r.generate(&store32[0], &store32[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store32[0], &store32[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ seq_r.generate(&store64[0], &store64[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store64[0], &store64[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ BOOST_CHECK_EQUAL(seq_r.size(), 3u);
+ seq_r.param(&param[0]);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &param[0], &param[0] + 4, &expected_param[0], &expected_param[0] + 4);
+
+ std::fill_n(&store32[0], 10, 0);
+ std::fill_n(&store64[0], 10, 0);
+ std::fill_n(&param[0], 3, 0);
+ boost::random::seed_seq seq_it(data.begin(), data.end());
+ seq_it.generate(&store32[0], &store32[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store32[0], &store32[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ seq_it.generate(&store64[0], &store64[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store64[0], &store64[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ BOOST_CHECK_EQUAL(seq_it.size(), 3u);
+ seq_it.param(&param[0]);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &param[0], &param[0] + 4, &expected_param[0], &expected_param[0] + 4);
+
+#ifndef BOOST_NO_INITIALIZER_LISTS
+ std::fill_n(&store32[0], 10, 0);
+ std::fill_n(&store64[0], 10, 0);
+ std::fill_n(&param[0], 3, 0);
+ boost::random::seed_seq seq_il = {2, 3, 4};
+ seq_il.generate(&store32[0], &store32[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store32[0], &store32[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ seq_il.generate(&store64[0], &store64[0] + 10);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &store64[0], &store64[0] + 10, &expected_r[0], &expected_r[0] + 10);
+ BOOST_CHECK_EQUAL(seq_il.size(), 3u);
+ seq_il.param(&param[0]);
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ &param[0], &param[0] + 4, &expected_param[0], &expected_param[0] + 4);
+#endif
+}
diff --git a/libs/random/test/test_student_t.cpp b/libs/random/test/test_student_t.cpp
new file mode 100644
index 0000000000..09385257bb
--- /dev/null
+++ b/libs/random/test/test_student_t.cpp
@@ -0,0 +1,24 @@
+/* test_student_t.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: test_student_t.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/student_t_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/students_t.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::student_t_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME student_t
+#define BOOST_MATH_DISTRIBUTION boost::math::students_t
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME n
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_student_t_distribution.cpp b/libs/random/test/test_student_t_distribution.cpp
new file mode 100644
index 0000000000..7ab6437d10
--- /dev/null
+++ b/libs/random/test/test_student_t_distribution.cpp
@@ -0,0 +1,29 @@
+/* test_student_t_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: test_student_t_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/student_t_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::student_t_distribution<>
+#define BOOST_RANDOM_ARG1 n
+#define BOOST_RANDOM_ARG1_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE 7.5
+
+#define BOOST_RANDOM_DIST0_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MIN -(std::numeric_limits<double>::infinity)()
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<double>::infinity)()
+
+#define BOOST_RANDOM_TEST1_PARAMS
+
+#define BOOST_RANDOM_TEST2_PARAMS (100.0)
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_taus88.cpp b/libs/random/test/test_taus88.cpp
new file mode 100644
index 0000000000..b7f3258f82
--- /dev/null
+++ b/libs/random/test/test_taus88.cpp
@@ -0,0 +1,24 @@
+/* test_taus88.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: test_taus88.cpp 74867 2011-10-09 23:13:31Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/taus88.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::taus88
+
+#define BOOST_RANDOM_SEED_WORDS 3
+
+#define BOOST_RANDOM_VALIDATION_VALUE 3535848941U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 2562639222U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3762466828U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x2B55504U, 0x5403F102U, 0xED45297EU, 0x6B84007U }
+
+#include "test_generator.ipp"
diff --git a/libs/random/test/test_triangle.cpp b/libs/random/test/test_triangle.cpp
new file mode 100644
index 0000000000..04d0b6dda6
--- /dev/null
+++ b/libs/random/test/test_triangle.cpp
@@ -0,0 +1,26 @@
+/* test_triangle.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: test_triangle.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/triangular.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::triangle_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME lognormal
+#define BOOST_MATH_DISTRIBUTION boost::math::triangular
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 0.5
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.0001, 0.9999)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0.0, b, 1.0)
+#define BOOST_MATH_DISTRIBUTION_INIT (0.0, b, 1.0)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_triangle_distribution.cpp b/libs/random/test/test_triangle_distribution.cpp
new file mode 100644
index 0000000000..6f745357c4
--- /dev/null
+++ b/libs/random/test/test_triangle_distribution.cpp
@@ -0,0 +1,41 @@
+/* test_triangle_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: test_triangle_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/triangle_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::triangle_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG3 c
+#define BOOST_RANDOM_ARG1_DEFAULT 0.0
+#define BOOST_RANDOM_ARG2_DEFAULT 0.5
+#define BOOST_RANDOM_ARG3_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE -0.5
+#define BOOST_RANDOM_ARG2_VALUE 0.25
+#define BOOST_RANDOM_ARG3_VALUE 1.5
+
+#define BOOST_RANDOM_DIST0_MIN 0.0
+#define BOOST_RANDOM_DIST0_MAX 1.0
+#define BOOST_RANDOM_DIST1_MIN -0.5
+#define BOOST_RANDOM_DIST1_MAX 1.0
+#define BOOST_RANDOM_DIST2_MIN -0.5
+#define BOOST_RANDOM_DIST2_MAX 1.0
+#define BOOST_RANDOM_DIST3_MIN -0.5
+#define BOOST_RANDOM_DIST3_MAX 1.5
+
+#define BOOST_RANDOM_TEST1_PARAMS (-1, -0.5, 0)
+#define BOOST_RANDOM_TEST1_MAX 0
+
+#define BOOST_RANDOM_TEST2_PARAMS (0, 0.5, 1)
+#define BOOST_RANDOM_TEST2_MIN 0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_uniform_int.cpp b/libs/random/test/test_uniform_int.cpp
new file mode 100644
index 0000000000..6b270fdce8
--- /dev/null
+++ b/libs/random/test/test_uniform_int.cpp
@@ -0,0 +1,27 @@
+/* test_uniform_int.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: test_uniform_int.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/math/distributions/uniform.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_int_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME uniform_int
+#define BOOST_MATH_DISTRIBUTION boost::math::uniform
+#define BOOST_RANDOM_ARG1_TYPE int
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 1000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_int<>(0, n)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0, b)
+#define BOOST_MATH_DISTRIBUTION_INIT (0, b+1)
+#define BOOST_RANDOM_DISTRIBUTION_MAX b
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_uniform_int.ipp b/libs/random/test/test_uniform_int.ipp
new file mode 100644
index 0000000000..bb84c0f6a5
--- /dev/null
+++ b/libs/random/test/test_uniform_int.ipp
@@ -0,0 +1,149 @@
+/* boost test_uniform_int.ipp
+ *
+ * Copyright Jens Maurer 2000
+ * 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: test_uniform_int.ipp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#include <numeric>
+#include <sstream>
+#include <vector>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/limits.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/random/variate_generator.hpp>
+#include "chi_squared_test.hpp"
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+template<class Generator>
+void check_uniform_int(Generator & gen, int iter)
+{
+ int range = (gen.max)()-(gen.min)()+1;
+ std::vector<int> bucket(range);
+ for(int j = 0; j < iter; j++) {
+ int result = gen();
+ BOOST_CHECK_GE(result, (gen.min)());
+ BOOST_CHECK_LE(result, (gen.max)());
+ if(result >= (gen.min)() && result <= (gen.max)()) {
+ bucket[result-(gen.min)()]++;
+ }
+ }
+ int sum = std::accumulate(bucket.begin(), bucket.end(), 0);
+ std::vector<double> expected(range, 1.0 / range);
+ BOOST_CHECK_LT(chi_squared_test(bucket, expected, sum), 0.99);
+}
+
+BOOST_AUTO_TEST_CASE(test_uniform_int)
+{
+ boost::random::mt19937 gen;
+ typedef BOOST_RANDOM_UNIFORM_INT<int> int_gen;
+
+ // large range => small range (modulo case)
+ typedef boost::random::variate_generator<boost::random::mt19937&, int_gen> level_one;
+
+ level_one uint12(gen, int_gen(1,2));
+ BOOST_CHECK((uint12.distribution().min)() == 1);
+ BOOST_CHECK((uint12.distribution().max)() == 2);
+ check_uniform_int(uint12, 100000);
+ level_one uint16(gen, int_gen(1,6));
+ check_uniform_int(uint16, 100000);
+
+ // test chaining to get all cases in operator()
+
+ // identity map
+ typedef boost::random::variate_generator<level_one&, int_gen> level_two;
+ level_two uint01(uint12, int_gen(0, 1));
+ check_uniform_int(uint01, 100000);
+
+ // small range => larger range
+ level_two uint05(uint12, int_gen(-3, 2));
+ check_uniform_int(uint05, 100000);
+
+ // small range => larger range
+ level_two uint099(uint12, int_gen(0, 99));
+ check_uniform_int(uint099, 100000);
+
+ // larger => small range, rejection case
+ typedef boost::random::variate_generator<level_two&, int_gen> level_three;
+ level_three uint1_4(uint05, int_gen(1, 4));
+ check_uniform_int(uint1_4, 100000);
+
+ typedef BOOST_RANDOM_UNIFORM_INT<boost::uint8_t> int8_gen;
+ typedef boost::random::variate_generator<boost::random::mt19937&, int8_gen> gen8_t;
+
+ gen8_t gen8_03(gen, int8_gen(0, 3));
+
+ // use the full range of the type, where the destination
+ // range is a power of the source range
+ typedef boost::random::variate_generator<gen8_t, int8_gen> uniform_uint8;
+ uniform_uint8 uint8_0255(gen8_03, int8_gen(0, 255));
+ check_uniform_int(uint8_0255, 100000);
+
+ // use the full range, but a generator whose range is not
+ // a root of the destination range.
+ gen8_t gen8_02(gen, int8_gen(0, 2));
+ uniform_uint8 uint8_0255_2(gen8_02, int8_gen(0, 255));
+ check_uniform_int(uint8_0255_2, 100000);
+
+ // expand the range to a larger type.
+ typedef boost::random::variate_generator<gen8_t, int_gen> uniform_uint_from8;
+ uniform_uint_from8 uint0300(gen8_03, int_gen(0, 300));
+ check_uniform_int(uint0300, 100000);
+}
+
+#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+
+// testcase by Mario Rutti
+class ruetti_gen
+{
+public:
+ ruetti_gen() : state((max)() - 1) {}
+ typedef boost::uint64_t result_type;
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<result_type>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }
+ result_type operator()() { return state--; }
+private:
+ result_type state;
+};
+
+BOOST_AUTO_TEST_CASE(test_overflow_range)
+{
+ ruetti_gen gen;
+ BOOST_RANDOM_DISTRIBUTION dist(0, 10);
+ for (int i=0;i<10;i++) {
+ dist(gen);
+ }
+}
+
+#endif
+
+BOOST_AUTO_TEST_CASE(test_misc)
+{
+ // bug report from Ken Mahler: This used to lead to an endless loop.
+ typedef BOOST_RANDOM_UNIFORM_INT<unsigned int> uint_dist;
+ boost::minstd_rand mr;
+ boost::variate_generator<boost::minstd_rand, uint_dist> r2(mr,
+ uint_dist(0, 0xffffffff));
+ r2();
+ r2();
+
+ // bug report from Fernando Cacciola: This used to lead to an endless loop.
+ // also from Douglas Gregor
+ boost::variate_generator<boost::minstd_rand, BOOST_RANDOM_DISTRIBUTION > x(mr, BOOST_RANDOM_DISTRIBUTION(0, 8361));
+ x();
+
+ // bug report from Alan Stokes and others: this throws an assertion
+ boost::variate_generator<boost::minstd_rand, BOOST_RANDOM_DISTRIBUTION > y(mr, BOOST_RANDOM_DISTRIBUTION(1,1));
+ y();
+ y();
+ y();
+}
diff --git a/libs/random/test/test_uniform_int_distribution.cpp b/libs/random/test/test_uniform_int_distribution.cpp
new file mode 100644
index 0000000000..35a345538a
--- /dev/null
+++ b/libs/random/test/test_uniform_int_distribution.cpp
@@ -0,0 +1,42 @@
+/* test_uniform_int_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: test_uniform_int_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_int_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_int_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 0
+#define BOOST_RANDOM_ARG2_DEFAULT 0x7fffffff
+#define BOOST_RANDOM_ARG1_VALUE 100
+#define BOOST_RANDOM_ARG2_VALUE 250
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX 0x7fffffff
+#define BOOST_RANDOM_DIST1_MIN 100
+#define BOOST_RANDOM_DIST1_MAX 0x7fffffff
+#define BOOST_RANDOM_DIST2_MIN 100
+#define BOOST_RANDOM_DIST2_MAX 250
+
+#define BOOST_RANDOM_TEST1_PARAMS (0, 9)
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 9
+
+#define BOOST_RANDOM_TEST2_PARAMS (10, 19)
+#define BOOST_RANDOM_TEST2_MIN 10
+#define BOOST_RANDOM_TEST2_MAX 19
+
+#include "test_distribution.ipp"
+
+#define BOOST_RANDOM_UNIFORM_INT boost::random::uniform_int_distribution
+
+#include "test_uniform_int.ipp"
diff --git a/libs/random/test/test_uniform_on_sphere_distribution.cpp b/libs/random/test/test_uniform_on_sphere_distribution.cpp
new file mode 100644
index 0000000000..4682de636b
--- /dev/null
+++ b/libs/random/test/test_uniform_on_sphere_distribution.cpp
@@ -0,0 +1,43 @@
+/* test_uniform_on_sphere_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: test_uniform_on_sphere_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/assign/list_of.hpp>
+
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_on_sphere<>
+#define BOOST_RANDOM_ARG1 dim
+#define BOOST_RANDOM_ARG1_DEFAULT 2
+#define BOOST_RANDOM_ARG1_VALUE 3
+
+std::vector<double> min0 = boost::assign::list_of(-1.0)(0.0);
+std::vector<double> max0 = boost::assign::list_of(1.0)(0.0);
+std::vector<double> min1 = boost::assign::list_of(-1.0)(0.0)(0.0);
+std::vector<double> max1 = boost::assign::list_of(1.0)(0.0)(0.0);
+
+#define BOOST_RANDOM_DIST0_MIN min0
+#define BOOST_RANDOM_DIST0_MAX max0
+#define BOOST_RANDOM_DIST1_MIN min1
+#define BOOST_RANDOM_DIST1_MAX max1
+
+#define BOOST_RANDOM_TEST1_PARAMS (0)
+#define BOOST_RANDOM_TEST1_MIN std::vector<double>()
+#define BOOST_RANDOM_TEST1_MAX std::vector<double>()
+#define BOOST_RANDOM_TEST2_PARAMS
+#define BOOST_RANDOM_TEST2_MIN min0
+#define BOOST_RANDOM_TEST2_MAX max0
+
+#include <boost/test/test_tools.hpp>
+
+BOOST_TEST_DONT_PRINT_LOG_VALUE( std::vector<double> )
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_uniform_real.cpp b/libs/random/test/test_uniform_real.cpp
new file mode 100644
index 0000000000..71ac6625aa
--- /dev/null
+++ b/libs/random/test/test_uniform_real.cpp
@@ -0,0 +1,26 @@
+/* test_uniform_real.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: test_uniform_real.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_real_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/uniform.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_real_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME uniform_int
+#define BOOST_MATH_DISTRIBUTION boost::math::uniform
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 1000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0, n)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0, b)
+#define BOOST_MATH_DISTRIBUTION_INIT (0, b)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_uniform_real_distribution.cpp b/libs/random/test/test_uniform_real_distribution.cpp
new file mode 100644
index 0000000000..47312bafac
--- /dev/null
+++ b/libs/random/test/test_uniform_real_distribution.cpp
@@ -0,0 +1,38 @@
+/* test_uniform_real_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: test_uniform_real_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_real_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_real_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 0.0
+#define BOOST_RANDOM_ARG2_DEFAULT 1.0
+#define BOOST_RANDOM_ARG1_VALUE -0.5
+#define BOOST_RANDOM_ARG2_VALUE 1.5
+
+#define BOOST_RANDOM_DIST0_MIN 0.0
+#define BOOST_RANDOM_DIST0_MAX 1.0
+#define BOOST_RANDOM_DIST1_MIN -0.5
+#define BOOST_RANDOM_DIST1_MAX 1.0
+#define BOOST_RANDOM_DIST2_MIN -0.5
+#define BOOST_RANDOM_DIST2_MAX 1.5
+
+#define BOOST_RANDOM_TEST1_PARAMS (-1.0, 0.0)
+#define BOOST_RANDOM_TEST1_MIN -1.0
+#define BOOST_RANDOM_TEST1_MAX 0.0
+
+#define BOOST_RANDOM_TEST2_PARAMS
+#define BOOST_RANDOM_TEST2_MIN 0.0
+#define BOOST_RANDOM_TEST2_MAX 1.0
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_uniform_smallint.cpp b/libs/random/test/test_uniform_smallint.cpp
new file mode 100644
index 0000000000..d855f0906c
--- /dev/null
+++ b/libs/random/test/test_uniform_smallint.cpp
@@ -0,0 +1,27 @@
+/* test_uniform_smallint.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: test_uniform_smallint.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_smallint.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/math/distributions/uniform.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_smallint<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME uniform_int
+#define BOOST_MATH_DISTRIBUTION boost::math::uniform
+#define BOOST_RANDOM_ARG1_TYPE int
+#define BOOST_RANDOM_ARG1_NAME b
+#define BOOST_RANDOM_ARG1_DEFAULT 1000
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_int<>(0, n)
+#define BOOST_RANDOM_DISTRIBUTION_INIT (0, b)
+#define BOOST_MATH_DISTRIBUTION_INIT (0, b+1)
+#define BOOST_RANDOM_DISTRIBUTION_MAX b
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_uniform_smallint_distribution.cpp b/libs/random/test/test_uniform_smallint_distribution.cpp
new file mode 100644
index 0000000000..e20cf4ece3
--- /dev/null
+++ b/libs/random/test/test_uniform_smallint_distribution.cpp
@@ -0,0 +1,38 @@
+/* test_uniform_smallint_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: test_uniform_smallint_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/uniform_smallint.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_smallint<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 0
+#define BOOST_RANDOM_ARG2_DEFAULT 9
+#define BOOST_RANDOM_ARG1_VALUE 5
+#define BOOST_RANDOM_ARG2_VALUE 250
+
+#define BOOST_RANDOM_DIST0_MIN 0
+#define BOOST_RANDOM_DIST0_MAX 9
+#define BOOST_RANDOM_DIST1_MIN 5
+#define BOOST_RANDOM_DIST1_MAX 9
+#define BOOST_RANDOM_DIST2_MIN 5
+#define BOOST_RANDOM_DIST2_MAX 250
+
+#define BOOST_RANDOM_TEST1_PARAMS (0, 9)
+#define BOOST_RANDOM_TEST1_MIN 0
+#define BOOST_RANDOM_TEST1_MAX 9
+
+#define BOOST_RANDOM_TEST2_PARAMS (10, 19)
+#define BOOST_RANDOM_TEST2_MIN 10
+#define BOOST_RANDOM_TEST2_MAX 19
+
+#include "test_distribution.ipp"
diff --git a/libs/random/test/test_weibull.cpp b/libs/random/test/test_weibull.cpp
new file mode 100644
index 0000000000..5fbb616dea
--- /dev/null
+++ b/libs/random/test/test_weibull.cpp
@@ -0,0 +1,28 @@
+/* test_weibull.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: test_weibull.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+
+#include <boost/random/weibull_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/math/distributions/weibull.hpp>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::weibull_distribution<>
+#define BOOST_RANDOM_DISTRIBUTION_NAME weibull
+#define BOOST_MATH_DISTRIBUTION boost::math::weibull
+#define BOOST_RANDOM_ARG1_TYPE double
+#define BOOST_RANDOM_ARG1_NAME a
+#define BOOST_RANDOM_ARG1_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG1_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+#define BOOST_RANDOM_ARG2_TYPE double
+#define BOOST_RANDOM_ARG2_NAME b
+#define BOOST_RANDOM_ARG2_DEFAULT 1000.0
+#define BOOST_RANDOM_ARG2_DISTRIBUTION(n) boost::uniform_real<>(0.00001, n)
+
+#include "test_real_distribution.ipp"
diff --git a/libs/random/test/test_weibull_distribution.cpp b/libs/random/test/test_weibull_distribution.cpp
new file mode 100644
index 0000000000..0465e02ad4
--- /dev/null
+++ b/libs/random/test/test_weibull_distribution.cpp
@@ -0,0 +1,36 @@
+/* test_weibull_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: test_weibull_distribution.cpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ */
+#include <boost/random/weibull_distribution.hpp>
+#include <limits>
+
+#define BOOST_RANDOM_DISTRIBUTION boost::random::weibull_distribution<>
+#define BOOST_RANDOM_ARG1 a
+#define BOOST_RANDOM_ARG2 b
+#define BOOST_RANDOM_ARG1_DEFAULT 1.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
+#define BOOST_RANDOM_TEST1_MIN 0.0
+#define BOOST_RANDOM_TEST1_MAX 100.0
+
+#define BOOST_RANDOM_TEST2_PARAMS (1.0, 1000000.0)
+#define BOOST_RANDOM_TEST2_MIN 100.0
+
+#include "test_distribution.ipp"