diff options
Diffstat (limited to 'libs/random/test')
101 files changed, 6780 insertions, 0 deletions
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(¶m[0]); + BOOST_CHECK_EQUAL_COLLECTIONS( + ¶m[0], ¶m[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(¶m[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(¶m[0]); + BOOST_CHECK_EQUAL_COLLECTIONS( + ¶m[0], ¶m[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(¶m[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(¶m[0]); + BOOST_CHECK_EQUAL_COLLECTIONS( + ¶m[0], ¶m[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(¶m[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(¶m[0]); + BOOST_CHECK_EQUAL_COLLECTIONS( + ¶m[0], ¶m[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" |