|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r71018 - in branches/release: . boost boost/algorithm/string boost/archive boost/bimap boost/config boost/date_time boost/date_time/posix_time boost/detail boost/filesystem boost/function boost/functional boost/functional/hash boost/fusion boost/fusion/container/list/detail boost/geometry boost/geometry/algorithms boost/geometry/arithmetic boost/geometry/core boost/geometry/domains boost/geometry/geometries boost/geometry/iterators boost/geometry/multi boost/geometry/policies boost/geometry/ranges boost/geometry/strategies boost/geometry/util boost/geometry/views boost/gil boost/graph boost/icl boost/integer boost/interprocess boost/intrusive boost/io boost/iostreams boost/iterator boost/math boost/msm boost/numeric/ublas boost/pool boost/program_options boost/program_options/detail boost/property_tree boost/random boost/random/detail boost/range boost/regex boost/serialization boost/signals boost/signals2 boost/spirit boost/spirit/home boost/spirit/home/karma boost/spirit/home/support boost/statechart boost/system boost/thread boost/tr1 boost/type_traits boost/typeof boost/unordered boost/utility boost/uuid boost/variant boost/wave libs libs/algorithm/string libs/array libs/array/test libs/config libs/date_time libs/date_time/example/gregorian libs/date_time/example/local_time libs/date_time/example/posix_time libs/date_time/example/tutorial libs/date_time/xmldoc libs/detail libs/filesystem libs/function libs/functional libs/functional/hash libs/fusion libs/geometry libs/geometry/doc libs/geometry/example libs/geometry/test libs/graph/doc libs/graph_parallel libs/icl libs/icl/doc libs/icl/doc/html libs/icl/doc/html/header/boost/icl libs/icl/test libs/icl/test/test_doc_code_ libs/integer libs/interprocess libs/intrusive libs/io libs/io/doc libs/iostreams libs/iterator libs/math libs/math/doc/sf_and_dist libs/math/doc/sf_and_dist/html/math_toolkit/main_overview libs/mpi/build libs/mpl/doc/refmanual libs/mpl/doc/src/refmanual libs/msm libs/numeric/ublas libs/numeric/ublas/doc libs/parameter/doc/html libs/pool libs/program_options libs/program_options/test libs/property_tree libs/random/doc libs/random/example libs/random/performance libs/random/src libs/random/test libs/range libs/regex libs/serialization libs/serialization/doc libs/serialization/example libs/serialization/src libs/serialization/test libs/serialization/vc7ide libs/signals libs/signals2 libs/spirit libs/spirit/classic/example libs/spirit/doc libs/spirit/example libs/spirit/phoenix libs/spirit/test libs/spirit/test/qi libs/statechart libs/static_assert libs/system libs/thread libs/timer libs/tr1 libs/type_traits libs/type_traits/doc libs/typeof/doc libs/units/test libs/unordered libs/utility libs/utility/swap/test libs/uuid libs/wave more status tools tools/bcp tools/boostbook tools/build/v2 tools/inspect tools/regression tools/regression/src tools/release tools/wave
From: steven_at_[hidden]
Date: 2011-04-05 17:28:08
Author: steven_watanabe
Date: 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
New Revision: 71018
URL: http://svn.boost.org/trac/boost/changeset/71018
Log:
Merge random from the trunk.
Added:
branches/release/boost/random/chi_squared_distribution.hpp
- copied, changed from r67669, /trunk/boost/random/chi_squared_distribution.hpp
branches/release/boost/random/detail/generator_seed_seq.hpp
- copied unchanged from r63549, /trunk/boost/random/detail/generator_seed_seq.hpp
branches/release/boost/random/detail/integer_log2.hpp (contents, props changed)
- copied, changed from r69961, /trunk/boost/random/detail/integer_log2.hpp
branches/release/boost/random/detail/large_arithmetic.hpp
- copied, changed from r70047, /trunk/boost/random/detail/large_arithmetic.hpp
branches/release/boost/random/detail/operators.hpp
- copied, changed from r63286, /trunk/boost/random/detail/operators.hpp
branches/release/boost/random/detail/seed_impl.hpp
- copied, changed from r68758, /trunk/boost/random/detail/seed_impl.hpp
branches/release/boost/random/detail/vector_io.hpp
- copied, changed from r67740, /trunk/boost/random/detail/vector_io.hpp
branches/release/boost/random/discrete_distribution.hpp
- copied, changed from r63180, /trunk/boost/random/discrete_distribution.hpp
branches/release/boost/random/extreme_value_distribution.hpp
- copied, changed from r63330, /trunk/boost/random/extreme_value_distribution.hpp
branches/release/boost/random/fisher_f_distribution.hpp
- copied, changed from r67694, /trunk/boost/random/fisher_f_distribution.hpp
branches/release/boost/random/generate_canonical.hpp
- copied, changed from r68813, /trunk/boost/random/generate_canonical.hpp
branches/release/boost/random/independent_bits.hpp
- copied, changed from r68804, /trunk/boost/random/independent_bits.hpp
branches/release/boost/random/negative_binomial_distribution.hpp
- copied, changed from r65157, /trunk/boost/random/negative_binomial_distribution.hpp
branches/release/boost/random/piecewise_constant_distribution.hpp
- copied, changed from r67740, /trunk/boost/random/piecewise_constant_distribution.hpp
branches/release/boost/random/piecewise_linear_distribution.hpp
- copied, changed from r68028, /trunk/boost/random/piecewise_linear_distribution.hpp
branches/release/boost/random/random_device.hpp
- copied, changed from r68814, /trunk/boost/random/random_device.hpp
branches/release/boost/random/seed_seq.hpp
- copied, changed from r63217, /trunk/boost/random/seed_seq.hpp
branches/release/boost/random/shuffle_order.hpp
- copied, changed from r63327, /trunk/boost/random/shuffle_order.hpp
branches/release/boost/random/student_t_distribution.hpp
- copied, changed from r67710, /trunk/boost/random/student_t_distribution.hpp
branches/release/boost/random/taus88.hpp
- copied unchanged from r68767, /trunk/boost/random/taus88.hpp
branches/release/boost/random/uniform_int_distribution.hpp
- copied, changed from r68440, /trunk/boost/random/uniform_int_distribution.hpp
branches/release/boost/random/uniform_real_distribution.hpp
- copied, changed from r68444, /trunk/boost/random/uniform_real_distribution.hpp
branches/release/boost/random/weibull_distribution.hpp
- copied, changed from r63328, /trunk/boost/random/weibull_distribution.hpp
branches/release/libs/random/example/password.cpp
- copied, changed from r62629, /trunk/libs/random/example/password.cpp
branches/release/libs/random/performance/Jamfile.v2
- copied, changed from r68872, /trunk/libs/random/performance/Jamfile.v2
branches/release/libs/random/test/chi_squared_test.hpp
- copied, changed from r63088, /trunk/libs/random/test/chi_squared_test.hpp
branches/release/libs/random/test/concepts.hpp
- copied, changed from r67761, /trunk/libs/random/test/concepts.hpp
branches/release/libs/random/test/test_bernoulli.cpp
- copied, changed from r68375, /trunk/libs/random/test/test_bernoulli.cpp
branches/release/libs/random/test/test_bernoulli_distribution.cpp
- copied unchanged from r68375, /trunk/libs/random/test/test_bernoulli_distribution.cpp
branches/release/libs/random/test/test_binomial.cpp
- copied, changed from r63088, /trunk/libs/random/test/test_binomial.cpp
branches/release/libs/random/test/test_binomial_distribution.cpp
- copied, changed from r63088, /trunk/libs/random/test/test_binomial_distribution.cpp
branches/release/libs/random/test/test_cauchy.cpp
- copied unchanged from r68406, /trunk/libs/random/test/test_cauchy.cpp
branches/release/libs/random/test/test_cauchy_distribution.cpp
- copied unchanged from r68406, /trunk/libs/random/test/test_cauchy_distribution.cpp
branches/release/libs/random/test/test_chi_squared.cpp
- copied, changed from r67669, /trunk/libs/random/test/test_chi_squared.cpp
branches/release/libs/random/test/test_chi_squared_distribution.cpp
- copied unchanged from r67669, /trunk/libs/random/test/test_chi_squared_distribution.cpp
branches/release/libs/random/test/test_const_mod.cpp
- copied, changed from r68747, /trunk/libs/random/test/test_const_mod.cpp
branches/release/libs/random/test/test_discrete.cpp
- copied unchanged from r63180, /trunk/libs/random/test/test_discrete.cpp
branches/release/libs/random/test/test_discrete_distribution.cpp
- copied, changed from r63180, /trunk/libs/random/test/test_discrete_distribution.cpp
branches/release/libs/random/test/test_distribution.ipp
- copied, changed from r65093, /trunk/libs/random/test/test_distribution.ipp
branches/release/libs/random/test/test_ecuyer1988.cpp
- copied, changed from r68727, /trunk/libs/random/test/test_ecuyer1988.cpp
branches/release/libs/random/test/test_exponential.cpp
- copied unchanged from r68372, /trunk/libs/random/test/test_exponential.cpp
branches/release/libs/random/test/test_exponential_distribution.cpp
- copied unchanged from r68372, /trunk/libs/random/test/test_exponential_distribution.cpp
branches/release/libs/random/test/test_extreme_value.cpp
- copied, changed from r63330, /trunk/libs/random/test/test_extreme_value.cpp
branches/release/libs/random/test/test_extreme_value_distribution.cpp
- copied, changed from r63330, /trunk/libs/random/test/test_extreme_value_distribution.cpp
branches/release/libs/random/test/test_fisher_f.cpp
- copied, changed from r67694, /trunk/libs/random/test/test_fisher_f.cpp
branches/release/libs/random/test/test_fisher_f_distribution.cpp
- copied unchanged from r67694, /trunk/libs/random/test/test_fisher_f_distribution.cpp
branches/release/libs/random/test/test_gamma.cpp
- copied, changed from r63247, /trunk/libs/random/test/test_gamma.cpp
branches/release/libs/random/test/test_gamma_distribution.cpp
- copied, changed from r63247, /trunk/libs/random/test/test_gamma_distribution.cpp
branches/release/libs/random/test/test_generate_canonical.cpp
- copied, changed from r68813, /trunk/libs/random/test/test_generate_canonical.cpp
branches/release/libs/random/test/test_generator.ipp
- copied, changed from r67761, /trunk/libs/random/test/test_generator.ipp
branches/release/libs/random/test/test_geometric.cpp
- copied, changed from r68410, /trunk/libs/random/test/test_geometric.cpp
branches/release/libs/random/test/test_geometric_distribution.cpp
- copied unchanged from r68410, /trunk/libs/random/test/test_geometric_distribution.cpp
branches/release/libs/random/test/test_hellekalek1995.cpp
- copied, changed from r68748, /trunk/libs/random/test/test_hellekalek1995.cpp
branches/release/libs/random/test/test_independent_bits31.cpp
- copied, changed from r68804, /trunk/libs/random/test/test_independent_bits31.cpp
branches/release/libs/random/test/test_independent_bits32.cpp
- copied, changed from r68804, /trunk/libs/random/test/test_independent_bits32.cpp
branches/release/libs/random/test/test_knuth_b.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_knuth_b.cpp
branches/release/libs/random/test/test_kreutzer1986.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_kreutzer1986.cpp
branches/release/libs/random/test/test_lagged_fibonacci.cpp
- copied, changed from r68754, /trunk/libs/random/test/test_lagged_fibonacci.cpp
branches/release/libs/random/test/test_lagged_fibonacci1279.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci1279.cpp
branches/release/libs/random/test/test_lagged_fibonacci19937.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci19937.cpp
branches/release/libs/random/test/test_lagged_fibonacci2281.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci2281.cpp
branches/release/libs/random/test/test_lagged_fibonacci23209.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci23209.cpp
branches/release/libs/random/test/test_lagged_fibonacci3217.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci3217.cpp
branches/release/libs/random/test/test_lagged_fibonacci4423.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci4423.cpp
branches/release/libs/random/test/test_lagged_fibonacci44497.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci44497.cpp
branches/release/libs/random/test/test_lagged_fibonacci607.cpp
- copied, changed from r68754, /trunk/libs/random/test/test_lagged_fibonacci607.cpp
branches/release/libs/random/test/test_lagged_fibonacci9689.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_lagged_fibonacci9689.cpp
branches/release/libs/random/test/test_linear_feedback_shift.cpp
- copied, changed from r68759, /trunk/libs/random/test/test_linear_feedback_shift.cpp
branches/release/libs/random/test/test_lognormal.cpp
- copied unchanged from r68424, /trunk/libs/random/test/test_lognormal.cpp
branches/release/libs/random/test/test_lognormal_distribution.cpp
- copied unchanged from r68424, /trunk/libs/random/test/test_lognormal_distribution.cpp
branches/release/libs/random/test/test_minstd_rand.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_minstd_rand.cpp
branches/release/libs/random/test/test_minstd_rand0.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_minstd_rand0.cpp
branches/release/libs/random/test/test_mt11213b.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_mt11213b.cpp
branches/release/libs/random/test/test_mt19937.cpp
- copied, changed from r67761, /trunk/libs/random/test/test_mt19937.cpp
branches/release/libs/random/test/test_mt19937_64.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_mt19937_64.cpp
branches/release/libs/random/test/test_negative_binomial.cpp
- copied, changed from r65157, /trunk/libs/random/test/test_negative_binomial.cpp
branches/release/libs/random/test/test_negative_binomial_distribution.cpp
- copied unchanged from r65157, /trunk/libs/random/test/test_negative_binomial_distribution.cpp
branches/release/libs/random/test/test_normal.cpp
- copied, changed from r67710, /trunk/libs/random/test/test_normal.cpp
branches/release/libs/random/test/test_normal_distribution.cpp
- copied unchanged from r67710, /trunk/libs/random/test/test_normal_distribution.cpp
branches/release/libs/random/test/test_old_uniform_int.cpp
- copied unchanged from r68647, /trunk/libs/random/test/test_old_uniform_int.cpp
branches/release/libs/random/test/test_old_uniform_int_distribution.cpp
- copied, changed from r68647, /trunk/libs/random/test/test_old_uniform_int_distribution.cpp
branches/release/libs/random/test/test_old_uniform_real.cpp
- copied, changed from r68647, /trunk/libs/random/test/test_old_uniform_real.cpp
branches/release/libs/random/test/test_old_uniform_real_distribution.cpp
- copied unchanged from r68647, /trunk/libs/random/test/test_old_uniform_real_distribution.cpp
branches/release/libs/random/test/test_piecewise_constant.cpp
- copied, changed from r67740, /trunk/libs/random/test/test_piecewise_constant.cpp
branches/release/libs/random/test/test_piecewise_constant_distribution.cpp
- copied, changed from r67740, /trunk/libs/random/test/test_piecewise_constant_distribution.cpp
branches/release/libs/random/test/test_piecewise_linear.cpp
- copied, changed from r68028, /trunk/libs/random/test/test_piecewise_linear.cpp
branches/release/libs/random/test/test_piecewise_linear_distribution.cpp
- copied, changed from r68028, /trunk/libs/random/test/test_piecewise_linear_distribution.cpp
branches/release/libs/random/test/test_poisson.cpp
- copied, changed from r63126, /trunk/libs/random/test/test_poisson.cpp
branches/release/libs/random/test/test_poisson_distribution.cpp
- copied, changed from r63126, /trunk/libs/random/test/test_poisson_distribution.cpp
branches/release/libs/random/test/test_rand48.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_rand48.cpp
branches/release/libs/random/test/test_random_number_generator.cpp
- copied unchanged from r69978, /trunk/libs/random/test/test_random_number_generator.cpp
branches/release/libs/random/test/test_ranlux24.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux24.cpp
branches/release/libs/random/test/test_ranlux24_base.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_ranlux24_base.cpp
branches/release/libs/random/test/test_ranlux3.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux3.cpp
branches/release/libs/random/test/test_ranlux3_01.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux3_01.cpp
branches/release/libs/random/test/test_ranlux4.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux4.cpp
branches/release/libs/random/test/test_ranlux48.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux48.cpp
branches/release/libs/random/test/test_ranlux48_base.cpp
- copied, changed from r68784, /trunk/libs/random/test/test_ranlux48_base.cpp
branches/release/libs/random/test/test_ranlux4_01.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux4_01.cpp
branches/release/libs/random/test/test_ranlux64_3.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux64_3.cpp
branches/release/libs/random/test/test_ranlux64_3_01.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux64_3_01.cpp
branches/release/libs/random/test/test_ranlux64_4.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux64_4.cpp
branches/release/libs/random/test/test_ranlux64_4_01.cpp
- copied, changed from r68783, /trunk/libs/random/test/test_ranlux64_4_01.cpp
branches/release/libs/random/test/test_real_distribution.ipp
- copied, changed from r68372, /trunk/libs/random/test/test_real_distribution.ipp
branches/release/libs/random/test/test_seed_seq.cpp
- copied unchanged from r63217, /trunk/libs/random/test/test_seed_seq.cpp
branches/release/libs/random/test/test_student_t.cpp
- copied, changed from r67710, /trunk/libs/random/test/test_student_t.cpp
branches/release/libs/random/test/test_student_t_distribution.cpp
- copied unchanged from r67710, /trunk/libs/random/test/test_student_t_distribution.cpp
branches/release/libs/random/test/test_taus88.cpp
- copied, changed from r68767, /trunk/libs/random/test/test_taus88.cpp
branches/release/libs/random/test/test_triangle.cpp
- copied unchanged from r68428, /trunk/libs/random/test/test_triangle.cpp
branches/release/libs/random/test/test_triangle_distribution.cpp
- copied unchanged from r68428, /trunk/libs/random/test/test_triangle_distribution.cpp
branches/release/libs/random/test/test_uniform_int.cpp
- copied, changed from r68440, /trunk/libs/random/test/test_uniform_int.cpp
branches/release/libs/random/test/test_uniform_int.ipp
- copied unchanged from r69991, /trunk/libs/random/test/test_uniform_int.ipp
branches/release/libs/random/test/test_uniform_int_distribution.cpp
- copied, changed from r68440, /trunk/libs/random/test/test_uniform_int_distribution.cpp
branches/release/libs/random/test/test_uniform_on_sphere_distribution.cpp
- copied unchanged from r68631, /trunk/libs/random/test/test_uniform_on_sphere_distribution.cpp
branches/release/libs/random/test/test_uniform_real.cpp
- copied unchanged from r68444, /trunk/libs/random/test/test_uniform_real.cpp
branches/release/libs/random/test/test_uniform_real_distribution.cpp
- copied unchanged from r68444, /trunk/libs/random/test/test_uniform_real_distribution.cpp
branches/release/libs/random/test/test_uniform_smallint.cpp
- copied unchanged from r68644, /trunk/libs/random/test/test_uniform_smallint.cpp
branches/release/libs/random/test/test_uniform_smallint_distribution.cpp
- copied unchanged from r68644, /trunk/libs/random/test/test_uniform_smallint_distribution.cpp
branches/release/libs/random/test/test_weibull.cpp
- copied, changed from r63328, /trunk/libs/random/test/test_weibull.cpp
branches/release/libs/random/test/test_weibull_distribution.cpp
- copied, changed from r63328, /trunk/libs/random/test/test_weibull_distribution.cpp
Removed:
branches/release/boost/random/detail/pass_through_engine.hpp
branches/release/libs/random/doc/random_number_generator.qbk
branches/release/libs/random/test/instantiate.cpp
branches/release/libs/random/test/random_test.cpp
branches/release/libs/random/test/validate.cpp
Properties modified:
branches/release/ (props changed)
branches/release/INSTALL (props changed)
branches/release/Jamroot (props changed)
branches/release/LICENSE_1_0.txt (props changed)
branches/release/boost/ (props changed)
branches/release/boost-build.jam (props changed)
branches/release/boost.css (props changed)
branches/release/boost.png (props changed)
branches/release/boost/algorithm/string/ (props changed)
branches/release/boost/archive/ (props changed)
branches/release/boost/archive/basic_binary_iarchive.hpp (props changed)
branches/release/boost/array.hpp (props changed)
branches/release/boost/bimap/ (props changed)
branches/release/boost/concept_check.hpp (props changed)
branches/release/boost/config/ (props changed)
branches/release/boost/config.hpp (props changed)
branches/release/boost/date_time/c_time.hpp (props changed)
branches/release/boost/date_time/gregorian_calendar.ipp (props changed)
branches/release/boost/date_time/posix_time/time_serialize.hpp (props changed)
branches/release/boost/date_time/strings_from_facet.hpp (props changed)
branches/release/boost/date_time/time_facet.hpp (props changed)
branches/release/boost/detail/ (props changed)
branches/release/boost/filesystem/ (props changed)
branches/release/boost/filesystem.hpp (props changed)
branches/release/boost/function/ (props changed)
branches/release/boost/functional/ (props changed)
branches/release/boost/functional/hash/ (props changed)
branches/release/boost/fusion/ (props changed)
branches/release/boost/fusion/container/list/detail/build_cons.hpp (props changed)
branches/release/boost/geometry/algorithms/ (props changed)
branches/release/boost/geometry/arithmetic/ (props changed)
branches/release/boost/geometry/core/ (props changed)
branches/release/boost/geometry/domains/ (props changed)
branches/release/boost/geometry/geometries/ (props changed)
branches/release/boost/geometry/geometry.hpp (props changed)
branches/release/boost/geometry/iterators/ (props changed)
branches/release/boost/geometry/multi/ (props changed)
branches/release/boost/geometry/policies/ (props changed)
branches/release/boost/geometry/ranges/ (props changed)
branches/release/boost/geometry/strategies/ (props changed)
branches/release/boost/geometry/util/ (props changed)
branches/release/boost/geometry/views/ (props changed)
branches/release/boost/gil/ (props changed)
branches/release/boost/graph/ (props changed)
branches/release/boost/icl/ (props changed)
branches/release/boost/integer/ (props changed)
branches/release/boost/interprocess/ (props changed)
branches/release/boost/intrusive/ (props changed)
branches/release/boost/io/ (props changed)
branches/release/boost/iostreams/ (props changed)
branches/release/boost/iterator/ (props changed)
branches/release/boost/iterator/iterator_facade.hpp (props changed)
branches/release/boost/math/ (props changed)
branches/release/boost/math_fwd.hpp (props changed)
branches/release/boost/msm/ (props changed)
branches/release/boost/numeric/ublas/ (props changed)
branches/release/boost/numeric/ublas/functional.hpp (props changed)
branches/release/boost/pool/ (props changed)
branches/release/boost/program_options/ (props changed)
branches/release/boost/program_options/detail/parsers.hpp (props changed)
branches/release/boost/program_options/parsers.hpp (props changed)
branches/release/boost/property_tree/ (props changed)
branches/release/boost/range/ (props changed)
branches/release/boost/regex/ (props changed)
branches/release/boost/serialization/ (props changed)
branches/release/boost/signals/ (props changed)
branches/release/boost/signals2/ (props changed)
branches/release/boost/signals2.hpp (props changed)
branches/release/boost/spirit/ (props changed)
branches/release/boost/spirit/home/ (props changed)
branches/release/boost/spirit/home/karma/ (props changed)
branches/release/boost/spirit/home/support/attributes.hpp (props changed)
branches/release/boost/statechart/ (props changed)
branches/release/boost/static_assert.hpp (props changed)
branches/release/boost/system/ (props changed)
branches/release/boost/thread/ (props changed)
branches/release/boost/thread.hpp (props changed)
branches/release/boost/token_functions.hpp (props changed)
branches/release/boost/tr1/ (props changed)
branches/release/boost/type_traits/ (props changed)
branches/release/boost/typeof/message.hpp (props changed)
branches/release/boost/typeof/register_functions.hpp (props changed)
branches/release/boost/typeof/register_functions_iterate.hpp (props changed)
branches/release/boost/typeof/typeof.hpp (props changed)
branches/release/boost/typeof/unsupported.hpp (props changed)
branches/release/boost/unordered/ (props changed)
branches/release/boost/utility/ (props changed)
branches/release/boost/utility/value_init.hpp (props changed)
branches/release/boost/uuid/ (props changed)
branches/release/boost/variant/ (props changed)
branches/release/boost/version.hpp (props changed)
branches/release/boost/wave/ (props changed)
branches/release/bootstrap.bat (props changed)
branches/release/bootstrap.sh (props changed)
branches/release/index.htm (props changed)
branches/release/index.html (props changed)
branches/release/libs/ (props changed)
branches/release/libs/algorithm/string/ (props changed)
branches/release/libs/array/ (props changed)
branches/release/libs/array/test/array0.cpp (props changed)
branches/release/libs/array/test/array2.cpp (props changed)
branches/release/libs/array/test/array6.cpp (props changed)
branches/release/libs/config/ (props changed)
branches/release/libs/date_time/ (props changed)
branches/release/libs/date_time/example/gregorian/days_between_new_years.cpp (props changed)
branches/release/libs/date_time/example/gregorian/days_since_year_start.cpp (props changed)
branches/release/libs/date_time/example/gregorian/days_till_new_year.cpp (props changed)
branches/release/libs/date_time/example/gregorian/month_add.cpp (props changed)
branches/release/libs/date_time/example/local_time/flight.cpp (props changed)
branches/release/libs/date_time/example/local_time/local_date_time.cpp (props changed)
branches/release/libs/date_time/example/posix_time/print_hours.cpp (props changed)
branches/release/libs/date_time/example/posix_time/time_math.cpp (props changed)
branches/release/libs/date_time/example/tutorial/io_tutorial.cpp (props changed)
branches/release/libs/date_time/xmldoc/date_class.xml (props changed)
branches/release/libs/date_time/xmldoc/usage_examples.xml (props changed)
branches/release/libs/detail/ (props changed)
branches/release/libs/filesystem/ (props changed)
branches/release/libs/function/ (props changed)
branches/release/libs/functional/ (props changed)
branches/release/libs/functional/hash/ (props changed)
branches/release/libs/fusion/ (props changed)
branches/release/libs/geometry/doc/ (props changed)
branches/release/libs/geometry/example/ (props changed)
branches/release/libs/geometry/index.html (props changed)
branches/release/libs/geometry/test/ (props changed)
branches/release/libs/graph/doc/ (props changed)
branches/release/libs/graph_parallel/ (props changed)
branches/release/libs/icl/ (props changed)
branches/release/libs/icl/doc/ (props changed)
branches/release/libs/icl/doc/html/ (props changed)
branches/release/libs/icl/doc/html/header/boost/icl/ (props changed)
branches/release/libs/icl/test/ (props changed)
branches/release/libs/icl/test/test_doc_code_/ (props changed)
branches/release/libs/integer/ (props changed)
branches/release/libs/interprocess/ (props changed)
branches/release/libs/intrusive/ (props changed)
branches/release/libs/io/ (props changed)
branches/release/libs/io/doc/ (props changed)
branches/release/libs/iostreams/ (props changed)
branches/release/libs/iterator/ (props changed)
branches/release/libs/libraries.htm (props changed)
branches/release/libs/maintainers.txt (props changed)
branches/release/libs/math/ (props changed)
branches/release/libs/math/doc/sf_and_dist/faq.qbk (props changed)
branches/release/libs/math/doc/sf_and_dist/html/math_toolkit/main_overview/faq.html (props changed)
branches/release/libs/mpi/build/ (props changed)
branches/release/libs/mpl/doc/refmanual/broken-compiler-workarounds.html (props changed)
branches/release/libs/mpl/doc/refmanual/categorized-index-concepts.html (props changed)
branches/release/libs/mpl/doc/refmanual/cfg-no-preprocessed-headers.html (props changed)
branches/release/libs/mpl/doc/refmanual/composition-and-argument-binding.html (props changed)
branches/release/libs/mpl/doc/refmanual/data-types-concepts.html (props changed)
branches/release/libs/mpl/doc/refmanual/data-types-miscellaneous.html (props changed)
branches/release/libs/mpl/doc/refmanual/extensible-associative-sequence.html (props changed)
branches/release/libs/mpl/doc/refmanual/inserter-class.html (props changed)
branches/release/libs/mpl/doc/refmanual/tag-dispatched-metafunction.html (props changed)
branches/release/libs/mpl/doc/refmanual/trivial-metafunctions-summary.html (props changed)
branches/release/libs/mpl/doc/src/refmanual/Iterators-Iterator.rst (props changed)
branches/release/libs/msm/ (props changed)
branches/release/libs/numeric/ublas/ (props changed)
branches/release/libs/numeric/ublas/doc/ (props changed)
branches/release/libs/parameter/doc/html/index.html (props changed)
branches/release/libs/pool/ (props changed)
branches/release/libs/program_options/ (props changed)
branches/release/libs/program_options/test/parsers_test.cpp (props changed)
branches/release/libs/property_tree/ (props changed)
branches/release/libs/range/ (props changed)
branches/release/libs/regex/ (props changed)
branches/release/libs/serialization/ (props changed)
branches/release/libs/serialization/doc/ (props changed)
branches/release/libs/serialization/example/ (props changed)
branches/release/libs/serialization/src/ (props changed)
branches/release/libs/serialization/test/test_diamond_complex.cpp (props changed)
branches/release/libs/serialization/vc7ide/ (props changed)
branches/release/libs/signals/ (props changed)
branches/release/libs/signals2/ (props changed)
branches/release/libs/spirit/ (props changed)
branches/release/libs/spirit/classic/example/ (props changed)
branches/release/libs/spirit/doc/ (props changed)
branches/release/libs/spirit/example/ (props changed)
branches/release/libs/spirit/phoenix/ (props changed)
branches/release/libs/spirit/test/ (props changed)
branches/release/libs/spirit/test/qi/optional.cpp (props changed)
branches/release/libs/statechart/ (props changed)
branches/release/libs/static_assert/ (props changed)
branches/release/libs/system/ (props changed)
branches/release/libs/thread/ (props changed)
branches/release/libs/timer/ (props changed)
branches/release/libs/tr1/ (props changed)
branches/release/libs/type_traits/ (props changed)
branches/release/libs/type_traits/doc/ (props changed)
branches/release/libs/typeof/doc/typeof.qbk (props changed)
branches/release/libs/units/test/ (props changed)
branches/release/libs/unordered/ (props changed)
branches/release/libs/utility/ (props changed)
branches/release/libs/utility/assert.html (props changed)
branches/release/libs/utility/assert_test.cpp (props changed)
branches/release/libs/utility/swap.html (props changed)
branches/release/libs/utility/swap/test/std_bitset.cpp (props changed)
branches/release/libs/utility/value_init.htm (props changed)
branches/release/libs/utility/value_init_test.cpp (props changed)
branches/release/libs/uuid/ (props changed)
branches/release/libs/wave/ (props changed)
branches/release/more/ (props changed)
branches/release/rst.css (props changed)
branches/release/status/ (props changed)
branches/release/status/Jamfile.v2 (props changed)
branches/release/status/explicit-failures-markup.xml (props changed)
branches/release/tools/ (props changed)
branches/release/tools/bcp/ (props changed)
branches/release/tools/boostbook/ (props changed)
branches/release/tools/build/v2/ (props changed)
branches/release/tools/inspect/ (props changed)
branches/release/tools/regression/ (props changed)
branches/release/tools/regression/src/library_status.cpp (props changed)
branches/release/tools/release/ (props changed)
branches/release/tools/wave/ (props changed)
Text files modified:
branches/release/boost/nondet_random.hpp | 122 -----
branches/release/boost/random.hpp | 61 +-
branches/release/boost/random/additive_combine.hpp | 399 ++++++++++-------
branches/release/boost/random/bernoulli_distribution.hpp | 228 +++++++---
branches/release/boost/random/binomial_distribution.hpp | 465 +++++++++++++++++---
branches/release/boost/random/cauchy_distribution.hpp | 251 +++++++---
branches/release/boost/random/chi_squared_distribution.hpp | 2
branches/release/boost/random/detail/const_mod.hpp | 361 ++++-----------
branches/release/boost/random/detail/integer_log2.hpp | 19
branches/release/boost/random/detail/large_arithmetic.hpp | 6
branches/release/boost/random/detail/operators.hpp | 19
branches/release/boost/random/detail/seed.hpp | 27 +
branches/release/boost/random/detail/seed_impl.hpp | 322 ++++++++++++--
branches/release/boost/random/detail/uniform_int_float.hpp | 84 +--
branches/release/boost/random/detail/vector_io.hpp | 12
branches/release/boost/random/discard_block.hpp | 240 +++++++---
branches/release/boost/random/discrete_distribution.hpp | 125 +---
branches/release/boost/random/exponential_distribution.hpp | 190 ++++++--
branches/release/boost/random/extreme_value_distribution.hpp | 12
branches/release/boost/random/fisher_f_distribution.hpp | 11
branches/release/boost/random/gamma_distribution.hpp | 331 ++++++++++----
branches/release/boost/random/generate_canonical.hpp | 21
branches/release/boost/random/geometric_distribution.hpp | 291 +++++++++---
branches/release/boost/random/independent_bits.hpp | 64 --
branches/release/boost/random/inversive_congruential.hpp | 280 ++++++++----
branches/release/boost/random/lagged_fibonacci.hpp | 844 +++++++++++++++++--------------------
branches/release/boost/random/linear_congruential.hpp | 621 +++++++++++++++------------
branches/release/boost/random/linear_feedback_shift.hpp | 285 +++++++-----
branches/release/boost/random/lognormal_distribution.hpp | 297 +++++++++---
branches/release/boost/random/mersenne_twister.hpp | 680 +++++++++++++++++++-----------
branches/release/boost/random/negative_binomial_distribution.hpp | 6
branches/release/boost/random/normal_distribution.hpp | 270 ++++++++---
branches/release/boost/random/piecewise_constant_distribution.hpp | 47 -
branches/release/boost/random/piecewise_linear_distribution.hpp | 77 +-
branches/release/boost/random/poisson_distribution.hpp | 388 ++++++++++++++---
branches/release/boost/random/random_device.hpp | 13
branches/release/boost/random/random_number_generator.hpp | 66 +-
branches/release/boost/random/ranlux.hpp | 52 +
branches/release/boost/random/seed_seq.hpp | 18
branches/release/boost/random/shuffle_order.hpp | 76 +-
branches/release/boost/random/shuffle_output.hpp | 227 ---------
branches/release/boost/random/student_t_distribution.hpp | 6
branches/release/boost/random/subtract_with_carry.hpp | 893 +++++++++++++++++++++++----------------
branches/release/boost/random/triangle_distribution.hpp | 264 ++++++++---
branches/release/boost/random/uniform_01.hpp | 20
branches/release/boost/random/uniform_int.hpp | 319 ++-----------
branches/release/boost/random/uniform_int_distribution.hpp | 10
branches/release/boost/random/uniform_on_sphere.hpp | 240 ++++++++--
branches/release/boost/random/uniform_real.hpp | 114 +---
branches/release/boost/random/uniform_real_distribution.hpp | 14
branches/release/boost/random/uniform_smallint.hpp | 324 ++++++++++----
branches/release/boost/random/variate_generator.hpp | 220 ++-------
branches/release/boost/random/weibull_distribution.hpp | 14
branches/release/boost/random/xor_combine.hpp | 305 +++++++------
branches/release/libs/random/doc/Jamfile.v2 | 93 +++-
branches/release/libs/random/doc/concepts.qbk | 70 --
branches/release/libs/random/doc/distribution_performance_linux.qbk | 41
branches/release/libs/random/doc/distribution_performance_windows.qbk | 41
branches/release/libs/random/doc/distributions.qbk | 52 +
branches/release/libs/random/doc/generator_performance_linux.qbk | 73 +-
branches/release/libs/random/doc/generator_performance_windows.qbk | 72 +-
branches/release/libs/random/doc/generators.qbk | 6
branches/release/libs/random/doc/performance.qbk | 8
branches/release/libs/random/doc/performance_data.qbk | 73 +-
branches/release/libs/random/doc/random.qbk | 127 ++--
branches/release/libs/random/doc/tutorial.qbk | 7
branches/release/libs/random/example/Jamfile.v2 | 1
branches/release/libs/random/example/die.cpp | 28
branches/release/libs/random/example/password.cpp | 12
branches/release/libs/random/example/random_demo.cpp | 22
branches/release/libs/random/example/weighted_die.cpp | 30
branches/release/libs/random/performance/Jamfile.v2 | 13
branches/release/libs/random/performance/generate_table.cpp | 22
branches/release/libs/random/performance/nondet_random_speed.cpp | 12
branches/release/libs/random/performance/random_speed.cpp | 118 ++---
branches/release/libs/random/src/random_device.cpp | 41 +
branches/release/libs/random/test/Jamfile.v2 | 131 ++++-
branches/release/libs/random/test/chi_squared_test.hpp | 2
branches/release/libs/random/test/concepts.hpp | 119 ++++
branches/release/libs/random/test/statistic_tests.hpp | 11
branches/release/libs/random/test/test_bernoulli.cpp | 2
branches/release/libs/random/test/test_binomial.cpp | 112 ----
branches/release/libs/random/test/test_binomial_distribution.cpp | 142 +-----
branches/release/libs/random/test/test_chi_squared.cpp | 102 ----
branches/release/libs/random/test/test_const_mod.cpp | 93 ++-
branches/release/libs/random/test/test_discrete_distribution.cpp | 5
branches/release/libs/random/test/test_distribution.ipp | 119 +++++
branches/release/libs/random/test/test_ecuyer1988.cpp | 8
branches/release/libs/random/test/test_extreme_value.cpp | 109 ----
branches/release/libs/random/test/test_extreme_value_distribution.cpp | 136 -----
branches/release/libs/random/test/test_fisher_f.cpp | 106 ----
branches/release/libs/random/test/test_gamma.cpp | 109 ----
branches/release/libs/random/test/test_gamma_distribution.cpp | 141 +-----
branches/release/libs/random/test/test_generate_canonical.cpp | 2
branches/release/libs/random/test/test_generator.ipp | 70 ++
branches/release/libs/random/test/test_geometric.cpp | 3
branches/release/libs/random/test/test_hellekalek1995.cpp | 8
branches/release/libs/random/test/test_independent_bits31.cpp | 9
branches/release/libs/random/test/test_independent_bits32.cpp | 7
branches/release/libs/random/test/test_knuth_b.cpp | 9
branches/release/libs/random/test/test_kreutzer1986.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci.cpp | 8
branches/release/libs/random/test/test_lagged_fibonacci1279.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci19937.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci2281.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci23209.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci3217.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci4423.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci44497.cpp | 9
branches/release/libs/random/test/test_lagged_fibonacci607.cpp | 8
branches/release/libs/random/test/test_lagged_fibonacci9689.cpp | 9
branches/release/libs/random/test/test_linear_feedback_shift.cpp | 9
branches/release/libs/random/test/test_minstd_rand.cpp | 9
branches/release/libs/random/test/test_minstd_rand0.cpp | 9
branches/release/libs/random/test/test_mt11213b.cpp | 7
branches/release/libs/random/test/test_mt19937.cpp | 9
branches/release/libs/random/test/test_mt19937_64.cpp | 7
branches/release/libs/random/test/test_negative_binomial.cpp | 120 ----
branches/release/libs/random/test/test_normal.cpp | 109 ----
branches/release/libs/random/test/test_old_uniform_int_distribution.cpp | 38 +
branches/release/libs/random/test/test_old_uniform_real.cpp | 1
branches/release/libs/random/test/test_piecewise_constant.cpp | 81 ++-
branches/release/libs/random/test/test_piecewise_constant_distribution.cpp | 57 ++
branches/release/libs/random/test/test_piecewise_linear.cpp | 98 +++-
branches/release/libs/random/test/test_piecewise_linear_distribution.cpp | 5
branches/release/libs/random/test/test_poisson.cpp | 115 ----
branches/release/libs/random/test/test_poisson_distribution.cpp | 109 ----
branches/release/libs/random/test/test_rand48.cpp | 14
branches/release/libs/random/test/test_random_device.cpp | 25
branches/release/libs/random/test/test_ranlux24.cpp | 9
branches/release/libs/random/test/test_ranlux24_base.cpp | 9
branches/release/libs/random/test/test_ranlux3.cpp | 9
branches/release/libs/random/test/test_ranlux3_01.cpp | 7
branches/release/libs/random/test/test_ranlux4.cpp | 9
branches/release/libs/random/test/test_ranlux48.cpp | 7
branches/release/libs/random/test/test_ranlux48_base.cpp | 7
branches/release/libs/random/test/test_ranlux4_01.cpp | 7
branches/release/libs/random/test/test_ranlux64_3.cpp | 10
branches/release/libs/random/test/test_ranlux64_3_01.cpp | 9
branches/release/libs/random/test/test_ranlux64_4.cpp | 10
branches/release/libs/random/test/test_ranlux64_4_01.cpp | 9
branches/release/libs/random/test/test_real_distribution.ipp | 66 ++
branches/release/libs/random/test/test_student_t.cpp | 100 ----
branches/release/libs/random/test/test_taus88.cpp | 7
branches/release/libs/random/test/test_uniform_int.cpp | 2
branches/release/libs/random/test/test_uniform_int_distribution.cpp | 4
branches/release/libs/random/test/test_weibull.cpp | 111 ----
branches/release/libs/random/test/test_weibull_distribution.cpp | 142 +-----
148 files changed, 7966 insertions(+), 6657 deletions(-)
Modified: branches/release/boost/nondet_random.hpp
==============================================================================
--- branches/release/boost/nondet_random.hpp (original)
+++ branches/release/boost/nondet_random.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,126 +17,6 @@
#ifndef BOOST_NONDET_RANDOM_HPP
#define BOOST_NONDET_RANDOM_HPP
-#include <string> // std::abs
-#include <algorithm> // std::min
-#include <boost/config/no_tr1/cmath.hpp>
-#include <boost/config.hpp>
-#include <boost/utility.hpp> // noncopyable
-#include <boost/integer_traits.hpp> // compile-time integral limits
-#include <boost/random/detail/auto_link.hpp>
-
-namespace boost {
-
-/**
- * Class \random_device models a \nondeterministic_random_number_generator.
- * It uses one or more implementation-defined stochastic processes to
- * generate a sequence of uniformly distributed non-deterministic random
- * numbers. For those environments where a non-deterministic random number
- * generator is not available, class random_device must not be implemented. See
- *
- * @blockquote
- * "Randomness Recommendations for Security", D. Eastlake, S. Crocker,
- * J. Schiller, Network Working Group, RFC 1750, December 1994
- * @endblockquote
- *
- * for further discussions.
- *
- * @xmlnote
- * Some operating systems abstract the computer hardware enough
- * to make it difficult to non-intrusively monitor stochastic processes.
- * However, several do provide a special device for exactly this purpose.
- * It seems to be impossible to emulate the functionality using Standard
- * C++ only, so users should be aware that this class may not be available
- * on all platforms.
- * @endxmlnote
- *
- * <b>Implementation Note for Linux</b>
- *
- * On the Linux operating system, token is interpreted as a filesystem
- * path. It is assumed that this path denotes an operating system
- * pseudo-device which generates a stream of non-deterministic random
- * numbers. The pseudo-device should never signal an error or end-of-file.
- * Otherwise, @c std::ios_base::failure is thrown. By default,
- * \random_device uses the /dev/urandom pseudo-device to retrieve
- * the random numbers. Another option would be to specify the /dev/random
- * pseudo-device, which blocks on reads if the entropy pool has no more
- * random bits available.
- *
- * <b>Implementation Note for Windows</b>
- *
- * On the Windows operating system, token is interpreted as the name
- * of a cryptographic service provider. By default \random_device uses
- * MS_DEF_PROV.
- *
- * <b>Performance</b>
- *
- * The test program <a href="\boost/libs/random/performance/nondet_random_speed.cpp">
- * nondet_random_speed.cpp</a> measures the execution times of the
- * nondet_random.hpp implementation of the above algorithms in a tight
- * loop. The performance has been evaluated on a Pentium Pro 200 MHz
- * with gcc 2.95.2, Linux 2.2.13, glibc 2.1.2.
- *
- * <table cols="2">
- * <tr><th>class</th><th>time per invocation [usec]</th></tr>
- * <tr><td> @xmlonly <classname alt="boost::random_device">random_device</classname> @endxmlonly </td><td>92.0</td></tr>
- * </table>
- *
- * The measurement error is estimated at +/- 1 usec.
- */
-class random_device : private noncopyable
-{
-public:
- typedef unsigned int result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = true);
- BOOST_STATIC_CONSTANT(result_type, min_value = integer_traits<result_type>::const_min);
- BOOST_STATIC_CONSTANT(result_type, max_value = integer_traits<result_type>::const_max);
-
- /**
- * Returns: The smallest value that the \random_device can produce.
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return min_value; }
- /**
- * Returns: The largest value that the \random_device can produce.
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return max_value; }
- /**
- * Constructs a @c random_device, optionally using the given token as an
- * access specification (for example, a URL) to some implementation-defined
- * service for monitoring a stochastic process.
- */
- BOOST_RANDOM_DECL explicit random_device(const std::string& token = default_token);
- BOOST_RANDOM_DECL ~random_device();
- /**
- * Returns: An entropy estimate for the random numbers returned by
- * operator(), in the range min() to log2( max()+1). A deterministic
- * random number generator (e.g. a pseudo-random number engine)
- * has entropy 0.
- *
- * Throws: Nothing.
- */
- BOOST_RANDOM_DECL double entropy() const;
- /**
- * Returns: A random value in the range [min, max]
- */
- BOOST_RANDOM_DECL unsigned int operator()();
-
-private:
- BOOST_RANDOM_DECL static const char * const default_token;
-
- /*
- * std:5.3.5/5 [expr.delete]: "If the object being deleted has incomplete
- * class type at the point of deletion and the complete class has a
- * non-trivial destructor [...], the behavior is undefined".
- * This disallows the use of scoped_ptr<> with pimpl-like classes
- * having a non-trivial destructor.
- */
- class impl;
- impl * pimpl;
-};
-
-
-// TODO: put Schneier's Yarrow-160 algorithm here.
-
-} // namespace boost
+#include <boost/random/random_device.hpp>
#endif /* BOOST_NONDET_RANDOM_HPP */
Modified: branches/release/boost/random.hpp
==============================================================================
--- branches/release/boost/random.hpp (original)
+++ branches/release/boost/random.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -33,52 +33,53 @@
#define BOOST_RANDOM_HPP
// generators
-#include <boost/random/linear_congruential.hpp>
#include <boost/random/additive_combine.hpp>
+#include <boost/random/discard_block.hpp>
+#include <boost/random/independent_bits.hpp>
#include <boost/random/inversive_congruential.hpp>
-#include <boost/random/shuffle_output.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include <boost/random/lagged_fibonacci.hpp>
-#include <boost/random/ranlux.hpp>
+#include <boost/random/linear_congruential.hpp>
#include <boost/random/linear_feedback_shift.hpp>
-#include <boost/random/xor_combine.hpp>
-#include <boost/random/discard_block.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/ranlux.hpp>
+#include <boost/random/shuffle_order.hpp>
+#include <boost/random/shuffle_output.hpp>
#include <boost/random/subtract_with_carry.hpp>
-#include <boost/random/variate_generator.hpp>
-
-namespace boost {
- /**
- * The specialization taus88 was suggested in
- *
- * @blockquote
- * "Maximally Equidistributed Combined Tausworthe Generators",
- * Pierre L'Ecuyer, Mathematics of Computation, Volume 65,
- * Number 213, January 1996, Pages 203-213
- * @endblockquote
- */
- typedef random::xor_combine<random::xor_combine<random::linear_feedback_shift<uint32_t, 32, 31, 13, 12, 0>, 0,
- random::linear_feedback_shift<uint32_t, 32, 29, 2, 4, 0>, 0, 0>, 0,
- random::linear_feedback_shift<uint32_t, 32, 28, 3, 17, 0>, 0, 0> taus88;
-} // namespace boost
+#include <boost/random/taus88.hpp>
+#include <boost/random/xor_combine.hpp>
// misc
+#include <boost/random/generate_canonical.hpp>
+#include <boost/random/seed_seq.hpp>
#include <boost/random/random_number_generator.hpp>
+#include <boost/random/variate_generator.hpp>
// distributions
-#include <boost/random/uniform_smallint.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/triangle_distribution.hpp>
#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/chi_squared_distribution.hpp>
+#include <boost/random/discrete_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/extreme_value_distribution.hpp>
+#include <boost/random/fisher_f_distribution.hpp>
+#include <boost/random/gamma_distribution.hpp>
#include <boost/random/geometric_distribution.hpp>
-#include <boost/random/normal_distribution.hpp>
#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/negative_binomial_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/piecewise_constant_distribution.hpp>
+#include <boost/random/piecewise_linear_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
-#include <boost/random/gamma_distribution.hpp>
-#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/student_t_distribution.hpp>
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_real_distribution.hpp>
+#include <boost/random/uniform_smallint.hpp>
+#include <boost/random/weibull_distribution.hpp>
#endif // BOOST_RANDOM_HPP
Modified: branches/release/boost/random/additive_combine.hpp
==============================================================================
--- branches/release/boost/random/additive_combine.hpp (original)
+++ branches/release/boost/random/additive_combine.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,20 +16,23 @@
#ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP
#define BOOST_RANDOM_ADDITIVE_COMBINE_HPP
-#include <iostream>
+#include <istream>
+#include <iosfwd>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/seed.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
/**
- * An instantiation of class template \additive_combine model a
+ * An instantiation of class template @c additive_combine_engine models a
* \pseudo_random_number_generator. It combines two multiplicative
- * \linear_congruential number generators, i.e. those with @c c = 0.
+ * \linear_congruential_engine number generators, i.e. those with @c c = 0.
* It is described in
*
* @blockquote
@@ -38,183 +41,225 @@
* @endblockquote
*
* The template parameters MLCG1 and MLCG2 shall denote two different
- * \linear_congruential number generators, each with c = 0. Each invocation
- * returns a random number X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1), where
- * m1 denotes the modulus of MLCG1.
- *
- * The template parameter @c val is the validation value checked by validation.
+ * \linear_congruential_engine number generators, each with c = 0. Each
+ * invocation returns a random number
+ * X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1),
+ * where m1 denotes the modulus of MLCG1.
*/
-template<class MLCG1, class MLCG2,
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- typename MLCG1::result_type
-#else
- int32_t
-#endif
- val>
-class additive_combine
+template<class MLCG1, class MLCG2>
+class additive_combine_engine
{
public:
- typedef MLCG1 first_base;
- typedef MLCG2 second_base;
- typedef typename MLCG1::result_type result_type;
+ typedef MLCG1 first_base;
+ typedef MLCG2 second_base;
+ typedef typename MLCG1::result_type result_type;
+
+ // Required by old Boost.Random concept
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ /**
+ * Returns the smallest value that the generator can produce
+ */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return 1; }
+ /**
+ * Returns the largest value that the generator can produce
+ */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return MLCG1::modulus-1; }
+
+ /**
+ * Constructs an @c additive_combine_engine using the
+ * default constructors of the two base generators.
+ */
+ additive_combine_engine() : _mlcg1(), _mlcg2() { }
+ /**
+ * Constructs an @c additive_combine_engine, using seed as
+ * the constructor argument for both base generators.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(additive_combine_engine,
+ result_type, seed_arg)
+ {
+ _mlcg1.seed(seed_arg);
+ _mlcg2.seed(seed_arg);
+ }
+ /**
+ * Constructs an @c additive_combine_engine, using seq as
+ * the constructor argument for both base generators.
+ *
+ * @xmlwarning
+ * The semantics of this function are liable to change.
+ * A @c seed_seq is designed to generate all the seeds
+ * in one shot, but this seeds the two base engines
+ * independantly and probably ends up giving the same
+ * sequence to both.
+ * @endxmlwarning
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(additive_combine_engine,
+ SeedSeq, seq)
+ {
+ _mlcg1.seed(seq);
+ _mlcg2.seed(seq);
+ }
+ /**
+ * Constructs an @c additive_combine_engine, using
+ * @c seed1 and @c seed2 as the constructor argument to
+ * the first and second base generators, respectively.
+ */
+ additive_combine_engine(typename MLCG1::result_type seed1,
+ typename MLCG2::result_type seed2)
+ : _mlcg1(seed1), _mlcg2(seed2) { }
+ /**
+ * Contructs an @c additive_combine_engine with
+ * values from the range defined by the input iterators first
+ * and last. first will be modified to point to the element
+ * after the last one used.
+ *
+ * Throws: @c std::invalid_argument if the input range is too small.
+ *
+ * Exception Safety: Basic
+ */
+ template<class It> additive_combine_engine(It& first, It last)
+ : _mlcg1(first, last), _mlcg2(first, last) { }
+
+ /**
+ * Seeds an @c additive_combine_engine using the default
+ * seeds of the two base generators.
+ */
+ void seed()
+ {
+ _mlcg1.seed();
+ _mlcg2.seed();
+ }
+
+ /**
+ * Seeds an @c additive_combine_engine, using @c seed as the
+ * seed for both base generators.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(additive_combine_engine,
+ result_type, seed_arg)
+ {
+ _mlcg1.seed(seed_arg);
+ _mlcg2.seed(seed_arg);
+ }
+
+ /**
+ * Seeds an @c additive_combine_engine, using @c seq to
+ * seed both base generators.
+ *
+ * See the warning on the corresponding constructor.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(additive_combine_engine,
+ SeedSeq, seq)
+ {
+ _mlcg1.seed(seq);
+ _mlcg2.seed(seq);
+ }
+
+ /**
+ * Seeds an @c additive_combine generator, using @c seed1 and @c seed2 as
+ * the seeds to the first and second base generators, respectively.
+ */
+ void seed(typename MLCG1::result_type seed1,
+ typename MLCG2::result_type seed2)
+ {
+ _mlcg1.seed(seed1);
+ _mlcg2.seed(seed2);
+ }
+
+ /**
+ * Seeds an @c additive_combine_engine with
+ * values from the range defined by the input iterators first
+ * and last. first will be modified to point to the element
+ * after the last one used.
+ *
+ * Throws: @c std::invalid_argument if the input range is too small.
+ *
+ * Exception Safety: Basic
+ */
+ template<class It> void seed(It& first, It last)
+ {
+ _mlcg1.seed(first, last);
+ _mlcg2.seed(first, last);
+ }
+
+ /** Returns the next value of the generator. */
+ result_type operator()() {
+ result_type val1 = _mlcg1();
+ result_type val2 = _mlcg2();
+ if(val2 < val1) return val1 - val2;
+ else return val1 - val2 + MLCG1::modulus - 1;
+ }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ _mlcg1.discard(z);
+ _mlcg2.discard(z);
+ }
+
+ /**
+ * Writes the state of an @c additive_combine_engine to a @c
+ * std::ostream. The textual representation of an @c
+ * additive_combine_engine is the textual representation of
+ * the first base generator followed by the textual representation
+ * of the second base generator.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, additive_combine_engine, r)
+ { os << r._mlcg1 << ' ' << r._mlcg2; return os; }
+
+ /**
+ * Reads the state of an @c additive_combine_engine from a
+ * @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, additive_combine_engine, r)
+ { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
+
+ /**
+ * Returns: true iff the two @c additive_combine_engines will
+ * produce the same sequence of values.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(additive_combine_engine, x, y)
+ { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
+ /**
+ * Returns: true iff the two @c additive_combine_engines will
+ * produce different sequences of values.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(additive_combine_engine)
+
+private:
+ MLCG1 _mlcg1;
+ MLCG2 _mlcg2;
+};
+
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const result_type min_value = 1;
- static const result_type max_value = MLCG1::max_value-1;
-#else
- enum { has_fixed_range = false };
-#endif
- /**
- * Returns: The smallest value that the generator can produce
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
- /**
- * Returns: The largest value that the generator can produce
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_mlcg1.max)()-1; }
-
- /**
- * Constructs an \additive_combine generator using the
- * default constructors of the two base generators.
- */
- additive_combine() : _mlcg1(), _mlcg2() { }
- /**
- * Constructs an \additive_combine generator, using aseed as
- * the constructor argument for both base generators.
- */
- explicit additive_combine(result_type aseed)
- : _mlcg1(aseed), _mlcg2(aseed) { }
- /**
- * Constructs an \additive_combine generator, using
- * @c seed1 and @c seed2 as the constructor argument to
- * the first and second base generators, respectively.
- */
- additive_combine(typename MLCG1::result_type seed1,
- typename MLCG2::result_type seed2)
- : _mlcg1(seed1), _mlcg2(seed2) { }
- /**
- * Contructs an \additive_combine generator with
- * values from the range defined by the input iterators first
- * and last. first will be modified to point to the element
- * after the last one used.
- *
- * Throws: @c std::invalid_argument if the input range is too small.
- *
- * Exception Safety: Basic
- */
- template<class It> additive_combine(It& first, It last)
- : _mlcg1(first, last), _mlcg2(first, last) { }
-
- /**
- * Seeds an \additive_combine generator using the default
- * seeds of the two base generators.
- */
- void seed()
- {
- _mlcg1.seed();
- _mlcg2.seed();
- }
-
- /**
- * Seeds an \additive_combine generator, using @c aseed as the
- * seed for both base generators.
- */
- void seed(result_type aseed)
- {
- _mlcg1.seed(aseed);
- _mlcg2.seed(aseed);
- }
-
- /**
- * Seeds an \additive_combine generator, using @c seed1 and @c seed2 as
- * the seeds to the first and second base generators, respectively.
- */
- void seed(typename MLCG1::result_type seed1,
- typename MLCG2::result_type seed2)
- {
- _mlcg1.seed(seed1);
- _mlcg2.seed(seed2);
- }
-
- /**
- * Seeds an \additive_combine generator with
- * values from the range defined by the input iterators first
- * and last. first will be modified to point to the element
- * after the last one used.
- *
- * Throws: @c std::invalid_argument if the input range is too small.
- *
- * Exception Safety: Basic
- */
- template<class It> void seed(It& first, It last)
- {
- _mlcg1.seed(first, last);
- _mlcg2.seed(first, last);
- }
-
- /**
- * Returns: the next value of the generator
- */
- result_type operator()() {
- result_type z = _mlcg1() - _mlcg2();
- if(z < 1)
- z += MLCG1::modulus-1;
- return z;
- }
-
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- /**
- * Writes the state of an \additive_combine generator to a @c
- * std::ostream. The textual representation of an \additive_combine
- * generator is the textual representation of the first base
- * generator followed by the textual representation of the
- * second base generator.
- */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const additive_combine& r)
- { os << r._mlcg1 << " " << r._mlcg2; return os; }
-
- /**
- * Reads the state of an \additive_combine generator from a
- * @c std::istream.
- */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, additive_combine& r)
- { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
+template<class MLCG1, class MLCG2>
+const bool additive_combine_engine<MLCG1, MLCG2>::has_fixed_range;
#endif
- /**
- * Returns: true iff the two \additive_combine generators will
- * produce the same sequence of values.
- */
- friend bool operator==(const additive_combine& x, const additive_combine& y)
- { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
- /**
- * Returns: true iff the two \additive_combine generators will
- * produce different sequences of values.
- */
- friend bool operator!=(const additive_combine& x, const additive_combine& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const additive_combine& rhs) const
- { return _mlcg1 == rhs._mlcg1 && _mlcg2 == rhs._mlcg2; }
- bool operator!=(const additive_combine& rhs) const
- { return !(*this == rhs); }
-#endif
+/// \cond show_deprecated
-private:
- MLCG1 _mlcg1;
- MLCG2 _mlcg2;
+/** Provided for backwards compatibility. */
+template<class MLCG1, class MLCG2, typename MLCG1::result_type val = 0>
+class additive_combine : public additive_combine_engine<MLCG1, MLCG2>
+{
+ typedef additive_combine_engine<MLCG1, MLCG2> base_t;
+public:
+ typedef typename base_t::result_type result_type;
+ additive_combine() {}
+ template<class T>
+ additive_combine(T& arg) : base_t(arg) {}
+ template<class T>
+ additive_combine(const T& arg) : base_t(arg) {}
+ template<class It>
+ additive_combine(It& first, It last) : base_t(first, last) {}
};
-} // namespace random
+/// \endcond
/**
* The specialization \ecuyer1988 was suggested in
@@ -224,10 +269,14 @@
* Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774
* @endblockquote
*/
-typedef random::additive_combine<
- random::linear_congruential<int32_t, 40014, 0, 2147483563, 0>,
- random::linear_congruential<int32_t, 40692, 0, 2147483399, 0>,
- 2060321752> ecuyer1988;
+typedef additive_combine_engine<
+ linear_congruential_engine<uint32_t, 40014, 0, 2147483563>,
+ linear_congruential_engine<uint32_t, 40692, 0, 2147483399>
+> ecuyer1988;
+
+} // namespace random
+
+using random::ecuyer1988;
} // namespace boost
Modified: branches/release/boost/random/bernoulli_distribution.hpp
==============================================================================
--- branches/release/boost/random/bernoulli_distribution.hpp (original)
+++ branches/release/boost/random/bernoulli_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/bernoulli_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -16,11 +17,13 @@
#ifndef BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#define BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
-#include <cassert>
-#include <iostream>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
namespace boost {
+namespace random {
/**
* Instantiations of class template \bernoulli_distribution model a
@@ -32,78 +35,163 @@
class bernoulli_distribution
{
public:
- // In principle, this could work with both integer and floating-point
- // types. Generating floating-point random numbers in the first
- // place is probably more expensive, so use integer as input.
- typedef int input_type;
- typedef bool result_type;
-
- /**
- * Constructs a \bernoulli_distribution object.
- * p is the parameter of the distribution.
- *
- * Requires: 0 <= p <= 1
- */
- explicit bernoulli_distribution(const RealType& p_arg = RealType(0.5))
- : _p(p_arg)
- {
- assert(_p >= 0);
- assert(_p <= 1);
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: The "p" parameter of the distribution.
- */
- RealType p() const { return _p; }
- /**
- * Effects: Subsequent uses of the distribution do not depend
- * on values produced by any engine prior to invoking reset.
- */
- void reset() { }
-
- /**
- * Returns: a random variate distributed according to the
- * \bernoulli_distribution.
- */
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- if(_p == RealType(0))
- return false;
- else
- return RealType(eng() - (eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- /**
- * Writes the parameters of the distribution to a @c std::ostream.
- */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const bernoulli_distribution& bd)
- {
- os << bd._p;
- return os;
- }
-
- /**
- * Reads the parameters of the distribution from a @c std::istream.
- */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, bernoulli_distribution& bd)
- {
- is >> std::ws >> bd._p;
- return is;
- }
-#endif
+ // In principle, this could work with both integer and floating-point
+ // types. Generating floating-point random numbers in the first
+ // place is probably more expensive, so use integer as input.
+ typedef int input_type;
+ typedef bool result_type;
+
+ class param_type
+ {
+ public:
+
+ typedef bernoulli_distribution distribution_type;
+
+ /**
+ * Constructs the parameters of the distribution.
+ *
+ * Requires: 0 <= p <= 1
+ */
+ explicit param_type(RealType p_arg = RealType(0.5))
+ : _p(p_arg)
+ {
+ BOOST_ASSERT(_p >= 0);
+ BOOST_ASSERT(_p <= 1);
+ }
+
+ /** Returns the p parameter of the distribution. */
+ RealType p() const { return _p; }
+
+ /** Writes the parameters to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._p;
+ return os;
+ }
+
+ /** Reads the parameters from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._p;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._p == rhs._p; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _p;
+ };
+
+ /**
+ * Constructs a \bernoulli_distribution object.
+ * p is the parameter of the distribution.
+ *
+ * Requires: 0 <= p <= 1
+ */
+ explicit bernoulli_distribution(const RealType& p_arg = RealType(0.5))
+ : _p(p_arg)
+ {
+ BOOST_ASSERT(_p >= 0);
+ BOOST_ASSERT(_p <= 1);
+ }
+ /**
+ * Constructs \bernoulli_distribution from its parameters
+ */
+ explicit bernoulli_distribution(const param_type& parm)
+ : _p(parm.p()) {}
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /**
+ * Returns: The "p" parameter of the distribution.
+ */
+ RealType p() const { return _p; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ bool min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return false; }
+ /** Returns the largest value that the distribution can produce. */
+ bool max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return true; }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_p); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm) { _p = parm.p(); }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /**
+ * Returns: a random variate distributed according to the
+ * \bernoulli_distribution.
+ */
+ template<class Engine>
+ bool operator()(Engine& eng) const
+ {
+ if(_p == RealType(0))
+ return false;
+ else
+ return RealType(eng() - (eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
+ }
+
+ /**
+ * Returns: a random variate distributed according to the
+ * \bernoulli_distribution with parameters specified by param.
+ */
+ template<class Engine>
+ bool operator()(Engine& eng, const param_type& parm) const
+ {
+ return bernoulli_distribution(parm)(eng);
+ }
+
+ /**
+ * Writes the parameters of the distribution to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, bernoulli_distribution, bd)
+ {
+ os << bd._p;
+ return os;
+ }
+
+ /**
+ * Reads the parameters of the distribution from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, bernoulli_distribution, bd)
+ {
+ is >> bd._p;
+ return is;
+ }
+
+ /**
+ * Returns true iff the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(bernoulli_distribution, lhs, rhs)
+ { return lhs._p == rhs._p; }
+
+ /**
+ * Returns true iff the two distributions will produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(bernoulli_distribution)
private:
- RealType _p;
+ RealType _p;
};
+} // namespace random
+
+using random::bernoulli_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
Modified: branches/release/boost/random/binomial_distribution.hpp
==============================================================================
--- branches/release/boost/random/binomial_distribution.hpp (original)
+++ branches/release/boost/random/binomial_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,6 @@
/* boost random/binomial_distribution.hpp header file
*
- * Copyright Jens Maurer 2002
+ * Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -8,104 +8,415 @@
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
- *
*/
-#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP
-#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP
+#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
+#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
+#include <cstdlib>
+#include <iosfwd>
+
#include <boost/random/detail/config.hpp>
-#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+
+#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
+namespace random {
+
+namespace detail {
+
+template<class RealType>
+struct binomial_table {
+ static const RealType table[10];
+};
+
+template<class RealType>
+const RealType binomial_table<RealType>::table[10] = {
+ 0.08106146679532726,
+ 0.04134069595540929,
+ 0.02767792568499834,
+ 0.02079067210376509,
+ 0.01664469118982119,
+ 0.01387612882307075,
+ 0.01189670994589177,
+ 0.01041126526197209,
+ 0.009255462182712733,
+ 0.008330563433362871
+};
+
+}
/**
* The binomial distribution is an integer valued distribution with
* two parameters, @c t and @c p. The values of the distribution
* are within the range [0,t].
*
- * The probability that the distribution produces a value k is
- * \f${t \choose k}p^k(1-p)^{t-k}\f$.
+ * The distribution function is
+ * \f$\displaystyle P(k) = {t \choose k}p^k(1-p)^{t-k}\f$.
+ *
+ * The algorithm used is the BTRD algorithm described in
+ *
+ * @blockquote
+ * "The generation of binomial random variates", Wolfgang Hormann,
+ * Journal of Statistical Computation and Simulation, Volume 46,
+ * Issue 1 & 2 April 1993 , pages 101 - 110
+ * @endblockquote
*/
template<class IntType = int, class RealType = double>
-class binomial_distribution
-{
+class binomial_distribution {
public:
- typedef typename bernoulli_distribution<RealType>::input_type input_type;
- typedef IntType result_type;
+ typedef IntType result_type;
+ typedef RealType input_type;
- /**
- * Construct an @c binomial_distribution object. @c t and @c p
- * are the parameters of the distribution.
- *
- * Requires: t >=0 && 0 <= p <= 1
- */
- explicit binomial_distribution(IntType t = 1,
- const RealType& p = RealType(0.5))
- : _bernoulli(p), _t(t)
- {
- assert(_t >= 0);
- assert(RealType(0) <= p && p <= RealType(1));
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /** Returns: the @c t parameter of the distribution */
- IntType t() const { return _t; }
- /** Returns: the @c p parameter of the distribution */
- RealType p() const { return _bernoulli.p(); }
- /**
- * Effects: Subsequent uses of the distribution do not depend
- * on values produced by any engine prior to invoking reset.
- */
- void reset() { }
-
- /**
- * Returns: a random variate distributed according to the
- * binomial distribution.
- */
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- // TODO: This is O(_t), but it should be O(log(_t)) for large _t
- result_type n = 0;
- for(IntType i = 0; i < _t; ++i)
- if(_bernoulli(eng))
- ++n;
- return n;
- }
+ class param_type {
+ public:
+ typedef binomial_distribution distribution_type;
+ /**
+ * Construct a param_type object. @c t and @c p
+ * are the parameters of the distribution.
+ *
+ * Requires: t >=0 && 0 <= p <= 1
+ */
+ explicit param_type(IntType t_arg = 1, RealType p_arg = RealType (0.5))
+ : _t(t_arg), _p(p_arg)
+ {}
+ /** Returns the @c t parameter of the distribution. */
+ IntType t() const { return _t; }
+ /** Returns the @c p parameter of the distribution. */
+ RealType p() const { return _p; }
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const param_type& parm)
+ {
+ os << parm._p << " " << parm._t;
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm)
+ {
+ is >> parm._p >> std::ws >> parm._t;
+ return is;
+ }
+#endif
+ /** Returns true if the parameters have the same values. */
+ friend bool operator==(const param_type& lhs, const param_type& rhs)
+ {
+ return lhs._t == rhs._t && lhs._p == rhs._p;
+ }
+ /** Returns true if the parameters have different values. */
+ friend bool operator!=(const param_type& lhs, const param_type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ private:
+ IntType _t;
+ RealType _p;
+ };
+
+ /**
+ * Construct a @c binomial_distribution object. @c t and @c p
+ * are the parameters of the distribution.
+ *
+ * Requires: t >=0 && 0 <= p <= 1
+ */
+ explicit binomial_distribution(IntType t_arg = 1,
+ RealType p_arg = RealType(0.5))
+ : _t(t_arg), _p(p_arg)
+ {
+ init();
+ }
+
+ /**
+ * Construct an @c binomial_distribution object from the
+ * parameters.
+ */
+ explicit binomial_distribution(const param_type& parm)
+ : _t(parm.t()), _p(parm.p())
+ {
+ init();
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * binomial distribution.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng) const
+ {
+ if(use_inversion()) {
+ if(0.5 < _p) {
+ return _t - invert(_t, 1-_p, urng);
+ } else {
+ return invert(_t, _p, urng);
+ }
+ } else if(0.5 < _p) {
+ return _t - generate(urng);
+ } else {
+ return generate(urng);
+ }
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * binomial distribution with parameters specified by @c param.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng, const param_type& parm) const
+ {
+ return binomial_distribution(parm)(urng);
+ }
+
+ /** Returns the @c t parameter of the distribution. */
+ IntType t() const { return _t; }
+ /** Returns the @c p parameter of the distribution. */
+ RealType p() const { return _p; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
+ /** Returns the largest value that the distribution can produce. */
+ IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const { return _t; }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_t, _p); }
+ /** Sets parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _t = parm.t();
+ _p = parm.p();
+ init();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- /**
- * Writes the parameters of the distribution to a @c std::ostream.
- */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const binomial_distribution& bd)
- {
- os << bd._bernoulli << " " << bd._t;
- return os;
- }
-
- /**
- * Reads the parameters of the distribution from a @c std::istream.
- */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, binomial_distribution& bd)
- {
- is >> std::ws >> bd._bernoulli >> std::ws >> bd._t;
- return is;
- }
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const binomial_distribution& bd)
+ {
+ os << bd.param();
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, binomial_distribution& bd)
+ {
+ bd.read(is);
+ return is;
+ }
#endif
+ /** Returns true if the two distributions will produce the same
+ sequence of values, given equal generators. */
+ friend bool operator==(const binomial_distribution& lhs,
+ const binomial_distribution& rhs)
+ {
+ return lhs._t == rhs._t && lhs._p == rhs._p;
+ }
+ /** Returns true if the two distributions could produce different
+ sequences of values, given equal generators. */
+ friend bool operator!=(const binomial_distribution& lhs,
+ const binomial_distribution& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
private:
- bernoulli_distribution<RealType> _bernoulli;
- IntType _t;
+
+ /// @cond show_private
+
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is) {
+ param_type parm;
+ if(is >> parm) {
+ param(parm);
+ }
+ }
+
+ bool use_inversion() const
+ {
+ // BTRD is safe when np >= 10
+ return m < 11;
+ }
+
+ // computes the correction factor for the Stirling approximation
+ // for log(k!)
+ static RealType fc(IntType k)
+ {
+ if(k < 10) return detail::binomial_table<RealType>::table[k];
+ else {
+ RealType ikp1 = RealType(1) / (k + 1);
+ return (RealType(1)/12
+ - (RealType(1)/360
+ - (RealType(1)/1260)*(ikp1*ikp1))*(ikp1*ikp1))*ikp1;
+ }
+ }
+
+ void init()
+ {
+ using std::sqrt;
+ using std::pow;
+
+ RealType p = (0.5 < _p)? (1 - _p) : _p;
+ IntType t = _t;
+
+ m = static_cast<IntType>((t+1)*p);
+
+ if(use_inversion()) {
+ q_n = pow((1 - p), static_cast<RealType>(t));
+ } else {
+ btrd.r = p/(1-p);
+ btrd.nr = (t+1)*btrd.r;
+ btrd.npq = t*p*(1-p);
+ RealType sqrt_npq = sqrt(btrd.npq);
+ btrd.b = 1.15 + 2.53 * sqrt_npq;
+ btrd.a = -0.0873 + 0.0248*btrd.b + 0.01*p;
+ btrd.c = t*p + 0.5;
+ btrd.alpha = (2.83 + 5.1/btrd.b) * sqrt_npq;
+ btrd.v_r = 0.92 - 4.2/btrd.b;
+ btrd.u_rv_r = 0.86*btrd.v_r;
+ }
+ }
+
+ template<class URNG>
+ result_type generate(URNG& urng) const
+ {
+ using std::floor;
+ using std::abs;
+ using std::log;
+
+ while(true) {
+ RealType u;
+ RealType v = uniform_01<RealType>()(urng);
+ if(v <= btrd.u_rv_r) {
+ RealType u = v/btrd.v_r - 0.43;
+ return static_cast<IntType>(floor(
+ (2*btrd.a/(0.5 - abs(u)) + btrd.b)*u + btrd.c));
+ }
+
+ if(v >= btrd.v_r) {
+ u = uniform_01<RealType>()(urng) - 0.5;
+ } else {
+ u = v/btrd.v_r - 0.93;
+ u = ((u < 0)? -0.5 : 0.5) - u;
+ v = uniform_01<RealType>()(urng) * btrd.v_r;
+ }
+
+ RealType us = 0.5 - abs(u);
+ IntType k = static_cast<IntType>(floor((2*btrd.a/us + btrd.b)*u + btrd.c));
+ if(k < 0 || k > _t) continue;
+ v = v*btrd.alpha/(btrd.a/(us*us) + btrd.b);
+ RealType km = abs(k - m);
+ if(km <= 15) {
+ RealType f = 1;
+ if(m < k) {
+ IntType i = m;
+ do {
+ ++i;
+ f = f*(btrd.nr/i - btrd.r);
+ } while(i != k);
+ } else if(m > k) {
+ IntType i = k;
+ do {
+ ++i;
+ v = v*(btrd.nr/i - btrd.r);
+ } while(i != m);
+ }
+ if(v <= f) return k;
+ else continue;
+ } else {
+ // final acceptance/rejection
+ v = log(v);
+ RealType rho =
+ (km/btrd.npq)*(((km/3. + 0.625)*km + 1./6)/btrd.npq + 0.5);
+ RealType t = -km*km/(2*btrd.npq);
+ if(v < t - rho) return k;
+ if(v > t + rho) continue;
+
+ IntType nm = _t - m + 1;
+ RealType h = (m + 0.5)*log((m + 1)/(btrd.r*nm))
+ + fc(m) + fc(_t - m);
+
+ IntType nk = _t - k + 1;
+ if(v <= h + (_t+1)*log(static_cast<RealType>(nm)/nk)
+ + (k + 0.5)*log(nk*btrd.r/(k+1))
+ - fc(k)
+ - fc(_t - k))
+ {
+ return k;
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+
+ template<class URNG>
+ IntType invert(IntType t, RealType p, URNG& urng) const
+ {
+ RealType q = 1 - p;
+ RealType s = p / q;
+ RealType a = (t + 1) * s;
+ RealType r = q_n;
+ RealType u = uniform_01<RealType>()(urng);
+ IntType x = 0;
+ while(u > r) {
+ u = u - r;
+ ++x;
+ r = ((a/x) - s) * r;
+ }
+ return x;
+ }
+
+ // parameters
+ IntType _t;
+ RealType _p;
+
+ // common data
+ IntType m;
+
+ union {
+ // for btrd
+ struct {
+ RealType r;
+ RealType nr;
+ RealType npq;
+ RealType b;
+ RealType a;
+ RealType c;
+ RealType alpha;
+ RealType v_r;
+ RealType u_rv_r;
+ } btrd;
+ // for inversion
+ RealType q_n;
+ };
+
+ /// @endcond
};
-} // namespace boost
+}
+
+// backwards compatibility
+using random::binomial_distribution;
+
+}
-#endif // BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP
+#include <boost/random/detail/enable_warnings.hpp>
+
+#endif
Modified: branches/release/boost/random/cauchy_distribution.hpp
==============================================================================
--- branches/release/boost/random/cauchy_distribution.hpp (original)
+++ branches/release/boost/random/cauchy_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,105 +17,198 @@
#define BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <iostream>
+#include <iosfwd>
+#include <istream>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/uniform_01.hpp>
namespace boost {
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-// Special gcc workaround: gcc 2.95.x ignores using-declarations
-// in template classes (confirmed by gcc author Martin v. Loewis)
- using std::tan;
-#endif
+namespace random {
// Cauchy distribution:
/**
* The cauchy distribution is a continuous distribution with two
- * parameters, sigma and median.
+ * parameters, median and sigma.
*
- * It has \f$p(x) = \frac{\sigma}{\pi(\sigma^2 + (x-m)^2)}\f$
+ * It has \f$\displaystyle p(x) = \frac{\sigma}{\pi(\sigma^2 + (x-m)^2)}\f$
*/
template<class RealType = double>
class cauchy_distribution
{
public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
-
- /**
- * Constructs a \cauchy_distribution with the paramters @c median
- * and @c sigma.
- */
- explicit cauchy_distribution(result_type median_arg = result_type(0),
- result_type sigma_arg = result_type(1))
- : _median(median_arg), _sigma(sigma_arg) { }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: the "median" parameter of the distribution
- */
- result_type median() const { return _median; }
- /**
- * Returns: the "sigma" parameter of the distribution
- */
- result_type sigma() const { return _sigma; }
- /**
- * Effects: Subsequent uses of the distribution do not depend
- * on values produced by any engine prior to invoking reset.
- */
- void reset() { }
-
- /**
- * Returns: A random variate distributed according to the
- * cauchy distribution.
- */
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- // Can we have a boost::mathconst please?
- const result_type pi = result_type(3.14159265358979323846);
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::tan;
-#endif
- return _median + _sigma * tan(pi*(eng()-result_type(0.5)));
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- /**
- * Writes the parameters of the distribution to a @c std::ostream.
- */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const cauchy_distribution& cd)
- {
- os << cd._median << " " << cd._sigma;
- return os;
- }
-
- /**
- * Reads the parameters of the distribution from a @c std::istream.
- */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, cauchy_distribution& cd)
- {
- is >> std::ws >> cd._median >> std::ws >> cd._sigma;
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef cauchy_distribution distribution_type;
+
+ /** Constructs the parameters of the cauchy distribution. */
+ explicit param_type(RealType median_arg = RealType(0.0),
+ RealType sigma_arg = RealType(1.0))
+ : _median(median_arg), _sigma(sigma_arg) {}
+
+ // backwards compatibility for Boost.Random
+
+ /** Returns the median of the distribution. */
+ RealType median() const { return _median; }
+ /** Returns the sigma parameter of the distribution. */
+ RealType sigma() const { return _sigma; }
+
+ // The new names in C++0x.
+
+ /** Returns the median of the distribution. */
+ RealType a() const { return _median; }
+ /** Returns the sigma parameter of the distribution. */
+ RealType b() const { return _sigma; }
+
+ /** Writes the parameters to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._median << " " << parm._sigma;
+ return os;
+ }
+
+ /** Reads the parameters from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._median >> std::ws >> parm._sigma;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._median == rhs._median && lhs._sigma == rhs._sigma; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _median;
+ RealType _sigma;
+ };
+
+ /**
+ * Constructs a \cauchy_distribution with the paramters @c median
+ * and @c sigma.
+ */
+ explicit cauchy_distribution(RealType median_arg = RealType(0.0),
+ RealType sigma_arg = RealType(1.0))
+ : _median(median_arg), _sigma(sigma_arg) { }
+
+ /**
+ * Constructs a \cauchy_distribution from it's parameters.
+ */
+ explicit cauchy_distribution(const param_type& parm)
+ : _median(parm.median()), _sigma(parm.sigma()) { }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ // backwards compatibility for Boost.Random
+
+ /** Returns: the "median" parameter of the distribution */
+ RealType median() const { return _median; }
+ /** Returns: the "sigma" parameter of the distribution */
+ RealType sigma() const { return _sigma; }
+
+ // The new names in C++0x
+
+ /** Returns: the "median" parameter of the distribution */
+ RealType a() const { return _median; }
+ /** Returns: the "sigma" parameter of the distribution */
+ RealType b() const { return _sigma; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return -(std::numeric_limits<RealType>::infinity)(); }
+
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::infinity)(); }
+
+ param_type param() const { return param_type(_median, _sigma); }
+
+ void param(const param_type& parm)
+ {
+ _median = parm.median();
+ _sigma = parm.sigma();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /**
+ * Returns: A random variate distributed according to the
+ * cauchy distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
+ // Can we have a boost::mathconst please?
+ const result_type pi = result_type(3.14159265358979323846);
+ using std::tan;
+ RealType val = uniform_01<RealType>()(eng)-result_type(0.5);
+ return _median + _sigma * tan(pi*val);
+ }
+
+ /**
+ * Returns: A random variate distributed according to the
+ * cauchy distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm)
+ {
+ return cauchy_distribution(parm)(eng);
+ }
+
+ /**
+ * Writes the distribution to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, cauchy_distribution, cd)
+ {
+ os << cd._median << " " << cd._sigma;
+ return os;
+ }
+
+ /**
+ * Reads the distribution from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, cauchy_distribution, cd)
+ {
+ is >> cd._median >> std::ws >> cd._sigma;
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce
+ * identical sequences of values, given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(cauchy_distribution, lhs, rhs)
+ { return lhs._median == rhs._median && lhs._sigma == rhs._sigma; }
+
+ /**
+ * Returns true if the two distributions may produce
+ * different sequences of values, given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(cauchy_distribution)
private:
- result_type _median, _sigma;
+ RealType _median;
+ RealType _sigma;
};
+} // namespace random
+
+using random::cauchy_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
Copied: branches/release/boost/random/chi_squared_distribution.hpp (from r67669, /trunk/boost/random/chi_squared_distribution.hpp)
==============================================================================
--- /trunk/boost/random/chi_squared_distribution.hpp (original)
+++ branches/release/boost/random/chi_squared_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -187,7 +187,7 @@
private:
- /// @cond
+ /// @cond show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
Modified: branches/release/boost/random/detail/const_mod.hpp
==============================================================================
--- branches/release/boost/random/detail/const_mod.hpp (original)
+++ branches/release/boost/random/detail/const_mod.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,113 +16,101 @@
#ifndef BOOST_RANDOM_CONST_MOD_HPP
#define BOOST_RANDOM_CONST_MOD_HPP
-#include <cassert>
+#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
-#include <boost/cstdint.hpp>
#include <boost/integer_traits.hpp>
-#include <boost/detail/workaround.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/random/detail/large_arithmetic.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
-/*
- * Some random number generators require modular arithmetic. Put
- * everything we need here.
- * IntType must be an integral type.
- */
-
-namespace detail {
-
- template<bool is_signed>
- struct do_add
- { };
-
- template<>
- struct do_add<true>
- {
- template<class IntType>
- static IntType add(IntType m, IntType x, IntType c)
- {
- if (x < m - c)
- return x + c;
- else
- return x - (m-c);
- }
- };
-
- template<>
- struct do_add<false>
- {
- template<class IntType>
- static IntType add(IntType, IntType, IntType)
- {
- // difficult
- assert(!"const_mod::add with c too large");
- return 0;
- }
- };
-} // namespace detail
-
-#if !(defined(__BORLANDC__) && (__BORLANDC__ == 0x560))
-
template<class IntType, IntType m>
class const_mod
{
public:
+ static IntType apply(IntType x)
+ {
+ if(((unsigned_m() - 1) & unsigned_m()) == 0)
+ return (unsigned_type(x)) & (unsigned_m() - 1);
+ else {
+ IntType supress_warnings = (m == 0);
+ BOOST_ASSERT(supress_warnings == 0);
+ return x % (m + supress_warnings);
+ }
+ }
+
static IntType add(IntType x, IntType c)
{
- if(c == 0)
+ if(((unsigned_m() - 1) & unsigned_m()) == 0)
+ return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
+ else if(c == 0)
return x;
- else if(c <= traits::const_max - m) // i.e. m+c < max
- return add_small(x, c);
+ else if(x < m - c)
+ return x + c;
else
- return detail::do_add<traits::is_signed>::add(m, x, c);
+ return x - (m - c);
}
static IntType mult(IntType a, IntType x)
{
- if(a == 1)
+ if(((unsigned_m() - 1) & unsigned_m()) == 0)
+ return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1);
+ else if(a == 0)
+ return 0;
+ else if(a == 1)
return x;
else if(m <= traits::const_max/a) // i.e. a*m <= max
return mult_small(a, x);
else if(traits::is_signed && (m%a < m/a))
return mult_schrage(a, x);
- else {
- // difficult
- assert(!"const_mod::mult with a too large");
- return 0;
- }
+ else
+ return mult_general(a, x);
}
static IntType mult_add(IntType a, IntType x, IntType c)
{
- if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max
- return (a*x+c) % m;
- else
+ if(((unsigned_m() - 1) & unsigned_m()) == 0)
+ return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
+ else if(a == 0)
+ return c;
+ else if(m <= (traits::const_max-c)/a) { // i.e. a*m+c <= max
+ IntType supress_warnings = (m == 0);
+ BOOST_ASSERT(supress_warnings == 0);
+ return (a*x+c) % (m + supress_warnings);
+ } else
return add(mult(a, x), c);
}
+ static IntType pow(IntType a, boost::uintmax_t exponent)
+ {
+ IntType result = 1;
+ while(exponent != 0) {
+ if(exponent % 2 == 1) {
+ result = mult(result, a);
+ }
+ a = mult(a, a);
+ exponent /= 2;
+ }
+ return result;
+ }
+
static IntType invert(IntType x)
- { return x == 0 ? 0 : invert_euclidian(x); }
+ { return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); }
private:
typedef integer_traits<IntType> traits;
+ typedef typename make_unsigned<IntType>::type unsigned_type;
const_mod(); // don't instantiate
- static IntType add_small(IntType x, IntType c)
- {
- x += c;
- if(x >= m)
- x -= m;
- return x;
- }
-
static IntType mult_small(IntType a, IntType x)
{
- return a*x % m;
+ IntType supress_warnings = (m == 0);
+ BOOST_ASSERT(supress_warnings == 0);
+ return a*x % (m + supress_warnings);
}
static IntType mult_schrage(IntType a, IntType value)
@@ -130,231 +118,96 @@
const IntType q = m / a;
const IntType r = m % a;
- assert(r < q); // check that overflow cannot happen
+ BOOST_ASSERT(r < q); // check that overflow cannot happen
- value = a*(value%q) - r*(value/q);
- // An optimizer bug in the SGI MIPSpro 7.3.1.x compiler requires this
- // convoluted formulation of the loop (Synge Todo)
- for(;;) {
- if (value > 0)
- break;
- value += m;
+ return sub(a*(value%q), r*(value/q));
+ }
+
+ static IntType mult_general(IntType a, IntType b)
+ {
+ IntType suppress_warnings = (m == 0);
+ BOOST_ASSERT(suppress_warnings == 0);
+ IntType modulus = m + suppress_warnings;
+ BOOST_ASSERT(modulus == m);
+ if(::boost::uintmax_t(modulus) <=
+ (::std::numeric_limits< ::boost::uintmax_t>::max)() / modulus)
+ {
+ return static_cast<IntType>(boost::uintmax_t(a) * b % modulus);
+ } else {
+ return static_cast<IntType>(detail::mulmod(a, b, modulus));
}
- return value;
+ }
+
+ static IntType sub(IntType a, IntType b)
+ {
+ if(a < b)
+ return m - (b - a);
+ else
+ return a - b;
+ }
+
+ static unsigned_type unsigned_m()
+ {
+ if(m == 0) {
+ return unsigned_type((std::numeric_limits<IntType>::max)()) + 1;
+ } else {
+ return unsigned_type(m);
+ }
}
// invert c in the finite field (mod m) (m must be prime)
static IntType invert_euclidian(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
- BOOST_STATIC_ASSERT(m > 0);
-#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
- assert(boost::integer_traits<IntType>::is_signed);
-#elif !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
- BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed);
-#endif
- assert(c > 0);
+ BOOST_ASSERT(c > 0);
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
for(;;) {
IntType q = p / n;
- l1 -= q * l2; // this requires a signed IntType!
+ l1 += q * l2;
p -= q * n;
if(p == 0)
- return (l2 < 1 ? l2 + m : l2);
+ return l2;
IntType q2 = n / p;
- l2 -= q2 * l1;
+ l2 += q2 * l1;
n -= q2 * p;
if(n == 0)
- return (l1 < 1 ? l1 + m : l1);
+ return m - l1;
}
}
-};
-
-// The modulus is exactly the word size: rely on machine overflow handling.
-// Due to a GCC bug, we cannot partially specialize in the presence of
-// template value parameters.
-template<>
-class const_mod<unsigned int, 0>
-{
- typedef unsigned int IntType;
-public:
- static IntType add(IntType x, IntType c) { return x+c; }
- static IntType mult(IntType a, IntType x) { return a*x; }
- static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
-
- // m is not prime, thus invert is not useful
-private: // don't instantiate
- const_mod();
-};
-template<>
-class const_mod<unsigned long, 0>
-{
- typedef unsigned long IntType;
-public:
- static IntType add(IntType x, IntType c) { return x+c; }
- static IntType mult(IntType a, IntType x) { return a*x; }
- static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
-
- // m is not prime, thus invert is not useful
-private: // don't instantiate
- const_mod();
-};
-
-// the modulus is some power of 2: rely partly on machine overflow handling
-// we only specialize for rand48 at the moment
-#ifndef BOOST_NO_INT64_T
-template<>
-class const_mod<uint64_t, uint64_t(1) << 48>
-{
- typedef uint64_t IntType;
-public:
- static IntType add(IntType x, IntType c) { return c == 0 ? x : mod(x+c); }
- static IntType mult(IntType a, IntType x) { return mod(a*x); }
- static IntType mult_add(IntType a, IntType x, IntType c)
- { return mod(a*x+c); }
- static IntType mod(IntType x) { return x &= ((uint64_t(1) << 48)-1); }
-
- // m is not prime, thus invert is not useful
-private: // don't instantiate
- const_mod();
-};
-#endif /* !BOOST_NO_INT64_T */
-
-#else
-
-//
-// for some reason Borland C++ Builder 6 has problems with
-// the full specialisations of const_mod, define a generic version
-// instead, the compiler will optimise away the const-if statements:
-//
-
-template<class IntType, IntType m>
-class const_mod
-{
-public:
- static IntType add(IntType x, IntType c)
- {
- if(0 == m)
- {
- return x+c;
- }
- else
- {
- if(c == 0)
- return x;
- else if(c <= traits::const_max - m) // i.e. m+c < max
- return add_small(x, c);
- else
- return detail::do_add<traits::is_signed>::add(m, x, c);
- }
- }
-
- static IntType mult(IntType a, IntType x)
- {
- if(x == 0)
- {
- return a*x;
- }
- else
- {
- if(a == 1)
- return x;
- else if(m <= traits::const_max/a) // i.e. a*m <= max
- return mult_small(a, x);
- else if(traits::is_signed && (m%a < m/a))
- return mult_schrage(a, x);
- else {
- // difficult
- assert(!"const_mod::mult with a too large");
- return 0;
- }
- }
- }
-
- static IntType mult_add(IntType a, IntType x, IntType c)
- {
- if(m == 0)
- {
- return a*x+c;
- }
- else
- {
- if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max
- return (a*x+c) % m;
- else
- return add(mult(a, x), c);
- }
- }
-
- static IntType invert(IntType x)
- { return x == 0 ? 0 : invert_euclidian(x); }
-
-private:
- typedef integer_traits<IntType> traits;
-
- const_mod(); // don't instantiate
-
- static IntType add_small(IntType x, IntType c)
- {
- x += c;
- if(x >= m)
- x -= m;
- return x;
- }
-
- static IntType mult_small(IntType a, IntType x)
- {
- return a*x % m;
- }
-
- static IntType mult_schrage(IntType a, IntType value)
- {
- const IntType q = m / a;
- const IntType r = m % a;
-
- assert(r < q); // check that overflow cannot happen
-
- value = a*(value%q) - r*(value/q);
- while(value <= 0)
- value += m;
- return value;
- }
-
- // invert c in the finite field (mod m) (m must be prime)
- static IntType invert_euclidian(IntType c)
+ // invert c in the finite field (mod m) (c must be relatively prime to m)
+ static IntType invert_euclidian0(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
- BOOST_STATIC_ASSERT(m > 0);
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed);
-#endif
- assert(c > 0);
+ BOOST_ASSERT(c > 0);
+ if(c == 1) return 1;
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
+ IntType max = (std::numeric_limits<IntType>::max)();
+ IntType q = max / n;
+ BOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m.");
+ l1 += q * l2;
+ p = max - q * n + 1;
for(;;) {
- IntType q = p / n;
- l1 -= q * l2; // this requires a signed IntType!
- p -= q * n;
if(p == 0)
- return (l2 < 1 ? l2 + m : l2);
+ return l2;
IntType q2 = n / p;
- l2 -= q2 * l1;
+ l2 += q2 * l1;
n -= q2 * p;
if(n == 0)
- return (l1 < 1 ? l1 + m : l1);
+ return m - l1;
+ q = p / n;
+ l1 += q * l2;
+ p -= q * n;
}
}
};
-
-#endif
-
} // namespace random
} // namespace boost
Copied: branches/release/boost/random/detail/integer_log2.hpp (from r69961, /trunk/boost/random/detail/integer_log2.hpp)
==============================================================================
--- /trunk/boost/random/detail/integer_log2.hpp (original)
+++ branches/release/boost/random/detail/integer_log2.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -7,13 +7,14 @@
*
* See http://www.boost.org for most recent version including documentation.
*
- * $Id: independent_bits.hpp 68822 2011-02-13 03:28:59Z steven_watanabe $
+ * $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
#define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
+#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/pending/integer_log2.hpp>
@@ -21,11 +22,21 @@
namespace random {
namespace detail {
+#if !defined(BOOST_NO_CONSTEXPR)
+#define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr
+#elif defined(BOOST_MSVC)
+#define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline
+#elif defined(__GNUC__) && __GNUC__ >= 4
+#define BOOST_RANDOM_DETAIL_CONSTEXPR __attribute__((const)) __attribute__((always_inline))
+#else
+#define BOOST_RANDOM_DETAIL_CONSTEXPR inline
+#endif
+
template<int Shift>
struct integer_log2_impl
{
template<class T>
- static int apply(T t, int accum)
+ BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
{
int update = ((t >> Shift) != 0) * Shift;
return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
@@ -36,14 +47,14 @@
struct integer_log2_impl<1>
{
template<class T>
- static int apply(T t, int accum)
+ BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
{
return int(t >> 1) + accum;
}
};
template<class T>
-inline int integer_log2(T t)
+BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t)
{
return integer_log2_impl<
::boost::detail::max_pow2_less<
Copied: branches/release/boost/random/detail/large_arithmetic.hpp (from r70047, /trunk/boost/random/detail/large_arithmetic.hpp)
==============================================================================
--- /trunk/boost/random/detail/large_arithmetic.hpp (original)
+++ branches/release/boost/random/detail/large_arithmetic.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -29,7 +29,7 @@
boost::uintmax_t remainder;
};
-div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
+inline div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{
static const int bits =
::std::numeric_limits< ::boost::uintmax_t>::digits / 2;
@@ -107,10 +107,10 @@
return result;
}
-boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
+inline boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{ return detail::muldivmod(a, b, m).quotient; }
-boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
+inline boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{ return detail::muldivmod(a, b, m).remainder; }
} // namespace detail
Copied: branches/release/boost/random/detail/operators.hpp (from r63286, /trunk/boost/random/detail/operators.hpp)
==============================================================================
--- /trunk/boost/random/detail/operators.hpp (original)
+++ branches/release/boost/random/detail/operators.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,6 @@
/* boost random/detail/operators.hpp header file
*
- * Copyright Steven Watanabe 2010
+ * Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -14,8 +14,10 @@
#define BOOST_RANDOM_DETAIL_OPERATORS_HPP
#include <boost/random/detail/config.hpp>
+#include <boost/detail/workaround.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \
+ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
template<class CharT, class Traits> \
@@ -41,6 +43,19 @@
#endif
+#if defined(__BORLANDC__)
+
+#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
+ bool operator==(const T& rhs) const \
+ { return T::is_equal(*this, rhs); } \
+ static bool is_equal(const T& lhs, const T& rhs)
+
+#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
+ bool operator!=(const T& rhs) const \
+ { return !T::is_equal(*this, rhs); }
+
+#endif
+
#ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR
#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
template<class CharT, class Traits> \
Deleted: branches/release/boost/random/detail/pass_through_engine.hpp
==============================================================================
--- branches/release/boost/random/detail/pass_through_engine.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
+++ (empty file)
@@ -1,100 +0,0 @@
-/* boost random/detail/uniform_int_float.hpp header file
- *
- * Copyright Jens Maurer 2000-2001
- * 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)
- *
- * See http://www.boost.org for most recent version including documentation.
- *
- * $Id$
- *
- */
-
-#ifndef BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP
-#define BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP
-
-#include <boost/config.hpp>
-#include <boost/random/detail/ptr_helper.hpp>
-#include <boost/random/detail/disable_warnings.hpp>
-
-namespace boost {
-namespace random {
-namespace detail {
-
-template<class UniformRandomNumberGenerator>
-class pass_through_engine
-{
-private:
- typedef ptr_helper<UniformRandomNumberGenerator> helper_type;
-
-public:
- typedef typename helper_type::value_type base_type;
- typedef typename base_type::result_type result_type;
-
- explicit pass_through_engine(UniformRandomNumberGenerator rng)
- // make argument an rvalue to avoid matching Generator& constructor
- : _rng(static_cast<typename helper_type::rvalue_type>(rng))
- { }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().min)(); }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().max)(); }
- base_type& base() { return helper_type::ref(_rng); }
- const base_type& base() const { return helper_type::ref(_rng); }
-
- result_type operator()() { return base()(); }
-
-private:
- UniformRandomNumberGenerator _rng;
-};
-
-#ifndef BOOST_NO_STD_LOCALE
-
-template<class UniformRandomNumberGenerator, class CharT, class Traits>
-std::basic_ostream<CharT,Traits>&
-operator<<(
- std::basic_ostream<CharT,Traits>& os
- , const pass_through_engine<UniformRandomNumberGenerator>& ud
- )
-{
- return os << ud.base();
-}
-
-template<class UniformRandomNumberGenerator, class CharT, class Traits>
-std::basic_istream<CharT,Traits>&
-operator>>(
- std::basic_istream<CharT,Traits>& is
- , const pass_through_engine<UniformRandomNumberGenerator>& ud
- )
-{
- return is >> ud.base();
-}
-
-#else // no new streams
-
-template<class UniformRandomNumberGenerator>
-inline std::ostream&
-operator<<(std::ostream& os,
- const pass_through_engine<UniformRandomNumberGenerator>& ud)
-{
- return os << ud.base();
-}
-
-template<class UniformRandomNumberGenerator>
-inline std::istream&
-operator>>(std::istream& is,
- const pass_through_engine<UniformRandomNumberGenerator>& ud)
-{
- return is >> ud.base();
-}
-
-#endif
-
-} // namespace detail
-} // namespace random
-} // namespace boost
-
-#include <boost/random/detail/enable_warnings.hpp>
-
-#endif // BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP
-
Modified: branches/release/boost/random/detail/seed.hpp
==============================================================================
--- branches/release/boost/random/detail/seed.hpp (original)
+++ branches/release/boost/random/detail/seed.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -43,12 +43,19 @@
template<class Generator> \
void seed(Generator& gen, typename ::boost::random::detail::disable_seed<Generator>::type* = 0)
+#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \
+ template<class SeedSeq> \
+ explicit Self(SeedSeq& seq, typename ::boost::random::detail::disable_constructor<Self, SeedSeq>::type* = 0)
+
+#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \
+ template<class SeedSeq> \
+ void seed(SeedSeq& seq, typename ::boost::random::detail::disable_seed<SeedSeq>::type* = 0)
+
#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \
explicit Self(const T& x)
#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \
void seed(const T& x)
-
}
}
}
@@ -76,6 +83,24 @@
template<class Generator>\
void boost_random_seed_impl(Generator& gen, ::boost::mpl::false_)
+#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \
+ Self(Self& other) { *this = other; } \
+ Self(const Self& other) { *this = other; } \
+ template<class SeedSeq> \
+ explicit Self(SeedSeq& seq) { \
+ boost_random_constructor_impl(seq, ::boost::is_arithmetic<SeedSeq>());\
+ } \
+ template<class SeedSeq> \
+ void boost_random_constructor_impl(SeedSeq& seq, ::boost::mpl::false_)
+
+#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \
+ template<class SeedSeq> \
+ void seed(SeedSeq& seq) { \
+ boost_random_seed_impl(seq, ::boost::is_arithmetic<SeedSeq>()); \
+ } \
+ template<class SeedSeq> \
+ void boost_random_seed_impl(SeedSeq& seq, ::boost::mpl::false_)
+
#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \
explicit Self(const T& x) { boost_random_constructor_impl(x, ::boost::mpl::true_()); }\
void boost_random_constructor_impl(const T& x, ::boost::mpl::true_)
Copied: branches/release/boost/random/detail/seed_impl.hpp (from r68758, /trunk/boost/random/detail/seed_impl.hpp)
==============================================================================
--- /trunk/boost/random/detail/seed_impl.hpp (original)
+++ branches/release/boost/random/detail/seed_impl.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,50 +13,118 @@
#ifndef BOOST_RANDOM_DETAIL_SEED_IMPL_HPP
#define BOOST_RANDOM_DETAIL_SEED_IMPL_HPP
+#include <stdexcept>
#include <boost/cstdint.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
#include <boost/random/detail/const_mod.hpp>
+#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
+#include <boost/random/detail/disable_warnings.hpp>
+
namespace boost {
namespace random {
namespace detail {
-template<class Engine, int Bits, class Iter>
+// finds the seed type of an engine, given its
+// result_type. If the result_type is integral
+// the seed type is the same. If the result_type
+// is floating point, the seed type is uint32_t
+template<class T>
+struct seed_type
+{
+ typedef typename boost::mpl::if_<boost::is_integral<T>,
+ T,
+ boost::uint32_t
+ >::type type;
+};
+
+template<int N>
+struct const_pow_impl
+{
+ template<class T>
+ static T call(T arg, int n, T result)
+ {
+ return const_pow_impl<N / 2>::call(arg * arg, n / 2,
+ n%2 == 0? result : result * arg);
+ }
+};
+
+template<>
+struct const_pow_impl<0>
+{
+ template<class T>
+ static T call(T, int, T result)
+ {
+ return result;
+ }
+};
+
+// requires N is an upper bound on n
+template<int N, class T>
+inline T const_pow(T arg, int n) { return const_pow_impl<N>::call(arg, n, T(1)); }
+
+template<class T>
+inline T pow2(int n)
+{
+ typedef unsigned int_type;
+ const int max_bits = std::numeric_limits<int_type>::digits;
+ T multiplier = T(int_type(1) << (max_bits - 1)) * 2;
+ return (int_type(1) << (n % max_bits)) *
+ const_pow<std::numeric_limits<T>::digits / max_bits>(multiplier, n / max_bits);
+}
+
+template<class Engine, class Iter>
void generate_from_real(Engine& eng, Iter begin, Iter end)
{
+ using std::fmod;
typedef typename Engine::result_type RealType;
+ const int Bits = Engine::precision();
int remaining_bits = 0;
- boost::uint32_t saved_bits;
- RealType mult32 = 4294967296.0; // 2^32
- for(; begin != end; ++begin) {
- RealType val = eng();
+ boost::uint_least32_t saved_bits = 0;
+ RealType multiplier = pow2<RealType>( Bits);
+ RealType mult32 = RealType(4294967296.0); // 2^32
+ while(true) {
+ RealType val = eng() * multiplier;
int available_bits = Bits;
- if(available_bits < 32 - remaining_bits) {
- saved_bits |= boost::uint32_t(val * mult32) >> remaining_bits;
- remaining_bits += available_bits;
+ // Make sure the compiler can optimize this out
+ // if it isn't possible.
+ if(Bits < 32 && available_bits < 32 - remaining_bits) {
+ saved_bits |= boost::uint_least32_t(val) << remaining_bits;
+ remaining_bits += Bits;
} else {
- if(remaining_bits != 0) {
- val *= boost::uint32_t(1) << (32 - remaining_bits);
- boost::uint32_t extra_bits = boost::uint32_t(val);
- val -= extra_bits;
- *begin++ = saved_bits | extra_bits;
- if(begin == end) break;
+ // If Bits < 32, then remaining_bits != 0, since
+ // if remaining_bits == 0, available_bits < 32 - 0,
+ // and we won't get here to begin with.
+ if(Bits < 32 || remaining_bits != 0) {
+ boost::uint_least32_t divisor =
+ (boost::uint_least32_t(1) << (32 - remaining_bits));
+ boost::uint_least32_t extra_bits = boost::uint_least32_t(fmod(val, mult32)) & (divisor - 1);
+ val = val / divisor;
+ *begin++ = saved_bits | (extra_bits << remaining_bits);
+ if(begin == end) return;
available_bits -= 32 - remaining_bits;
remaining_bits = 0;
}
- for(; available_bits >= 32; available_bits -= 32) {
- val *= mult32;
- boost::uint32_t word = boost::uint32_t(val);
- val -= word;
- *begin++ = word;
- if(begin == end) break;
+ // If Bits < 32 we should never enter this loop
+ if(Bits >= 32) {
+ for(; available_bits >= 32; available_bits -= 32) {
+ boost::uint_least32_t word = boost::uint_least32_t(fmod(val, mult32));
+ val /= mult32;
+ *begin++ = word;
+ if(begin == end) return;
+ }
}
remaining_bits = available_bits;
- saved_bits = boost::uint32_t(val * mult32);
+ saved_bits = static_cast<boost::uint_least32_t>(val);
}
}
}
@@ -67,60 +135,126 @@
typedef typename Engine::result_type IntType;
typedef typename boost::make_unsigned<IntType>::type unsigned_type;
int remaining_bits = 0;
- boost::uint32_t saved_bits;
+ boost::uint_least32_t saved_bits = 0;
unsigned_type range = boost::random::detail::subtract<IntType>()((eng.max)(), (eng.min)());
- int bits = 0;
- unsigned_type mask = 0;
- for(; bits < std::numeric_limits<unsigned_type>::digits; ++bits)
+
+ int bits =
+ (range == (std::numeric_limits<unsigned_type>::max)()) ?
+ std::numeric_limits<unsigned_type>::digits :
+ detail::integer_log2(range + 1);
+
{
- unsigned_type test = mask | (unsigned_type(1) << bits);
- if(test <= range) {
- mask = test;
- } else {
- break;
+ int discarded_bits = detail::integer_log2(bits);
+ unsigned_type excess = (range + 1) >> (bits - discarded_bits);
+ if(excess != 0) {
+ int extra_bits = detail::integer_log2((excess - 1) ^ excess);
+ bits = bits - discarded_bits + extra_bits;
}
}
- for(; begin != end; ++begin) {
+
+ unsigned_type mask = (static_cast<unsigned_type>(2) << (bits - 1)) - 1;
+ unsigned_type limit = ((range + 1) & ~mask) - 1;
+
+ while(true) {
unsigned_type val;
do {
val = boost::random::detail::subtract<IntType>()(eng(), (eng.min)());
- } while(val > mask);
+ } while(limit != range && val > limit);
+ val &= mask;
int available_bits = bits;
- if(available_bits < 32 - remaining_bits) {
- saved_bits |= boost::uint32_t(val) << remaining_bits;
+ if(available_bits == 32) {
+ *begin++ = static_cast<boost::uint_least32_t>(val) & 0xFFFFFFFFu;
+ if(begin == end) return;
+ } else if(available_bits % 32 == 0) {
+ for(int i = 0; i < available_bits / 32; ++i) {
+ boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu;
+ int supress_warning = (bits >= 32);
+ BOOST_ASSERT(supress_warning == 1);
+ val >>= (32 * supress_warning);
+ *begin++ = word;
+ if(begin == end) return;
+ }
+ } else if(bits < 32 && available_bits < 32 - remaining_bits) {
+ saved_bits |= boost::uint_least32_t(val) << remaining_bits;
remaining_bits += bits;
} else {
- if(remaining_bits != 0) {
- boost::uint32_t extra_bits = boost::uint32_t(val) & ((boost::uint32_t(1) << (32 - remaining_bits)) - 1);
+ if(bits < 32 || remaining_bits != 0) {
+ boost::uint_least32_t extra_bits = boost::uint_least32_t(val) & ((boost::uint_least32_t(1) << (32 - remaining_bits)) - 1);
val >>= 32 - remaining_bits;
*begin++ = saved_bits | (extra_bits << remaining_bits);
- if(begin == end) break;
+ if(begin == end) return;
available_bits -= 32 - remaining_bits;
remaining_bits = 0;
}
- for(; available_bits >= 32; available_bits -= 32) {
- boost::uint32_t word = boost::uint32_t(val);
- val >>= 32;
- *begin++ = word;
- if(begin == end) break;
+ if(bits >= 32) {
+ for(; available_bits >= 32; available_bits -= 32) {
+ boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu;
+ int supress_warning = (bits >= 32);
+ BOOST_ASSERT(supress_warning == 1);
+ val >>= (32 * supress_warning);
+ *begin++ = word;
+ if(begin == end) return;
+ }
}
remaining_bits = available_bits;
- saved_bits = val;
+ saved_bits = static_cast<boost::uint_least32_t>(val);
}
}
}
+template<class Engine, class Iter>
+void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::true_)
+{
+ return detail::generate_from_int(eng, first, last);
+}
+
+template<class Engine, class Iter>
+void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::false_)
+{
+ return detail::generate_from_real(eng, first, last);
+}
+
+template<class Engine, class Iter>
+void generate(Engine& eng, Iter first, Iter last)
+{
+ return detail::generate_impl(eng, first, last, boost::is_integral<typename Engine::result_type>());
+}
+
+
+
template<class IntType, IntType m, class SeedSeq>
IntType seed_one_int(SeedSeq& seq)
{
- static const int log = ::boost::static_log2<m>::value;
+ static const int log = ::boost::mpl::if_c<(m == 0),
+ ::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
+ ::boost::static_log2<m> >::type::value;
static const int k =
- (log + ((~(static_cast<IntType>(1) << log) & m)? 32 : 31)) / 32;
- boost::uint_least32_t array[k + 3];
+ (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
+ ::boost::uint_least32_t array[log / 32 + 4];
seq.generate(&array[0], &array[0] + k + 3);
IntType s = 0;
for(int j = 0; j < k; ++j) {
- IntType digit = IntType(array[j+3]) % m;
+ IntType digit = const_mod<IntType, m>::apply(IntType(array[j+3]));
+ IntType mult = IntType(1) << 32*j;
+ s = const_mod<IntType, m>::mult_add(mult, digit, s);
+ }
+ return s;
+}
+
+template<class IntType, IntType m, class Iter>
+IntType get_one_int(Iter& first, Iter last)
+{
+ static const int log = ::boost::mpl::if_c<(m == 0),
+ ::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
+ ::boost::static_log2<m> >::type::value;
+ static const int k =
+ (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
+ IntType s = 0;
+ for(int j = 0; j < k; ++j) {
+ if(first == last) {
+ throw ::std::invalid_argument("Not enough elements in call to seed.");
+ }
+ IntType digit = const_mod<IntType, m>::apply(IntType(*first++));
IntType mult = IntType(1) << 32*j;
s = const_mod<IntType, m>::mult_add(mult, digit, s);
}
@@ -161,8 +295,102 @@
seed_array_int_impl<w>(seq, x, boost::is_signed<IntType>());
}
+template<int w, std::size_t n, class Iter, class UIntType>
+void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n])
+{
+ for(std::size_t j = 0; j < n; j++) {
+ UIntType val = 0;
+ for(std::size_t k = 0; k < (w+31)/32; ++k) {
+ if(first == last) {
+ throw std::invalid_argument("Not enough elements in call to seed.");
+ }
+ val += static_cast<UIntType>(*first++) << 32*k;
+ }
+ x[j] = val & ::boost::low_bits_mask_t<w>::sig_bits;
+ }
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::true_)
+{
+ typedef typename boost::make_unsigned<IntType>::type unsigned_array[n];
+ fill_array_int_impl<w>(first, last, reinterpret_cast<unsigned_array&>(x));
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::false_)
+{
+ fill_array_int_impl<w>(first, last, x);
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n])
+{
+ fill_array_int_impl<w>(first, last, x, boost::is_signed<IntType>());
+}
+
+template<int w, std::size_t n, class RealType>
+void seed_array_real_impl(const boost::uint_least32_t* storage, RealType (&x)[n])
+{
+ boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32));
+ RealType two32 = 4294967296.0;
+ const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
+ unsigned int j;
+ for(j = 0; j < n; ++j) {
+ RealType val = RealType(0);
+ RealType mult = divisor;
+ for(int k = 0; k < w/32; ++k) {
+ val += *storage++ * mult;
+ mult *= two32;
+ }
+ if(mask != 0) {
+ val += (*storage++ & mask) * mult;
+ }
+ BOOST_ASSERT(val >= 0);
+ BOOST_ASSERT(val < 1);
+ x[j] = val;
+ }
+}
+
+template<int w, std::size_t n, class SeedSeq, class RealType>
+void seed_array_real(SeedSeq& seq, RealType (&x)[n])
+{
+ using std::pow;
+ boost::uint_least32_t storage[((w+31)/32) * n];
+ seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n);
+ seed_array_real_impl<w>(storage, x);
+}
+
+template<int w, std::size_t n, class Iter, class RealType>
+void fill_array_real(Iter& first, Iter last, RealType (&x)[n])
+{
+ boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32));
+ RealType two32 = 4294967296.0;
+ const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
+ unsigned int j;
+ for(j = 0; j < n; ++j) {
+ RealType val = RealType(0);
+ RealType mult = divisor;
+ for(int k = 0; k < w/32; ++k, ++first) {
+ if(first == last) throw std::invalid_argument("Not enough elements in call to seed.");
+ val += *first * mult;
+ mult *= two32;
+ }
+ if(mask != 0) {
+ if(first == last) throw std::invalid_argument("Not enough elements in call to seed.");
+ val += (*first & mask) * mult;
+ ++first;
+ }
+ BOOST_ASSERT(val >= 0);
+ BOOST_ASSERT(val < 1);
+ x[j] = val;
+ }
}
+
}
}
+}
+
+#include <boost/random/detail/enable_warnings.hpp>
#endif
Modified: branches/release/boost/random/detail/uniform_int_float.hpp
==============================================================================
--- branches/release/boost/random/detail/uniform_int_float.hpp (original)
+++ branches/release/boost/random/detail/uniform_int_float.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/detail/uniform_int_float.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -14,72 +15,59 @@
#ifndef BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#define BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
+#include <boost/limits.hpp>
#include <boost/config.hpp>
+#include <boost/integer.hpp>
#include <boost/random/detail/config.hpp>
-#include <boost/random/uniform_01.hpp>
+#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
-template<class UniformRandomNumberGenerator, class IntType = unsigned long>
+template<class URNG>
class uniform_int_float
{
public:
- typedef UniformRandomNumberGenerator base_type;
- typedef IntType result_type;
+ typedef URNG base_type;
+ typedef typename base_type::result_type base_result;
- uniform_int_float(base_type rng, IntType min_arg = 0, IntType max_arg = 0xffffffff)
- : _rng(rng), _min(min_arg), _max(max_arg)
- {
- init();
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
- base_type& base() { return _rng.base(); }
- const base_type& base() const { return _rng.base(); }
-
- result_type operator()()
- {
- return static_cast<IntType>(_rng() * _range) + _min;
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int_float& ud)
- {
- os << ud._min << " " << ud._max;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, uniform_int_float& ud)
- {
- is >> std::ws >> ud._min >> std::ws >> ud._max;
- ud.init();
- return is;
- }
-#endif
+ typedef typename boost::uint_t<
+ (std::numeric_limits<boost::uintmax_t>::digits <
+ std::numeric_limits<base_result>::digits)?
+ std::numeric_limits<boost::uintmax_t>::digits :
+ std::numeric_limits<base_result>::digits
+ >::fast result_type;
+
+ uniform_int_float(base_type& rng)
+ : _rng(rng) {}
+
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return 0; }
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ {
+ std::size_t digits = std::numeric_limits<result_type>::digits;
+ if(URNG::precision() < digits) digits = URNG::precision();
+ return (result_type(2) << (digits - 1)) - 1;
+ }
+ base_type& base() { return _rng; }
+ const base_type& base() const { return _rng; }
+
+ result_type operator()()
+ {
+ base_result range = static_cast<base_result>((max)())+1;
+ return static_cast<result_type>(_rng() * range);
+ }
private:
- void init()
- {
- _range = static_cast<base_result>(_max-_min)+1;
- }
-
- typedef typename base_type::result_type base_result;
- uniform_01<base_type> _rng;
- result_type _min, _max;
- base_result _range;
+ base_type& _rng;
};
-
} // namespace detail
} // namespace random
} // namespace boost
+#include <boost/random/detail/enable_warnings.hpp>
+
#endif // BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
Copied: branches/release/boost/random/detail/vector_io.hpp (from r67740, /trunk/boost/random/detail/vector_io.hpp)
==============================================================================
--- /trunk/boost/random/detail/vector_io.hpp (original)
+++ branches/release/boost/random/detail/vector_io.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -28,26 +28,26 @@
typename std::vector<T>::const_iterator
iter = vec.begin(),
end = vec.end();
- os << '[';
+ os << os.widen('[');
if(iter != end) {
os << *iter;
++iter;
for(; iter != end; ++iter)
{
- os << ' ' << *iter;
+ os << os.widen(' ') << *iter;
}
}
- os << ']';
+ os << os.widen(']');
}
template<class CharT, class Traits, class T>
void read_vector(std::basic_istream<CharT, Traits>& is, std::vector<T>& vec)
{
- char ch;
+ CharT ch;
if(!(is >> ch)) {
return;
}
- if(ch != '[') {
+ if(ch != is.widen('[')) {
is.putback(ch);
is.setstate(std::ios_base::failbit);
return;
@@ -61,7 +61,7 @@
if(!(is >> ch)) {
return;
}
- if(ch != ']') {
+ if(ch != is.widen(']')) {
is.putback(ch);
is.setstate(std::ios_base::failbit);
}
Modified: branches/release/boost/random/discard_block.hpp
==============================================================================
--- branches/release/boost/random/discard_block.hpp (original)
+++ branches/release/boost/random/discard_block.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/discard_block.hpp header file
*
* Copyright Jens Maurer 2002
+ * Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,113 +19,208 @@
#include <iostream>
#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/seed.hpp>
namespace boost {
namespace random {
/**
- * The class template \discard_block is a model of
+ * The class template \discard_block_engine is a model of
* \pseudo_random_number_generator. It modifies
* another generator by discarding parts of its output.
- * Out of every block of @c r results, the first @c p
+ * Out of every block of @c p results, the first @c r
* will be returned and the rest discarded.
*
* Requires: 0 < p <= r
*/
-template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
-class discard_block
+template<class UniformRandomNumberGenerator, std::size_t p, std::size_t r>
+class discard_block_engine
{
+ typedef typename detail::seed_type<
+ typename UniformRandomNumberGenerator::result_type>::type seed_type;
public:
- typedef UniformRandomNumberGenerator base_type;
- typedef typename base_type::result_type result_type;
+ typedef UniformRandomNumberGenerator base_type;
+ typedef typename base_type::result_type result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(unsigned int, total_block = p);
- BOOST_STATIC_CONSTANT(unsigned int, returned_block = r);
+ BOOST_STATIC_CONSTANT(std::size_t, block_size = p);
+ BOOST_STATIC_CONSTANT(std::size_t, used_block = r);
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(total_block >= returned_block);
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(std::size_t, total_block = p);
+ BOOST_STATIC_CONSTANT(std::size_t, returned_block = r);
+
+ BOOST_STATIC_ASSERT(total_block >= returned_block);
+
+ /** Uses the default seed for the base generator. */
+ discard_block_engine() : _rng(), _n(0) { }
+ /** Constructs a new \discard_block_engine with a copy of rng. */
+ explicit discard_block_engine(const base_type & rng) : _rng(rng), _n(0) { }
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ /** Constructs a new \discard_block_engine with rng. */
+ explicit discard_block_engine(base_type && rng) : _rng(rng), _n(0) { }
#endif
- discard_block() : _rng(), _n(0) { }
- explicit discard_block(const base_type & rng) : _rng(rng), _n(0) { }
- template<class T> explicit discard_block(T s) : _rng(s), _n(0) {}
- template<class It> discard_block(It& first, It last)
- : _rng(first, last), _n(0) { }
- void seed() { _rng.seed(); _n = 0; }
- template<class T> void seed(T s) { _rng.seed(s); _n = 0; }
- template<class It> void seed(It& first, It last)
- { _n = 0; _rng.seed(first, last); }
-
- const base_type& base() const { return _rng; }
-
- result_type operator()()
- {
- if(_n >= returned_block) {
- // discard values of random number generator
- for( ; _n < total_block; ++_n)
- _rng();
- _n = 0;
+ /**
+ * Creates a new \discard_block_engine and seeds the underlying
+ * generator with @c value
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(discard_block_engine,
+ seed_type, value)
+ { _rng.seed(value); _n = 0; }
+
+ /**
+ * Creates a new \discard_block_engine and seeds the underlying
+ * generator with @c seq
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(discard_block_engine, SeedSeq, seq)
+ { _rng.seed(seq); _n = 0; }
+
+ /**
+ * Creates a new \discard_block_engine and seeds the underlying
+ * generator with first and last.
+ */
+ template<class It> discard_block_engine(It& first, It last)
+ : _rng(first, last), _n(0) { }
+
+ /** default seeds the underlying generator. */
+ void seed() { _rng.seed(); _n = 0; }
+ /** Seeds the underlying generator with s. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(discard_block_engine, seed_type, s)
+ { _rng.seed(s); _n = 0; }
+ /** Seeds the underlying generator with seq. */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(discard_block_engine, SeedSeq, seq)
+ { _rng.seed(seq); _n = 0; }
+ /** Seeds the underlying generator with first and last. */
+ template<class It> void seed(It& first, It last)
+ { _rng.seed(first, last); _n = 0; }
+
+ /** Returns the underlying engine. */
+ const base_type& base() const { return _rng; }
+
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ if(_n >= returned_block) {
+ // discard values of random number generator
+ _rng.discard(total_block - _n);
+ _n = 0;
+ }
+ ++_n;
+ return _rng();
}
- ++_n;
- return _rng();
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); }
- static bool validation(result_type x) { return true; } // dummy
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
+
+ template<class It>
+ void generate(It first, It last)
+ { detail::generate(*this, first, last); }
+
+ /**
+ * Returns the smallest value that the generator can produce.
+ * This is the same as the minimum of the underlying generator.
+ */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (base_type::min)(); }
+ /**
+ * Returns the largest value that the generator can produce.
+ * This is the same as the maximum of the underlying generator.
+ */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (base_type::max)(); }
+
+ /**
+ * INTERNAL ONLY
+ * Returns the number of random bits.
+ * This is not part of the standard, and I'm not sure that
+ * it's the best solution, but something like this is needed
+ * to implement generate_canonical. For now, mark it as
+ * an implementation detail.
+ */
+ static std::size_t precision() { return base_type::precision(); }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const discard_block& s)
- {
- os << s._rng << " " << s._n << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, discard_block& s)
- {
- is >> s._rng >> std::ws >> s._n >> std::ws;
- return is;
- }
-#endif
+ /** Writes a \discard_block_engine to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const discard_block_engine& s)
+ {
+ os << s._rng << ' ' << s._n;
+ return os;
+ }
- friend bool operator==(const discard_block& x, const discard_block& y)
- { return x._rng == y._rng && x._n == y._n; }
- friend bool operator!=(const discard_block& x, const discard_block& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const discard_block& rhs) const
- { return _rng == rhs._rng && _n == rhs._n; }
- bool operator!=(const discard_block& rhs) const
- { return !(*this == rhs); }
+ /** Reads a \discard_block_engine from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, discard_block_engine& s)
+ {
+ is >> s._rng >> std::ws >> s._n;
+ return is;
+ }
#endif
+ /** Returns true if the two generators will produce identical sequences. */
+ friend bool operator==(const discard_block_engine& x,
+ const discard_block_engine& y)
+ { return x._rng == y._rng && x._n == y._n; }
+ /** Returns true if the two generators will produce different sequences. */
+ friend bool operator!=(const discard_block_engine& x,
+ const discard_block_engine& y)
+ { return !(x == y); }
+
private:
- base_type _rng;
- unsigned int _n;
+ base_type _rng;
+ std::size_t _n;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
-const bool discard_block<UniformRandomNumberGenerator, p, r>::has_fixed_range;
-template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
-const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::total_block;
-template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
-const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::returned_block;
+template<class URNG, std::size_t p, std::size_t r>
+const bool discard_block_engine<URNG, p, r>::has_fixed_range;
+template<class URNG, std::size_t p, std::size_t r>
+const std::size_t discard_block_engine<URNG, p, r>::total_block;
+template<class URNG, std::size_t p, std::size_t r>
+const std::size_t discard_block_engine<URNG, p, r>::returned_block;
+template<class URNG, std::size_t p, std::size_t r>
+const std::size_t discard_block_engine<URNG, p, r>::block_size;
+template<class URNG, std::size_t p, std::size_t r>
+const std::size_t discard_block_engine<URNG, p, r>::used_block;
#endif
+/// \cond \show_deprecated
+
+template<class URNG, int p, int r>
+class discard_block : public discard_block_engine<URNG, p, r>
+{
+ typedef discard_block_engine<URNG, p, r> base_t;
+public:
+ typedef typename base_t::result_type result_type;
+ discard_block() {}
+ template<class T>
+ discard_block(T& arg) : base_t(arg) {}
+ template<class T>
+ discard_block(const T& arg) : base_t(arg) {}
+ template<class It>
+ discard_block(It& first, It last) : base_t(first, last) {}
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (this->base().min)(); }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (this->base().max)(); }
+};
+
+/// \endcond
+
} // namespace random
} // namespace boost
Copied: branches/release/boost/random/discrete_distribution.hpp (from r63180, /trunk/boost/random/discrete_distribution.hpp)
==============================================================================
--- /trunk/boost/random/discrete_distribution.hpp (original)
+++ branches/release/boost/random/discrete_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,24 +1,29 @@
-// discrete_distribution.hpp
-//
-// Copyright (c) 2009-2010
-// Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
+/* boost random/discrete_distribution.hpp header file
+ *
+ * Copyright Steven Watanabe 2009-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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id$
+ */
#ifndef BOOST_RANDOM_DISCRETE_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_DISCRETE_DISTRIBUTION_HPP_INCLUDED
#include <vector>
-#include <cassert>
#include <limits>
#include <numeric>
#include <utility>
#include <iterator>
+#include <boost/assert.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/vector_io.hpp>
#ifndef BOOST_NO_INITIALIZER_LISTS
#include <initializer_list>
@@ -27,6 +32,8 @@
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
+#include <boost/random/detail/disable_warnings.hpp>
+
namespace boost {
namespace random {
@@ -44,6 +51,9 @@
class param_type {
public:
+
+ typedef discrete_distribution distribution_type;
+
/**
* Constructs a @c param_type object, representing a distribution
* with \f$p(0) = 1\f$ and \f$p(k|k>0) = 0\f$.
@@ -96,7 +106,7 @@
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
- assert(delta > 0);
+ BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_probabilities.push_back(fw(xmin + k*delta + delta/2));
}
@@ -112,75 +122,33 @@
return _probabilities;
}
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters to a @c std::ostream. */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT, Traits>&
- operator<<(std::basic_ostream<CharT, Traits>& os,
- const param_type& parm)
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
- typename std::vector<WeightType>::const_iterator
- iter = parm._probabilities.begin(),
- end = parm._probabilities.end();
- os << '[';
- if(iter != end) {
- os << *iter;
- ++iter;
- for(; iter != end; ++iter)
- {
- os << ' ' << *iter;
- }
- }
- os << ']';
+ detail::print_vector(os, parm._probabilities);
return os;
}
/** Reads the parameters from a @c std::istream. */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT, Traits>&
- operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
- std::vector<WeightType> result;
- char ch;
- if(!(is >> ch)) {
- return is;
- }
- if(ch != '[') {
- is.putback(ch);
- is.setstate(std::ios_base::failbit);
- return is;
- }
- WeightType val;
- while(is >> std::ws >> val) {
- result.push_back(val);
- }
- if(is.fail()) {
- is.clear();
- if(!(is >> ch)) {
- return is;
- }
- if(ch != ']') {
- is.putback(ch);
- is.setstate(std::ios_base::failbit);
- }
+ std::vector<WeightType> temp;
+ detail::read_vector(is, temp);
+ if(is) {
+ parm._probabilities.swap(temp);
}
- parm._probabilities.swap(result);
return is;
}
-#endif
/** Returns true if the two sets of parameters are the same. */
- friend bool operator==(const param_type& lhs, const param_type& rhs)
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{
return lhs._probabilities == rhs._probabilities;
}
/** Returns true if the two sets of parameters are different. */
- friend bool operator!=(const param_type& lhs, const param_type& rhs)
- {
- return !(lhs == rhs);
- }
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
- /// @cond
+ /// @cond show_private
friend class discrete_distribution;
explicit param_type(const discrete_distribution& dist)
: _probabilities(dist.probabilities())
@@ -267,7 +235,7 @@
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
- assert(delta > 0);
+ BOOST_ASSERT(delta > 0);
std::vector<WeightType> weights;
for(std::size_t k = 0; k < n; ++k) {
weights.push_back(fw(xmin + k*delta + delta/2));
@@ -287,8 +255,9 @@
* discrete_distribution.
*/
template<class URNG>
- IntType operator()(URNG& urng) const {
- assert(!_alias_table.empty());
+ IntType operator()(URNG& urng) const
+ {
+ BOOST_ASSERT(!_alias_table.empty());
WeightType test = uniform_01<WeightType>()(urng);
IntType result = uniform_int<IntType>((min)(), (max)())(urng);
if(test < _alias_table[result].first) {
@@ -300,7 +269,7 @@
/**
* Returns a value distributed according to the parameters
- * specified by parm.
+ * specified by param.
*/
template<class URNG>
IntType operator()(URNG& urng, const param_type& parm) const
@@ -374,21 +343,15 @@
*/
void reset() {}
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a distribution to a @c std::ostream. */
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT, Traits>&
- operator<<(std::basic_ostream<CharT, Traits>& os,
- const discrete_distribution& dd)
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, discrete_distribution, dd)
{
os << dd.param();
return os;
}
/** Reads a distribution from a @c std::istream */
- template<class CharT, class Traits>
- friend std::basic_istream<CharT, Traits>&
- operator>>(std::basic_istream<CharT, Traits>& is, discrete_distribution& dd)
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, discrete_distribution, dd)
{
param_type parm;
if(is >> parm) {
@@ -396,14 +359,12 @@
}
return is;
}
-#endif
/**
* Returns true if the two distributions will return the
* same sequence of values, when passed equal generators.
*/
- friend bool operator==(const discrete_distribution& lhs,
- const discrete_distribution& rhs)
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(discrete_distribution, lhs, rhs)
{
return lhs._alias_table == rhs._alias_table;
}
@@ -411,15 +372,11 @@
* Returns true if the two distributions may return different
* sequences of values, when passed equal generators.
*/
- friend bool operator!=(const discrete_distribution& lhs,
- const discrete_distribution& rhs)
- {
- return !(lhs == rhs);
- }
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(discrete_distribution)
private:
- /// @cond
+ /// @cond show_private
template<class Iter>
void init(Iter first, Iter last, std::input_iterator_tag)
@@ -491,4 +448,6 @@
}
}
+#include <boost/random/detail/enable_warnings.hpp>
+
#endif
Modified: branches/release/boost/random/exponential_distribution.hpp
==============================================================================
--- branches/release/boost/random/exponential_distribution.hpp (original)
+++ branches/release/boost/random/exponential_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/exponential_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,70 +18,165 @@
#define BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
-#include <iostream>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/uniform_01.hpp>
namespace boost {
+namespace random {
/**
- * The exponential distribution has a single parameter lambda.
+ * The exponential distribution is a model of \random_distribution with
+ * a single parameter lambda.
*
- * It has \f$p(x) = \lambda e^{-\lambda x}\f$
+ * It has \f$\displaystyle p(x) = \lambda e^{-\lambda x}\f$
*/
template<class RealType = double>
class exponential_distribution
{
public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
-#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
-
- explicit exponential_distribution(result_type lambda_arg = result_type(1))
- : _lambda(lambda_arg) { assert(_lambda > result_type(0)); }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- result_type lambda() const { return _lambda; }
-
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::log;
-#endif
- return -result_type(1) / _lambda * log(result_type(1)-eng());
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const exponential_distribution& ed)
- {
- os << ed._lambda;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, exponential_distribution& ed)
- {
- is >> std::ws >> ed._lambda;
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef exponential_distribution distribution_type;
+
+ /**
+ * Constructs parameters with a given lambda.
+ *
+ * Requires: lambda > 0
+ */
+ param_type(RealType lambda_arg = RealType(1.0))
+ : _lambda(lambda_arg) { BOOST_ASSERT(_lambda > RealType(0)); }
+
+ /** Returns the lambda parameter of the distribution. */
+ RealType lambda() const { return _lambda; }
+
+ /** Writes the parameters to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._lambda;
+ return os;
+ }
+
+ /** Reads the parameters from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._lambda;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._lambda == rhs._lambda; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _lambda;
+ };
+
+ /**
+ * Constructs an exponential_distribution with a given lambda.
+ *
+ * Requires: lambda > 0
+ */
+ explicit exponential_distribution(RealType lambda_arg = RealType(1.0))
+ : _lambda(lambda_arg) { BOOST_ASSERT(_lambda > RealType(0)); }
+
+ /**
+ * Constructs an exponential_distribution from its parameters
+ */
+ explicit exponential_distribution(const param_type& parm)
+ : _lambda(parm.lambda()) {}
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the lambda parameter of the distribution. */
+ RealType lambda() const { return _lambda; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return RealType(0); }
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::infinity)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_lambda); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm) { _lambda = parm.lambda(); }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /**
+ * Returns a random variate distributed according to the
+ * exponential distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng) const
+ {
+ using std::log;
+ return -result_type(1) /
+ _lambda * log(result_type(1)-uniform_01<RealType>()(eng));
+ }
+
+ /**
+ * Returns a random variate distributed according to the exponential
+ * distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm) const
+ {
+ return exponential_distribution(parm)(eng);
+ }
+
+ /** Writes the distribution to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, exponential_distribution, ed)
+ {
+ os << ed._lambda;
+ return os;
+ }
+
+ /** Reads the distribution from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, exponential_distribution, ed)
+ {
+ is >> ed._lambda;
+ return is;
+ }
+
+ /**
+ * Returns true iff the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(exponential_distribution, lhs, rhs)
+ { return lhs._lambda == rhs._lambda; }
+
+ /**
+ * Returns true iff the two distributions will produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(exponential_distribution)
private:
- result_type _lambda;
+ result_type _lambda;
};
+} // namespace random
+
+using random::exponential_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
Copied: branches/release/boost/random/extreme_value_distribution.hpp (from r63330, /trunk/boost/random/extreme_value_distribution.hpp)
==============================================================================
--- /trunk/boost/random/extreme_value_distribution.hpp (original)
+++ branches/release/boost/random/extreme_value_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -101,7 +101,7 @@
/**
* Returns a random variate distributed accordint to the extreme
- * value distribution with parameters specified by @c parm.
+ * value distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
@@ -115,10 +115,10 @@
RealType b() const { return _b; }
/** Returns the smallest value that the distribution can produce. */
- RealType min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -std::numeric_limits<RealType>::infinity(); }
/** Returns the largest value that the distribution can produce. */
- RealType max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
@@ -130,6 +130,12 @@
_b = parm.b();
}
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
/** Writes an @c extreme_value_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, extreme_value_distribution, wd)
{
Copied: branches/release/boost/random/fisher_f_distribution.hpp (from r67694, /trunk/boost/random/fisher_f_distribution.hpp)
==============================================================================
--- /trunk/boost/random/fisher_f_distribution.hpp (original)
+++ branches/release/boost/random/fisher_f_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -119,10 +119,9 @@
RealType n() const { return _impl_n.n(); }
/** Returns the smallest value that the distribution can produce. */
- RealType min BOOST_PREVENT_MACRO_SUBSTITUTION ()
- { return 0; }
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/** Returns the largest value that the distribution can produce. */
- RealType max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
@@ -137,6 +136,12 @@
_impl_n.param(n_param);
}
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
/** Writes an @c fisher_f_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, fisher_f_distribution, fd)
{
Modified: branches/release/boost/random/gamma_distribution.hpp
==============================================================================
--- branches/release/boost/random/gamma_distribution.hpp (original)
+++ branches/release/boost/random/gamma_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/gamma_distribution.hpp header file
*
* Copyright Jens Maurer 2002
+ * Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,129 +16,277 @@
#define BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
+#include <istream>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/exponential_distribution.hpp>
namespace boost {
+namespace random {
// The algorithm is taken from Knuth
/**
- * The gamma distribution is a continuous distribution with a single
- * parameter alpha.
+ * The gamma distribution is a continuous distribution with two
+ * parameters alpha and beta. It produces values > 0.
*
- * It has \f$p(x) = x^{\alpha-1}\frac{e^{-x}}{\Gamma(\alpha)}\f$.
+ * It has
+ * \f$\displaystyle p(x) = x^{\alpha-1}\frac{e^{-x/\beta}}{\beta^\alpha\Gamma(\alpha)}\f$.
*/
template<class RealType = double>
class gamma_distribution
{
public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
+
+ class param_type
+ {
+ public:
+ typedef gamma_distribution distribution_type;
+
+ /**
+ * Constructs a @c param_type object from the "alpha" and "beta"
+ * parameters.
+ *
+ * Requires: alpha > 0 && beta > 0
+ */
+ param_type(const RealType& alpha_arg = RealType(1.0),
+ const RealType& beta_arg = RealType(1.0))
+ : _alpha(alpha_arg), _beta(beta_arg)
+ {
+ }
+
+ /** Returns the "alpha" parameter of the distribution. */
+ RealType alpha() const { return _alpha; }
+ /** Returns the "beta" parameter of the distribution. */
+ RealType beta() const { return _beta; }
+
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os,
+ const param_type& parm)
+ {
+ os << parm._alpha << ' ' << parm._beta;
+ return os;
+ }
+
+ /** Reads the parameters from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
+ {
+ is >> parm._alpha >> std::ws >> parm._beta;
+ return is;
+ }
+#endif
+
+ /** Returns true if the two sets of parameters are the same. */
+ friend bool operator==(const param_type& lhs, const param_type& rhs)
+ {
+ return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta;
+ }
+ /** Returns true if the two sets fo parameters are different. */
+ friend bool operator!=(const param_type& lhs, const param_type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ private:
+ RealType _alpha;
+ RealType _beta;
+ };
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
+ BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
- explicit gamma_distribution(const result_type& alpha_arg = result_type(1))
- : _exp(result_type(1)), _alpha(alpha_arg)
- {
- assert(_alpha > result_type(0));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- RealType alpha() const { return _alpha; }
-
- void reset() { _exp.reset(); }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
+ /**
+ * Creates a new gamma_distribution with parameters "alpha" and "beta".
+ *
+ * Requires: alpha > 0 && beta > 0
+ */
+ explicit gamma_distribution(const result_type& alpha_arg = result_type(1.0),
+ const result_type& beta_arg = result_type(1.0))
+ : _exp(result_type(1)), _alpha(alpha_arg), _beta(beta_arg)
+ {
+ BOOST_ASSERT(_alpha > result_type(0));
+ BOOST_ASSERT(_beta > result_type(0));
+ init();
+ }
+
+ /** Constructs a @c gamma_distribution from its parameters. */
+ explicit gamma_distribution(const param_type& parm)
+ : _exp(result_type(1)), _alpha(parm.alpha()), _beta(parm.beta())
+ {
+ init();
+ }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the "alpha" paramter of the distribution. */
+ RealType alpha() const { return _alpha; }
+ /** Returns the "beta" parameter of the distribution. */
+ RealType beta() const { return _beta; }
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
+ /* Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::infinity)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_alpha, _beta); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _alpha = parm.alpha();
+ _beta = parm.beta();
+ init();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _exp.reset(); }
+
+ /**
+ * Returns a random variate distributed according to
+ * the gamma distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::tan; using std::sqrt; using std::exp; using std::log;
- using std::pow;
+ // allow for Koenig lookup
+ using std::tan; using std::sqrt; using std::exp; using std::log;
+ using std::pow;
#endif
- if(_alpha == result_type(1)) {
- return _exp(eng);
- } else if(_alpha > result_type(1)) {
- // Can we have a boost::mathconst please?
- const result_type pi = result_type(3.14159265358979323846);
- for(;;) {
- result_type y = tan(pi * eng());
- result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
- + _alpha-result_type(1);
- if(x <= result_type(0))
- continue;
- if(eng() >
- (result_type(1)+y*y) * exp((_alpha-result_type(1))
- *log(x/(_alpha-result_type(1)))
- - sqrt(result_type(2)*_alpha
- -result_type(1))*y))
- continue;
- return x;
- }
- } else /* alpha < 1.0 */ {
- for(;;) {
- result_type u = eng();
- result_type y = _exp(eng);
- result_type x, q;
- if(u < _p) {
- x = exp(-y/_alpha);
- q = _p*exp(-x);
- } else {
- x = result_type(1)+y;
- q = _p + (result_type(1)-_p) * pow(x, _alpha-result_type(1));
- }
- if(u >= q)
- continue;
- return x;
- }
+ if(_alpha == result_type(1)) {
+ return _exp(eng) * _beta;
+ } else if(_alpha > result_type(1)) {
+ // Can we have a boost::mathconst please?
+ const result_type pi = result_type(3.14159265358979323846);
+ for(;;) {
+ result_type y = tan(pi * uniform_01<RealType>()(eng));
+ result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
+ + _alpha-result_type(1);
+ if(x <= result_type(0))
+ continue;
+ if(uniform_01<RealType>()(eng) >
+ (result_type(1)+y*y) * exp((_alpha-result_type(1))
+ *log(x/(_alpha-result_type(1)))
+ - sqrt(result_type(2)*_alpha
+ -result_type(1))*y))
+ continue;
+ return x * _beta;
+ }
+ } else /* alpha < 1.0 */ {
+ for(;;) {
+ result_type u = uniform_01<RealType>()(eng);
+ result_type y = _exp(eng);
+ result_type x, q;
+ if(u < _p) {
+ x = exp(-y/_alpha);
+ q = _p*exp(-x);
+ } else {
+ x = result_type(1)+y;
+ q = _p + (result_type(1)-_p) * pow(x,_alpha-result_type(1));
+ }
+ if(u >= q)
+ continue;
+ return x * _beta;
+ }
+ }
+ }
+
+ template<class URNG>
+ RealType operator()(URNG& urng, const param_type& parm) const
+ {
+ return gamma_distribution(parm)(urng);
}
- }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const gamma_distribution& gd)
- {
- os << gd._alpha;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
- {
- is >> std::ws >> gd._alpha;
- gd.init();
- return is;
- }
+ /** Writes a @c gamma_distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const gamma_distribution& gd)
+ {
+ os << gd.param();
+ return os;
+ }
+
+ /** Reads a @c gamma_distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
+ {
+ gd.read(is);
+ return is;
+ }
#endif
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of random variates given equal generators.
+ */
+ friend bool operator==(const gamma_distribution& lhs,
+ const gamma_distribution& rhs)
+ {
+ return lhs._alpha == rhs._alpha
+ && lhs._beta == rhs._beta
+ && lhs._exp == rhs._exp;
+ }
+
+ /**
+ * Returns true if the two distributions can produce different
+ * sequences of random variates, given equal generators.
+ */
+ friend bool operator!=(const gamma_distribution& lhs,
+ const gamma_distribution& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
private:
- /// \cond hide_private_members
- void init()
- {
+ /// \cond hide_private_members
+
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is)
+ {
+ param_type parm;
+ if(is >> parm) {
+ param(parm);
+ }
+ }
+
+ void init()
+ {
#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp;
+ // allow for Koenig lookup
+ using std::exp;
#endif
- _p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
- }
- /// \endcond
-
- exponential_distribution<RealType> _exp;
- result_type _alpha;
- // some data precomputed from the parameters
- result_type _p;
+ _p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
+ }
+ /// \endcond
+
+ exponential_distribution<RealType> _exp;
+ result_type _alpha;
+ result_type _beta;
+ // some data precomputed from the parameters
+ result_type _p;
};
+
+} // namespace random
+
+using random::gamma_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
Copied: branches/release/boost/random/generate_canonical.hpp (from r68813, /trunk/boost/random/generate_canonical.hpp)
==============================================================================
--- /trunk/boost/random/generate_canonical.hpp (original)
+++ branches/release/boost/random/generate_canonical.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,8 +14,8 @@
#ifndef BOOST_RANDOM_GENERATE_CANONICAL_HPP
#define BOOST_RANDOM_GENERATE_CANONICAL_HPP
-#include <cassert>
#include <algorithm>
+#include <boost/assert.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/is_integral.hpp>
@@ -33,9 +33,11 @@
using std::pow;
typedef typename URNG::result_type base_result;
std::size_t digits = std::numeric_limits<RealType>::digits;
- RealType R = RealType(g.max()) - RealType(g.min()) + 1;
+ RealType R = RealType((g.max)()) - RealType((g.min)()) + 1;
RealType mult = R;
- RealType limit = pow(RealType(2), RealType((std::min)(bits, digits)));
+ RealType limit =
+ pow(RealType(2),
+ RealType((std::min)(static_cast<std::size_t>(bits), digits)));
RealType S = RealType(detail::subtract<base_result>()(g(), (g.min)()));
while(mult < limit) {
RealType inc = RealType(detail::subtract<base_result>()(g(), (g.min)()));
@@ -50,17 +52,16 @@
{
using std::pow;
using std::floor;
- assert((g.min)() == 0);
- assert((g.max)() == 1);
+ BOOST_ASSERT((g.min)() == 0);
+ BOOST_ASSERT((g.max)() == 1);
typedef typename URNG::result_type base_result;
std::size_t digits = std::numeric_limits<RealType>::digits;
std::size_t engine_bits = g.precision();
std::size_t b = (std::min)(bits, digits);
- std::size_t k = (b + engine_bits - 1) / engine_bits;
RealType R = pow(RealType(2), RealType(engine_bits));
RealType mult = R;
RealType limit = pow(RealType(2), RealType(b));
- RealType S = g() - (g.min)();
+ RealType S = RealType(g() - (g.min)());
while(mult < limit) {
RealType inc(floor((RealType(g()) - RealType((g.min)())) * R));
S += inc * mult;
@@ -80,11 +81,11 @@
{
RealType result = detail::generate_canonical_impl<RealType, bits>(
g, boost::is_integral<typename URNG::result_type>());
- assert(result >= 0);
- assert(result <= 1);
+ BOOST_ASSERT(result >= 0);
+ BOOST_ASSERT(result <= 1);
if(result == 1) {
result -= std::numeric_limits<RealType>::epsilon() / 2;
- assert(result != 1);
+ BOOST_ASSERT(result != 1);
}
return result;
}
Modified: branches/release/boost/random/geometric_distribution.hpp
==============================================================================
--- branches/release/boost/random/geometric_distribution.hpp (original)
+++ branches/release/boost/random/geometric_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/geometric_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,18 +18,15 @@
#define BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp> // std::log
-#include <cassert>
-#include <iostream>
+#include <iosfwd>
+#include <ios>
+#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-// Special gcc workaround: gcc 2.95.x ignores using-declarations
-// in template classes (confirmed by gcc author Martin v. Loewis)
- using std::log;
-#endif
+namespace random {
/**
* An instantiation of the class template @c geometric_distribution models
@@ -36,83 +34,234 @@
* integers which are the number of bernoulli trials
* with probability @c p required to get one that fails.
*
- * For the geometric distribution, \f$p(i) = (1-p) p^{i-1}\f$.
+ * For the geometric distribution, \f$p(i) = p(1-p)^{i}\f$.
+ *
+ * @xmlwarning
+ * This distribution has been updated to match the C++ standard.
+ * Its behavior has changed from the original
+ * boost::geometric_distribution. A backwards compatible
+ * wrapper is provided in namespace boost.
+ * @endxmlwarning
*/
template<class IntType = int, class RealType = double>
class geometric_distribution
{
public:
- typedef RealType input_type;
- typedef IntType result_type;
+ typedef RealType input_type;
+ typedef IntType result_type;
- /**
- * Contructs a new geometric_distribution with the paramter @c p.
- *
- * Requires: 0 < p < 1
- */
- explicit geometric_distribution(const RealType& p = RealType(0.5))
- : _p(p)
- {
- assert(RealType(0) < _p && _p < RealType(1));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: the distribution parameter @c p
- */
- RealType p() const { return _p; }
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::log;
- using std::floor;
-#endif
- return IntType(floor(log(RealType(1)-eng()) / _log_p)) + IntType(1);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const geometric_distribution& gd)
- {
- os << gd._p;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, geometric_distribution& gd)
- {
- is >> std::ws >> gd._p;
- gd.init();
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef geometric_distribution distribution_type;
+
+ /** Constructs the parameters with p. */
+ explicit param_type(RealType p_arg = RealType(0.5))
+ : _p(p_arg)
+ {
+ BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
+ }
+
+ /** Returns the p parameter of the distribution. */
+ RealType p() const { return _p; }
+
+ /** Writes the parameters to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._p;
+ return os;
+ }
+
+ /** Reads the parameters from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ double p_in;
+ if(is >> p_in) {
+ if(p_in > RealType(0) && p_in < RealType(1)) {
+ parm._p = p_in;
+ } else {
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._p == rhs._p; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+
+ private:
+ RealType _p;
+ };
+
+ /**
+ * Contructs a new geometric_distribution with the paramter @c p.
+ *
+ * Requires: 0 < p < 1
+ */
+ explicit geometric_distribution(const RealType& p = RealType(0.5))
+ : _p(p)
+ {
+ BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
+ init();
+ }
+
+ /** Constructs a new geometric_distribution from its parameters. */
+ explicit geometric_distribution(const param_type& parm)
+ : _p(parm.p())
+ {
+ init();
+ }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns: the distribution parameter @c p */
+ RealType p() const { return _p; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return IntType(1); }
+
+ /** Returns the largest value that the distribution can produce. */
+ IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<IntType>::max)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_p); }
+
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _p = parm.p();
+ init();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /**
+ * Returns a random variate distributed according to the
+ * geometric_distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng) const
+ {
+ using std::log;
+ using std::floor;
+ RealType x = RealType(1) - boost::uniform_01<RealType>()(eng);
+ return IntType(floor(log(x) / _log_1mp));
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * geometric distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm) const
+ { return geometric_distribution(parm)(eng); }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
+ {
+ os << gd._p;
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
+ {
+ param_type parm;
+ if(is >> parm) {
+ gd.param(parm);
+ }
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(geometric_distribution, lhs, rhs)
+ { return lhs._p == rhs._p; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(geometric_distribution)
private:
- /// \cond hide_private_functions
+ /// \cond show_private
- void init()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::log;
-#endif
- _log_p = log(_p);
- }
+ void init()
+ {
+ using std::log;
+ _log_1mp = log(1 - _p);
+ }
- /// \endcond
+ RealType _p;
+ RealType _log_1mp;
- RealType _p;
- RealType _log_p;
+ /// \endcond
};
+} // namespace random
+
+/// \cond show_deprecated
+
+/**
+ * Provided for backwards compatibility. This class is
+ * deprecated. It provides the old behavior of geometric_distribution
+ * with \f$p(i) = (1-p) p^{i-1}\f$.
+ */
+template<class IntType = int, class RealType = double>
+class geometric_distribution
+{
+public:
+ typedef RealType input_type;
+ typedef IntType result_type;
+
+ explicit geometric_distribution(RealType p_arg = RealType(0.5))
+ : _impl(1 - p_arg) {}
+
+ RealType p() const { return 1 - _impl.p(); }
+
+ void reset() {}
+
+ template<class Engine>
+ IntType operator()(Engine& eng) const { return _impl(eng) + IntType(1); }
+
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
+ {
+ os << gd.p();
+ return os;
+ }
+
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
+ {
+ RealType val;
+ if(is >> val) {
+ typename impl_type::param_type impl_param(1 - val);
+ gd._impl.param(impl_param);
+ }
+ return is;
+ }
+
+private:
+ typedef random::geometric_distribution<IntType, RealType> impl_type;
+ impl_type _impl;
+};
+
+/// \endcond
+
} // namespace boost
#endif // BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
-
Copied: branches/release/boost/random/independent_bits.hpp (from r68804, /trunk/boost/random/independent_bits.hpp)
==============================================================================
--- /trunk/boost/random/independent_bits.hpp (original)
+++ branches/release/boost/random/independent_bits.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,15 +14,16 @@
#ifndef BOOST_RANDOM_INDEPENDENT_BITS_HPP
#define BOOST_RANDOM_INDEPENDENT_BITS_HPP
-#include <cassert>
#include <istream>
#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
#include <boost/integer/integer_mask.hpp>
-#include <boost/pending/integer_log2.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
@@ -31,41 +32,6 @@
namespace boost {
namespace random {
-namespace detail {
-
-template<int Shift>
-struct integer_log2_impl
-{
- template<class T>
- static int apply(T t, int accum)
- {
- int update = ((t >> Shift) != 0) * Shift;
- return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
- }
-};
-
-template<>
-struct integer_log2_impl<1>
-{
- template<class T>
- static int apply(T t, int accum)
- {
- return int(t >> 1) + accum;
- }
-};
-
-template<class T>
-inline int integer_log2(T t)
-{
- return integer_log2_impl<
- ::boost::detail::max_pow2_less<
- ::std::numeric_limits<T>::digits, 4
- >::value
- >::apply(t, 0);
-}
-
-}
-
/**
* An instantiation of class template @c independent_bits_engine
* model a \pseudo_random_number_generator. It generates random
@@ -84,14 +50,10 @@
// Required by old Boost.Random concept
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- /**
- * Returns the smallest value that the generator can produce
- */
+ /** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0; }
- /**
- * Returns the largest value that the generator can produce
- */
+ /** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return boost::low_bits_mask_t<w>::sig_bits; }
@@ -154,7 +116,7 @@
* seed the base generator.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(independent_bits_engine,
- result_type, seq)
+ SeedSeq, seq)
{ _base.seed(seq); }
/**
@@ -193,7 +155,7 @@
calc_params(n, range, w0, n0, y0, y1, y0_mask, y1_mask);
}
- assert(n0*w0 + (n - n0)*(w0 + 1) == w);
+ BOOST_ASSERT(n0*w0 + (n - n0)*(w0 + 1) == w);
result_type S = 0;
for(std::size_t k = 0; k < n0; ++k) {
@@ -218,15 +180,13 @@
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
-#ifndef BOOST_NO_LONG_LONG
/** Advances the state of the generator by @c z. */
- void discard(boost::ulong_long_type z)
+ void discard(boost::uintmax_t z)
{
- for(boost::ulong_long_type i = 0; i < z; ++i) {
+ for(boost::uintmax_t i = 0; i < z; ++i) {
(*this)();
}
}
-#endif
const base_type& base() const { return _base; }
@@ -265,7 +225,7 @@
private:
- /// \cond
+ /// \cond show_private
typedef typename base_type::result_type base_result;
typedef typename make_unsigned<base_result>::type base_unsigned;
@@ -275,14 +235,14 @@
base_unsigned& y0, base_unsigned& y1,
base_unsigned& y0_mask, base_unsigned& y1_mask)
{
- assert(w >= n);
+ BOOST_ASSERT(w >= n);
w0 = w/n;
n0 = n - w % n;
y0_mask = (base_unsigned(2) << (w0 - 1)) - 1;
y1_mask = (y0_mask << 1) | 1;
y0 = (range + 1) & ~y0_mask;
y1 = (range + 1) & ~y1_mask;
- assert(y0 != 0 || base_unsigned(range + 1) == 0);
+ BOOST_ASSERT(y0 != 0 || base_unsigned(range + 1) == 0);
}
/// \endcond
Modified: branches/release/boost/random/inversive_congruential.hpp
==============================================================================
--- branches/release/boost/random/inversive_congruential.hpp (original)
+++ branches/release/boost/random/inversive_congruential.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,20 +16,26 @@
#ifndef BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
#define BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
-#include <iostream>
-#include <cassert>
+#include <iosfwd>
#include <stdexcept>
+#include <boost/assert.hpp>
#include <boost/config.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/integer/static_log2.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/const_mod.hpp>
+#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/seed_impl.hpp>
+
+#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
// Eichenauer and Lehn 1986
/**
- * Instantiations of class template @c inversive_congruential model a
+ * Instantiations of class template @c inversive_congruential_engine model a
* \pseudo_random_number_generator. It uses the inversive congruential
* algorithm (ICG) described in
*
@@ -57,103 +63,185 @@
* not optimal for calculating the multiplicative inverse.
* @endxmlnote
*/
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-class inversive_congruential
+template<class IntType, IntType a, IntType b, IntType p>
+class inversive_congruential_engine
{
public:
- typedef IntType result_type;
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const result_type min_value = (b == 0 ? 1 : 0);
- static const result_type max_value = p-1;
-#else
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-#endif
- BOOST_STATIC_CONSTANT(result_type, multiplier = a);
- BOOST_STATIC_CONSTANT(result_type, increment = b);
- BOOST_STATIC_CONSTANT(result_type, modulus = p);
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return b == 0 ? 1 : 0; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return p-1; }
-
- /**
- * Constructs an inversive_congruential generator with
- * @c y0 as the initial state.
- */
- explicit inversive_congruential(IntType y0 = 1) : value(y0)
- {
- BOOST_STATIC_ASSERT(b >= 0);
- BOOST_STATIC_ASSERT(p > 1);
- BOOST_STATIC_ASSERT(a >= 1);
- if(b == 0)
- assert(y0 > 0);
- }
- template<class It> inversive_congruential(It& first, It last)
- { seed(first, last); }
-
- /** Changes the current state to y0. */
- void seed(IntType y0 = 1) { value = y0; if(b == 0) assert(y0 > 0); }
- template<class It> void seed(It& first, It last)
- {
- if(first == last)
- throw std::invalid_argument("inversive_congruential::seed");
- value = *first++;
- }
- IntType operator()()
- {
- typedef const_mod<IntType, p> do_mod;
- value = do_mod::mult_add(a, do_mod::invert(value), b);
- return value;
- }
-
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, inversive_congruential x)
- { os << x.value; return os; }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, inversive_congruential& x)
- { is >> x.value; return is; }
-#endif
+ typedef IntType result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+ BOOST_STATIC_CONSTANT(result_type, multiplier = a);
+ BOOST_STATIC_CONSTANT(result_type, increment = b);
+ BOOST_STATIC_CONSTANT(result_type, modulus = p);
+ BOOST_STATIC_CONSTANT(IntType, default_seed = 1);
+
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return b == 0 ? 1 : 0; }
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return p-1; }
+
+ /**
+ * Constructs an @c inversive_congruential_engine, seeding it with
+ * the default seed.
+ */
+ inversive_congruential_engine() { seed(); }
+
+ /**
+ * Constructs an @c inversive_congruential_engine, seeding it with @c x0.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(inversive_congruential_engine,
+ IntType, x0)
+ { seed(x0); }
+
+ /**
+ * Constructs an @c inversive_congruential_engine, seeding it with values
+ * produced by a call to @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(inversive_congruential_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ /**
+ * Constructs an @c inversive_congruential_engine, seeds it
+ * with values taken from the itrator range [first, last),
+ * and adjusts first to point to the element after the last one
+ * used. If there are not enough elements, throws @c std::invalid_argument.
+ *
+ * first and last must be input iterators.
+ */
+ template<class It> inversive_congruential_engine(It& first, It last)
+ { seed(first, last); }
+
+ /**
+ * Calls seed(default_seed)
+ */
+ void seed() { seed(default_seed); }
+
+ /**
+ * If c mod m is zero and x0 mod m is zero, changes the current value of
+ * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
+ * distinct seeds in the range [1,m) will leave the generator in distinct
+ * states. If c is not zero, the range is [0,m).
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(inversive_congruential_engine, IntType, x0)
+ {
+ // wrap _x if it doesn't fit in the destination
+ if(modulus == 0) {
+ _value = x0;
+ } else {
+ _value = x0 % modulus;
+ }
+ // handle negative seeds
+ if(_value <= 0 && _value != 0) {
+ _value += modulus;
+ }
+ // adjust to the correct range
+ if(increment == 0 && _value == 0) {
+ _value = 1;
+ }
+ BOOST_ASSERT(_value >= (min)());
+ BOOST_ASSERT(_value <= (max)());
+ }
+
+ /**
+ * Seeds an @c inversive_congruential_engine using values from a SeedSeq.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(inversive_congruential_engine, SeedSeq, seq)
+ { seed(detail::seed_one_int<IntType, modulus>(seq)); }
+
+ /**
+ * seeds an @c inversive_congruential_engine with values taken
+ * from the itrator range [first, last) and adjusts @c first to
+ * point to the element after the last one used. If there are
+ * not enough elements, throws @c std::invalid_argument.
+ *
+ * @c first and @c last must be input iterators.
+ */
+ template<class It> void seed(It& first, It last)
+ { seed(detail::get_one_int<IntType, modulus>(first, last)); }
+
+ /** Returns the next output of the generator. */
+ IntType operator()()
+ {
+ typedef const_mod<IntType, p> do_mod;
+ _value = do_mod::mult_add(a, do_mod::invert(_value), b);
+ return _value;
+ }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
+
+ /**
+ * Writes the textual representation of the generator to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, inversive_congruential_engine, x)
+ {
+ os << x._value;
+ return os;
+ }
+
+ /**
+ * Reads the textual representation of the generator from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, inversive_congruential_engine, x)
+ {
+ is >> x._value;
+ return is;
+ }
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(inversive_congruential_engine, x, y)
+ { return x._value == y._value; }
+
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(inversive_congruential_engine)
- friend bool operator==(inversive_congruential x, inversive_congruential y)
- { return x.value == y.value; }
- friend bool operator!=(inversive_congruential x, inversive_congruential y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(inversive_congruential rhs) const
- { return value == rhs.value; }
- bool operator!=(inversive_congruential rhs) const
- { return !(*this == rhs); }
-#endif
private:
- IntType value;
+ IntType _value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const bool inversive_congruential<IntType, a, b, p, val>::has_fixed_range;
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::min_value;
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::max_value;
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::multiplier;
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::increment;
-template<class IntType, IntType a, IntType b, IntType p, IntType val>
-const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::modulus;
+template<class IntType, IntType a, IntType b, IntType p>
+const bool inversive_congruential_engine<IntType, a, b, p>::has_fixed_range;
+template<class IntType, IntType a, IntType b, IntType p>
+const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::multiplier;
+template<class IntType, IntType a, IntType b, IntType p>
+const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::increment;
+template<class IntType, IntType a, IntType b, IntType p>
+const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::modulus;
+template<class IntType, IntType a, IntType b, IntType p>
+const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::default_seed;
#endif
-} // namespace random
+/// \cond show_deprecated
+
+// provided for backwards compatibility
+template<class IntType, IntType a, IntType b, IntType p, IntType val = 0>
+class inversive_congruential : public inversive_congruential_engine<IntType, a, b, p>
+{
+ typedef inversive_congruential_engine<IntType, a, b, p> base_type;
+public:
+ inversive_congruential(IntType x0 = 1) : base_type(x0) {}
+ template<class It>
+ inversive_congruential(It& first, It last) : base_type(first, last) {}
+};
+
+/// \endcond
/**
* The specialization hellekalek1995 was suggested in
@@ -165,9 +253,15 @@
* (editors), 1995, pp. 255-262. ftp://random.mat.sbg.ac.at/pub/data/wsc95.ps
* @endblockquote
*/
-typedef random::inversive_congruential<int32_t, 9102, 2147483647-36884165,
- 2147483647, 0> hellekalek1995;
+typedef inversive_congruential_engine<uint32_t, 9102, 2147483647-36884165,
+ 2147483647> hellekalek1995;
+
+} // namespace random
+
+using random::hellekalek1995;
} // namespace boost
+#include <boost/random/detail/enable_warnings.hpp>
+
#endif // BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
Modified: branches/release/boost/random/lagged_fibonacci.hpp
==============================================================================
--- branches/release/boost/random/lagged_fibonacci.hpp (original)
+++ branches/release/boost/random/lagged_fibonacci.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,289 +16,223 @@
#ifndef BOOST_RANDOM_LAGGED_FIBONACCI_HPP
#define BOOST_RANDOM_LAGGED_FIBONACCI_HPP
-#include <boost/config/no_tr1/cmath.hpp>
-#include <iostream>
+#include <istream>
+#include <iosfwd>
#include <algorithm> // std::max
#include <iterator>
#include <boost/config/no_tr1/cmath.hpp> // std::pow
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
-#include <boost/detail/workaround.hpp>
+#include <boost/integer/integer_mask.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
-#include <boost/random/detail/pass_through_engine.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/generator_seed_seq.hpp>
namespace boost {
namespace random {
-#if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
-# define BOOST_RANDOM_EXTRACT_LF
-#endif
-
-#if defined(__APPLE_CC__) && defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
-# define BOOST_RANDOM_EXTRACT_LF
-#endif
-
-# ifdef BOOST_RANDOM_EXTRACT_LF
-namespace detail
-{
- template<class IStream, class F, class RealType>
- IStream&
- extract_lagged_fibonacci_01(
- IStream& is
- , F const& f
- , unsigned int& i
- , RealType* x
- , RealType modulus)
- {
- is >> i >> std::ws;
- for(unsigned int i = 0; i < f.long_lag; ++i)
- {
- RealType value;
- is >> value >> std::ws;
- x[i] = value / modulus;
- }
- return is;
- }
-
- template<class IStream, class F, class UIntType>
- IStream&
- extract_lagged_fibonacci(
- IStream& is
- , F const& f
- , unsigned int& i
- , UIntType* x)
- {
- is >> i >> std::ws;
- for(unsigned int i = 0; i < f.long_lag; ++i)
- is >> x[i] >> std::ws;
- return is;
- }
-}
-# endif
-
/**
- * Instantiations of class template \lagged_fibonacci model a
+ * Instantiations of class template \lagged_fibonacci_engine model a
* \pseudo_random_number_generator. It uses a lagged Fibonacci
* algorithm with two lags @c p and @c q:
* x(i) = x(i-p) + x(i-q) (mod 2<sup>w</sup>) with p > q.
*/
-template<class UIntType, int w, unsigned int p, unsigned int q,
- UIntType val = 0>
-class lagged_fibonacci
+template<class UIntType, int w, unsigned int p, unsigned int q>
+class lagged_fibonacci_engine
{
public:
- typedef UIntType result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, word_size = w);
- BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
- BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
-
- /**
- * Returns: the smallest value that the generator can produce
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
- /**
- * Returns: the largest value that the generator can produce
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return wordmask; }
-
- /**
- * Creates a new @c lagged_fibonacci generator and calls @c seed()
- */
- lagged_fibonacci() { init_wordmask(); seed(); }
- /**
- * Creates a new @c lagged_fibonacci generator and calls @c seed(value)
- */
- explicit lagged_fibonacci(uint32_t value) { init_wordmask(); seed(value); }
- /**
- * Creates a new @c lagged_fibonacci generator and calls @c seed(first, last)
- */
- template<class It> lagged_fibonacci(It& first, It last)
- { init_wordmask(); seed(first, last); }
- // compiler-generated copy ctor and assignment operator are fine
+ typedef UIntType result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(int, word_size = w);
+ BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
+ BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
+
+ BOOST_STATIC_CONSTANT(UIntType, default_seed = 331u);
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return low_bits_mask_t<w>::sig_bits; }
+
+ /** Creates a new @c lagged_fibonacci_engine and calls @c seed(). */
+ lagged_fibonacci_engine() { seed(); }
+
+ /** Creates a new @c lagged_fibonacci_engine and calls @c seed(value). */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_engine,
+ UIntType, value)
+ { seed(value); }
+
+ /** Creates a new @c lagged_fibonacci_engine and calls @c seed(seq). */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ /**
+ * Creates a new @c lagged_fibonacci_engine and calls @c seed(first, last).
+ */
+ template<class It> lagged_fibonacci_engine(It& first, It last)
+ { seed(first, last); }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Calls @c seed(default_seed). */
+ void seed() { seed(default_seed); }
+
+ /**
+ * Sets the state of the generator to values produced by
+ * a \minstd_rand0 generator.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_engine,
+ UIntType, value)
+ {
+ minstd_rand0 intgen(static_cast<boost::uint32_t>(value));
+ detail::generator_seed_seq<minstd_rand0> gen(intgen);
+ seed(gen);
+ }
-private:
- /// \cond hide_private_members
- void init_wordmask()
- {
- wordmask = 0;
- for(int j = 0; j < w; ++j)
- wordmask |= (1u << j);
- }
- /// \endcond
+ /**
+ * Sets the state of the generator using values produced by seq.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_engine, SeedSeq, seq)
+ {
+ detail::seed_array_int<w>(seq, x);
+ i = long_lag;
+ }
-public:
- /**
- * Sets the state of the generator to values produced by
- * a \minstd_rand generator.
- */
- void seed(uint32_t value = 331u)
- {
- minstd_rand0 gen(value);
- for(unsigned int j = 0; j < long_lag; ++j)
- x[j] = gen() & wordmask;
- i = long_lag;
- }
-
- /**
- * Sets the state of the generator to values from the iterator
- * range [first, last). If there are not enough elements in the
- * range [first, last) throws @c std::invalid_argument.
- */
- template<class It>
- void seed(It& first, It last)
- {
- // word size could be smaller than the seed values
- unsigned int j;
- for(j = 0; j < long_lag && first != last; ++j, ++first)
- x[j] = *first & wordmask;
- i = long_lag;
- if(first == last && j < long_lag)
- throw std::invalid_argument("lagged_fibonacci::seed");
- }
-
- /**
- * Returns: the next value of the generator
- */
- result_type operator()()
- {
- if(i >= long_lag)
- fill();
- return x[i++];
- }
-
- static bool validation(result_type x)
- {
- return x == val;
- }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
+ /**
+ * Sets the state of the generator to values from the iterator
+ * range [first, last). If there are not enough elements in the
+ * range [first, last) throws @c std::invalid_argument.
+ */
+ template<class It>
+ void seed(It& first, It last)
+ {
+ detail::fill_array_int<w>(first, last, x);
+ i = long_lag;
+ }
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const lagged_fibonacci& f)
- {
- os << f.i << " ";
- for(unsigned int i = 0; i < f.long_lag; ++i)
- os << f.x[i] << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT, Traits>&
- operator>>(std::basic_istream<CharT, Traits>& is, lagged_fibonacci& f)
- {
-# ifdef BOOST_RANDOM_EXTRACT_LF
- return detail::extract_lagged_fibonacci(is, f, f.i, f.x);
-# else
- is >> f.i >> std::ws;
- for(unsigned int i = 0; i < f.long_lag; ++i)
- is >> f.x[i] >> std::ws;
- return is;
-# endif
- }
-#endif
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ if(i >= long_lag)
+ fill();
+ return x[i++];
+ }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
- friend bool operator==(const lagged_fibonacci& x, const lagged_fibonacci& y)
- { return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
- friend bool operator!=(const lagged_fibonacci& x,
- const lagged_fibonacci& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const lagged_fibonacci& rhs) const
- { return i == rhs.i && std::equal(x, x+long_lag, rhs.x); }
- bool operator!=(const lagged_fibonacci& rhs) const
- { return !(*this == rhs); }
-#endif
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
+
+ /**
+ * Writes the textual representation of the generator to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_engine, f)
+ {
+ os << f.i;
+ for(unsigned int i = 0; i < f.long_lag; ++i)
+ os << ' ' << f.x[i];
+ return os;
+ }
+
+ /**
+ * Reads the textual representation of the generator from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_engine, f)
+ {
+ is >> f.i >> std::ws;
+ for(unsigned int i = 0; i < f.long_lag; ++i)
+ is >> f.x[i] >> std::ws;
+ return is;
+ }
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_engine, x, y)
+ { return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
+
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_engine)
private:
- /// \cond hide_private_members
- void fill();
- /// \endcond
-
- UIntType wordmask;
- unsigned int i;
- UIntType x[long_lag];
+ /// \cond show_private
+ void fill();
+ /// \endcond
+
+ unsigned int i;
+ UIntType x[long_lag];
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
-const bool lagged_fibonacci<UIntType, w, p, q, val>::has_fixed_range;
-template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
-const unsigned int lagged_fibonacci<UIntType, w, p, q, val>::long_lag;
-template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
-const unsigned int lagged_fibonacci<UIntType, w, p, q, val>::short_lag;
+template<class UIntType, int w, unsigned int p, unsigned int q>
+const bool lagged_fibonacci_engine<UIntType, w, p, q>::has_fixed_range;
+template<class UIntType, int w, unsigned int p, unsigned int q>
+const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::long_lag;
+template<class UIntType, int w, unsigned int p, unsigned int q>
+const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::short_lag;
+template<class UIntType, int w, unsigned int p, unsigned int q>
+const UIntType lagged_fibonacci_engine<UIntType, w, p, q>::default_seed;
#endif
-/// \cond hide_private_members
+/// \cond show_private
-template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
-void lagged_fibonacci<UIntType, w, p, q, val>::fill()
+template<class UIntType, int w, unsigned int p, unsigned int q>
+void lagged_fibonacci_engine<UIntType, w, p, q>::fill()
{
- // two loops to avoid costly modulo operations
- { // extra scope for MSVC brokenness w.r.t. for scope
- for(unsigned int j = 0; j < short_lag; ++j)
- x[j] = (x[j] + x[j+(long_lag-short_lag)]) & wordmask;
- }
- for(unsigned int j = short_lag; j < long_lag; ++j)
- x[j] = (x[j] + x[j-short_lag]) & wordmask;
- i = 0;
+ // two loops to avoid costly modulo operations
+ { // extra scope for MSVC brokenness w.r.t. for scope
+ for(unsigned int j = 0; j < short_lag; ++j)
+ x[j] = (x[j] + x[j+(long_lag-short_lag)]) & low_bits_mask_t<w>::sig_bits;
+ }
+ for(unsigned int j = short_lag; j < long_lag; ++j)
+ x[j] = (x[j] + x[j-short_lag]) & low_bits_mask_t<w>::sig_bits;
+ i = 0;
}
+/// \endcond
+/// \cond show_deprecated
-// lagged Fibonacci generator for the range [0..1)
-// contributed by Matthias Troyer
-// for p=55, q=24 originally by G. J. Mitchell and D. P. Moore 1958
-
-template<class T, unsigned int p, unsigned int q>
-struct fibonacci_validation
+// provided for backwards compatibility
+template<class UIntType, int w, unsigned int p, unsigned int q, UIntType v = 0>
+class lagged_fibonacci : public lagged_fibonacci_engine<UIntType, w, p, q>
{
- BOOST_STATIC_CONSTANT(bool, is_specialized = false);
- static T value() { return 0; }
- static T tolerance() { return 0; }
-};
-
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-// A definition is required even for integral static constants
-template<class T, unsigned int p, unsigned int q>
-const bool fibonacci_validation<T, p, q>::is_specialized;
-#endif
-
-#define BOOST_RANDOM_FIBONACCI_VAL(T,P,Q,V,E) \
-template<> \
-struct fibonacci_validation<T, P, Q> \
-{ \
- BOOST_STATIC_CONSTANT(bool, is_specialized = true); \
- static T value() { return V; } \
- static T tolerance() \
-{ return (std::max)(E, static_cast<T>(5*std::numeric_limits<T>::epsilon())); } \
+ typedef lagged_fibonacci_engine<UIntType, w, p, q> base_type;
+public:
+ lagged_fibonacci() {}
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci, UIntType, val)
+ { this->seed(val); }
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci, SeedSeq, seq)
+ { this->seed(seq); }
+ template<class It>
+ lagged_fibonacci(It& first, It last) : base_type(first, last) {}
};
-// (The extra static_cast<T> in the std::max call above is actually
-// unnecessary except for HP aCC 1.30, which claims that
-// numeric_limits<double>::epsilon() doesn't actually return a double.)
-
-BOOST_RANDOM_FIBONACCI_VAL(double, 607, 273, 0.4293817707235914, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 1279, 418, 0.9421630240437659, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 2281, 1252, 0.1768114046909004, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 3217, 576, 0.1956232694868209, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 4423, 2098, 0.9499762202147172, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 9689, 5502, 0.05737836943695162, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 19937, 9842, 0.5076528587449834, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 23209, 13470, 0.5414473810619185, 1e-14)
-BOOST_RANDOM_FIBONACCI_VAL(double, 44497,21034, 0.254135073399297, 1e-14)
-
-#undef BOOST_RANDOM_FIBONACCI_VAL
/// \endcond
+// lagged Fibonacci generator for the range [0..1)
+// contributed by Matthias Troyer
+// for p=55, q=24 originally by G. J. Mitchell and D. P. Moore 1958
+
/**
* Instantiations of class template @c lagged_fibonacci_01 model a
* \pseudo_random_number_generator. It uses a lagged Fibonacci
@@ -322,216 +256,215 @@
* 4856 bytes and \lagged_fibonacci44497 requires about 350 KBytes.
*/
template<class RealType, int w, unsigned int p, unsigned int q>
-class lagged_fibonacci_01
+class lagged_fibonacci_01_engine
{
public:
- typedef RealType result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, word_size = w);
- BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
- BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
-
- /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(). */
- lagged_fibonacci_01() { init_modulus(); seed(); }
- /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(value). */
- BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, uint32_t, value)
- { init_modulus(); seed(value); }
- /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(gen). */
- BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(lagged_fibonacci_01, Generator, gen)
- { init_modulus(); seed(gen); }
- template<class It> lagged_fibonacci_01(It& first, It last)
- { init_modulus(); seed(first, last); }
- // compiler-generated copy ctor and assignment operator are fine
+ typedef RealType result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(int, word_size = w);
+ BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
+ BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
+
+ BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 331u);
+
+ /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(). */
+ lagged_fibonacci_01_engine() { seed(); }
+ /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(value). */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01_engine, uint32_t, value)
+ { seed(value); }
+ /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(gen). */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01_engine, SeedSeq, seq)
+ { seed(seq); }
+ template<class It> lagged_fibonacci_01_engine(It& first, It last)
+ { seed(first, last); }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Calls seed(default_seed). */
+ void seed() { seed(default_seed); }
+
+ /**
+ * Constructs a \minstd_rand0 generator with the constructor parameter
+ * value and calls seed with it. Distinct seeds in the range
+ * [1, 2147483647) will produce generators with different states. Other
+ * seeds will be equivalent to some seed within this range. See
+ * \linear_congruential_engine for details.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine, boost::uint32_t, value)
+ {
+ minstd_rand0 intgen(value);
+ detail::generator_seed_seq<minstd_rand0> gen(intgen);
+ seed(gen);
+ }
-private:
- /// \cond hide_private_members
- void init_modulus()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::pow;
-#endif
- _modulus = pow(RealType(2), word_size);
- }
- /// \endcond
+ /**
+ * Seeds this @c lagged_fibonacci_01_engine using values produced by
+ * @c seq.generate.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_01_engine, SeedSeq, seq)
+ {
+ detail::seed_array_real<w>(seq, x);
+ i = long_lag;
+ }
+
+ /**
+ * Seeds this @c lagged_fibonacci_01_engine using values from the
+ * iterator range [first, last). If there are not enough elements
+ * in the range, throws @c std::invalid_argument.
+ */
+ template<class It>
+ void seed(It& first, It last)
+ {
+ detail::fill_array_real<w>(first, last, x);
+ i = long_lag;
+ }
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(0); }
+ /** Returns the upper bound of the generators outputs. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); }
+
+ /**
+ * INTERNAL ONLY
+ * Returns the number of random bits.
+ * This is not part of the standard, and I'm not sure that
+ * it's the best solution, but something like this is needed
+ * to implement generate_canonical. For now, mark it as
+ * an implementation detail.
+ */
+ static std::size_t precision() { return w; }
-public:
- /** Calls seed(331u). */
- void seed() { seed(331u); }
- /**
- * Constructs a \minstd_rand0 generator with the constructor parameter
- * value and calls seed with it. Distinct seeds in the range
- * [1, 2147483647) will produce generators with different states. Other
- * seeds will be equivalent to some seed within this range. See
- * \linear_congruential for details.
- */
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01, uint32_t, value)
- {
- minstd_rand0 intgen(value);
- seed(intgen);
- }
-
- /**
- * Sets the state of this @c lagged_fibonacci_01 to the values returned
- * by p invocations of \uniform_01<code>\<RealType\>()(gen)</code>.
- *
- * Complexity: Exactly p invocations of gen.
- */
- BOOST_RANDOM_DETAIL_GENERATOR_SEED(lagged_fibonacci, Generator, gen)
- {
- // use pass-by-reference, but wrap argument in pass_through_engine
- typedef detail::pass_through_engine<Generator&> ref_gen;
- uniform_01<ref_gen, RealType> gen01 =
- uniform_01<ref_gen, RealType>(ref_gen(gen));
- // I could have used std::generate_n, but it takes "gen" by value
- for(unsigned int j = 0; j < long_lag; ++j)
- x[j] = gen01();
- i = long_lag;
- }
-
- template<class It>
- void seed(It& first, It last)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::fmod;
- using std::pow;
-#endif
- unsigned long mask = ~((~0u) << (w%32)); // now lowest w bits set
- RealType two32 = pow(RealType(2), 32);
- unsigned int j;
- for(j = 0; j < long_lag && first != last; ++j) {
- x[j] = RealType(0);
- for(int k = 0; k < w/32 && first != last; ++k, ++first)
- x[j] += *first / pow(two32,k+1);
- if(first != last && mask != 0) {
- x[j] += fmod((*first & mask) / _modulus, RealType(1));
- ++first;
- }
- }
- i = long_lag;
- if(first == last && j < long_lag)
- throw std::invalid_argument("lagged_fibonacci_01::seed");
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
-
- result_type operator()()
- {
- if(i >= long_lag)
- fill();
- return x[i++];
- }
-
- static bool validation(result_type x)
- {
- result_type v = fibonacci_validation<result_type, p, q>::value();
- result_type epsilon = fibonacci_validation<result_type, p, q>::tolerance();
- // std::abs is a source of trouble: sometimes, it's not overloaded
- // for double, plus the usual namespace std noncompliance -> avoid it
- // using std::abs;
- // return abs(x - v) < 5 * epsilon
- return x > v - epsilon && x < v + epsilon;
- }
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ if(i >= long_lag)
+ fill();
+ return x[i++];
+ }
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { return detail::generate_from_real(*this, first, last); }
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const lagged_fibonacci_01&f)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::pow;
-#endif
- os << f.i << " ";
- std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
- for(unsigned int i = 0; i < f.long_lag; ++i)
- os << f.x[i] * f._modulus << " ";
- os.flags(oldflags);
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT, Traits>&
- operator>>(std::basic_istream<CharT, Traits>& is, lagged_fibonacci_01& f)
- {
-# ifdef BOOST_RANDOM_EXTRACT_LF
- return detail::extract_lagged_fibonacci_01(is, f, f.i, f.x, f._modulus);
-# else
- is >> f.i >> std::ws;
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
+
+ /**
+ * Writes the textual representation of the generator to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_01_engine, f)
+ {
+ // allow for Koenig lookup
+ using std::pow;
+ os << f.i;
+ std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
+ for(unsigned int i = 0; i < f.long_lag; ++i)
+ os << ' ' << f.x[i] * f.modulus();
+ os.flags(oldflags);
+ return os;
+ }
+
+ /**
+ * Reads the textual representation of the generator from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_01_engine, f)
+ {
+ is >> f.i;
for(unsigned int i = 0; i < f.long_lag; ++i) {
- typename lagged_fibonacci_01::result_type value;
- is >> value >> std::ws;
- f.x[i] = value / f._modulus;
+ typename lagged_fibonacci_01_engine::result_type value;
+ is >> std::ws >> value;
+ f.x[i] = value / f.modulus();
}
return is;
-# endif
}
-#endif
-
- friend bool operator==(const lagged_fibonacci_01& x,
- const lagged_fibonacci_01& y)
- { return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
- friend bool operator!=(const lagged_fibonacci_01& x,
- const lagged_fibonacci_01& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const lagged_fibonacci_01& rhs) const
- { return i == rhs.i && std::equal(x, x+long_lag, rhs.x); }
- bool operator!=(const lagged_fibonacci_01& rhs) const
- { return !(*this == rhs); }
-#endif
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_01_engine, x, y)
+ { return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
+
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_01_engine)
private:
- /// \cond hide_private_members
- void fill();
- /// \endcond
- unsigned int i;
- RealType x[long_lag];
- RealType _modulus;
+ /// \cond show_private
+ void fill();
+ static RealType modulus()
+ {
+ using std::pow;
+ return pow(RealType(2), word_size);
+ }
+ /// \endcond
+ unsigned int i;
+ RealType x[long_lag];
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class RealType, int w, unsigned int p, unsigned int q>
-const bool lagged_fibonacci_01<RealType, w, p, q>::has_fixed_range;
+const bool lagged_fibonacci_01_engine<RealType, w, p, q>::has_fixed_range;
template<class RealType, int w, unsigned int p, unsigned int q>
-const unsigned int lagged_fibonacci_01<RealType, w, p, q>::long_lag;
+const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::long_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
-const unsigned int lagged_fibonacci_01<RealType, w, p, q>::short_lag;
+const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::short_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
-const int lagged_fibonacci_01<RealType,w,p,q>::word_size;
-
+const int lagged_fibonacci_01_engine<RealType,w,p,q>::word_size;
+template<class RealType, int w, unsigned int p, unsigned int q>
+const boost::uint32_t lagged_fibonacci_01_engine<RealType,w,p,q>::default_seed;
#endif
-/// \cond hide_private_members
+/// \cond show_private
template<class RealType, int w, unsigned int p, unsigned int q>
-void lagged_fibonacci_01<RealType, w, p, q>::fill()
+void lagged_fibonacci_01_engine<RealType, w, p, q>::fill()
{
- // two loops to avoid costly modulo operations
- { // extra scope for MSVC brokenness w.r.t. for scope
- for(unsigned int j = 0; j < short_lag; ++j) {
- RealType t = x[j] + x[j+(long_lag-short_lag)];
- if(t >= RealType(1))
- t -= RealType(1);
- x[j] = t;
- }
- }
- for(unsigned int j = short_lag; j < long_lag; ++j) {
- RealType t = x[j] + x[j-short_lag];
- if(t >= RealType(1))
- t -= RealType(1);
- x[j] = t;
- }
- i = 0;
+ // two loops to avoid costly modulo operations
+ { // extra scope for MSVC brokenness w.r.t. for scope
+ for(unsigned int j = 0; j < short_lag; ++j) {
+ RealType t = x[j] + x[j+(long_lag-short_lag)];
+ if(t >= RealType(1))
+ t -= RealType(1);
+ x[j] = t;
+ }
+ }
+ for(unsigned int j = short_lag; j < long_lag; ++j) {
+ RealType t = x[j] + x[j-short_lag];
+ if(t >= RealType(1))
+ t -= RealType(1);
+ x[j] = t;
+ }
+ i = 0;
}
/// \endcond
-} // namespace random
+/// \cond show_deprecated
+
+// provided for backwards compatibility
+template<class RealType, int w, unsigned int p, unsigned int q>
+class lagged_fibonacci_01 : public lagged_fibonacci_01_engine<RealType, w, p, q>
+{
+ typedef lagged_fibonacci_01_engine<RealType, w, p, q> base_type;
+public:
+ lagged_fibonacci_01() {}
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, boost::uint32_t, val)
+ { this->seed(val); }
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01, SeedSeq, seq)
+ { this->seed(seq); }
+ template<class It>
+ lagged_fibonacci_01(It& first, It last) : base_type(first, last) {}
+};
+
+/// \endcond
#ifdef BOOST_RANDOM_DOXYGEN
namespace detail {
@@ -558,47 +491,36 @@
}
#endif
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 607, 273> lagged_fibonacci607;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 1279, 418> lagged_fibonacci1279;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 2281, 1252> lagged_fibonacci2281;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 3217, 576> lagged_fibonacci3217;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 4423, 2098> lagged_fibonacci4423;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 9689, 5502> lagged_fibonacci9689;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 19937, 9842> lagged_fibonacci19937;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 23209, 13470> lagged_fibonacci23209;
-/**
- * @copydoc boost::detail::lagged_fibonacci_doc
- */
-typedef random::lagged_fibonacci_01<double, 48, 44497, 21034> lagged_fibonacci44497;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 607, 273> lagged_fibonacci607;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 1279, 418> lagged_fibonacci1279;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 2281, 1252> lagged_fibonacci2281;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 3217, 576> lagged_fibonacci3217;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 4423, 2098> lagged_fibonacci4423;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 9689, 5502> lagged_fibonacci9689;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 19937, 9842> lagged_fibonacci19937;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 23209, 13470> lagged_fibonacci23209;
+/** @copydoc boost::random::detail::lagged_fibonacci_doc */
+typedef lagged_fibonacci_01_engine<double, 48, 44497, 21034> lagged_fibonacci44497;
+} // namespace random
-// It is possible to partially specialize uniform_01<> on lagged_fibonacci_01<>
-// to help the compiler generate efficient code. For GCC, this seems useless,
-// because GCC optimizes (x-0)/(1-0) to (x-0). This is good enough for now.
+using random::lagged_fibonacci607;
+using random::lagged_fibonacci1279;
+using random::lagged_fibonacci2281;
+using random::lagged_fibonacci3217;
+using random::lagged_fibonacci4423;
+using random::lagged_fibonacci9689;
+using random::lagged_fibonacci19937;
+using random::lagged_fibonacci23209;
+using random::lagged_fibonacci44497;
} // namespace boost
Modified: branches/release/boost/random/linear_congruential.hpp
==============================================================================
--- branches/release/boost/random/linear_congruential.hpp (original)
+++ branches/release/boost/random/linear_congruential.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,13 +17,19 @@
#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
#include <iostream>
-#include <cassert>
#include <stdexcept>
+#include <boost/assert.hpp>
#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
+#include <boost/integer/static_log2.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/const_mod.hpp>
+#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/seed_impl.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/detail/disable_warnings.hpp>
@@ -32,13 +38,15 @@
namespace random {
/**
- * Instantiations of class template linear_congruential model a
+ * Instantiations of class template linear_congruential_engine model a
* \pseudo_random_number_generator. Linear congruential pseudo-random
* number generators are described in:
*
+ * @blockquote
* "Mathematical methods in large-scale computing units", D. H. Lehmer,
* Proc. 2nd Symposium on Large-Scale Digital Calculating Machines,
* Harvard University Press, 1951, pp. 141-146
+ * @endblockquote
*
* Let x(n) denote the sequence of numbers returned by some pseudo-random
* number generator. Then for the linear congruential generator,
@@ -51,208 +59,250 @@
* the parameters. User code should use one of the sensibly parameterized
* generators such as minstd_rand instead.
*/
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-class linear_congruential
+template<class IntType, IntType a, IntType c, IntType m>
+class linear_congruential_engine
{
public:
- typedef IntType result_type;
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const result_type min_value = ( c == 0 ? 1 : 0 );
- static const result_type max_value = m-1;
-#else
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-#endif
- BOOST_STATIC_CONSTANT(IntType, multiplier = a);
- BOOST_STATIC_CONSTANT(IntType, increment = c);
- BOOST_STATIC_CONSTANT(IntType, modulus = m);
-
- // MSVC 6 and possibly others crash when encountering complicated integral
- // constant expressions. Avoid the check for now.
- // BOOST_STATIC_ASSERT(m == 0 || a < m);
- // BOOST_STATIC_ASSERT(m == 0 || c < m);
-
- /**
- * Constructs a linear_congruential generator, seeding it with @c x0.
- */
- explicit linear_congruential(IntType x0 = 1)
- {
- seed(x0);
+ typedef IntType result_type;
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ // Required for old Boost.Random concept
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+ BOOST_STATIC_CONSTANT(IntType, multiplier = a);
+ BOOST_STATIC_CONSTANT(IntType, increment = c);
+ BOOST_STATIC_CONSTANT(IntType, modulus = m);
+ BOOST_STATIC_CONSTANT(IntType, default_seed = 1);
+
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
-#endif
- }
+ BOOST_STATIC_ASSERT(m == 0 || a < m);
+ BOOST_STATIC_ASSERT(m == 0 || c < m);
+
+ /**
+ * Constructs a @c linear_congruential_engine, using the default seed
+ */
+ linear_congruential_engine() { seed(); }
+
+ /**
+ * Constructs a @c linear_congruential_engine, seeding it with @c x0.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_congruential_engine,
+ IntType, x0)
+ { seed(x0); }
+
+ /**
+ * Constructs a @c linear_congruential_engine, seeding it with values
+ * produced by a call to @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_congruential_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ /**
+ * Constructs a @c linear_congruential_engine and seeds it
+ * with values taken from the itrator range [first, last)
+ * and adjusts first to point to the element after the last one
+ * used. If there are not enough elements, throws @c std::invalid_argument.
+ *
+ * first and last must be input iterators.
+ */
+ template<class It>
+ linear_congruential_engine(It& first, It last)
+ {
+ seed(first, last);
+ }
+
+ // compiler-generated copy constructor and assignment operator are fine
- /**
- * Constructs a @c linear_congruential generator and seeds it
- * with values taken from the itrator range [first, last)
- * and adjusts first to point to the element after the last one
- * used. If there are not enough elements, throws @c std::invalid_argument.
- *
- * first and last must be input iterators.
- */
- template<class It>
- linear_congruential(It& first, It last)
- {
- seed(first, last);
- }
-
- // compiler-generated copy constructor and assignment operator are fine
-
- /**
- * If c mod m is zero and x0 mod m is zero, changes the current value of
- * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
- * distinct seeds in the range [1,m) will leave the generator in distinct
- * states. If c is not zero, the range is [0,m).
- */
- void seed(IntType x0 = 1)
- {
- // wrap _x if it doesn't fit in the destination
- if(modulus == 0) {
- _x = x0;
- } else {
- _x = x0 % modulus;
+ /**
+ * Calls seed(default_seed)
+ */
+ void seed() { seed(default_seed); }
+
+ /**
+ * If c mod m is zero and x0 mod m is zero, changes the current value of
+ * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
+ * distinct seeds in the range [1,m) will leave the generator in distinct
+ * states. If c is not zero, the range is [0,m).
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_congruential_engine, IntType, x0)
+ {
+ // wrap _x if it doesn't fit in the destination
+ if(modulus == 0) {
+ _x = x0;
+ } else {
+ _x = x0 % modulus;
+ }
+ // handle negative seeds
+ if(_x <= 0 && _x != 0) {
+ _x += modulus;
+ }
+ // adjust to the correct range
+ if(increment == 0 && _x == 0) {
+ _x = 1;
+ }
+ BOOST_ASSERT(_x >= (min)());
+ BOOST_ASSERT(_x <= (max)());
}
- // handle negative seeds
- if(_x <= 0 && _x != 0) {
- _x += modulus;
+
+ /**
+ * Seeds a @c linear_congruential_engine using values from a SeedSeq.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_congruential_engine, SeedSeq, seq)
+ { seed(detail::seed_one_int<IntType, m>(seq)); }
+
+ /**
+ * seeds a @c linear_congruential_engine with values taken
+ * from the itrator range [first, last) and adjusts @c first to
+ * point to the element after the last one used. If there are
+ * not enough elements, throws @c std::invalid_argument.
+ *
+ * @c first and @c last must be input iterators.
+ */
+ template<class It>
+ void seed(It& first, It last)
+ { seed(detail::get_one_int<IntType, m>(first, last)); }
+
+ /**
+ * Returns the smallest value that the @c linear_congruential_engine
+ * can produce.
+ */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return c == 0 ? 1 : 0; }
+ /**
+ * Returns the largest value that the @c linear_congruential_engine
+ * can produce.
+ */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return modulus-1; }
+
+ /** Returns the next value of the @c linear_congruential_engine. */
+ IntType operator()()
+ {
+ _x = const_mod<IntType, m>::mult_add(a, _x, c);
+ return _x;
}
- // adjust to the correct range
- if(increment == 0 && _x == 0) {
- _x = 1;
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ typedef const_mod<IntType, m> mod_type;
+ IntType b_inv = mod_type::invert(a-1);
+ IntType b_gcd = mod_type::mult(a-1, b_inv);
+ if(b_gcd == 1) {
+ IntType a_z = mod_type::pow(a, z);
+ _x = mod_type::mult_add(a_z, _x,
+ mod_type::mult(mod_type::mult(c, b_inv), a_z - 1));
+ } else {
+ // compute (a^z - 1)*c % (b_gcd * m) / (b / b_gcd) * inv(b / b_gcd)
+ // we're storing the intermediate result / b_gcd
+ IntType a_zm1_over_gcd = 0;
+ IntType a_km1_over_gcd = (a - 1) / b_gcd;
+ boost::uintmax_t exponent = z;
+ while(exponent != 0) {
+ if(exponent % 2 == 1) {
+ a_zm1_over_gcd =
+ mod_type::mult_add(
+ b_gcd,
+ mod_type::mult(a_zm1_over_gcd, a_km1_over_gcd),
+ mod_type::add(a_zm1_over_gcd, a_km1_over_gcd));
+ }
+ a_km1_over_gcd = mod_type::mult_add(
+ b_gcd,
+ mod_type::mult(a_km1_over_gcd, a_km1_over_gcd),
+ mod_type::add(a_km1_over_gcd, a_km1_over_gcd));
+ exponent /= 2;
+ }
+
+ IntType a_z = mod_type::mult_add(b_gcd, a_zm1_over_gcd, 1);
+ IntType num = mod_type::mult(c, a_zm1_over_gcd);
+ b_inv = mod_type::invert((a-1)/b_gcd);
+ _x = mod_type::mult_add(a_z, _x, mod_type::mult(b_inv, num));
+ }
}
- assert(_x >= (min)());
- assert(_x <= (max)());
- }
-
- /**
- * seeds a @c linear_congruential generator with values taken
- * from the itrator range [first, last) and adjusts @c first to
- * point to the element after the last one used. If there are
- * not enough elements, throws @c std::invalid_argument.
- *
- * @c first and @c last must be input iterators.
- */
- template<class It>
- void seed(It& first, It last)
- {
- if(first == last)
- throw std::invalid_argument("linear_congruential::seed");
- seed(*first++);
- }
-
- /**
- * Returns the smallest value that the @c linear_congruential generator
- * can produce.
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return c == 0 ? 1 : 0; }
- /**
- * Returns the largest value that the @c linear_congruential generator
- * can produce.
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return modulus-1; }
-
- /** Returns the next value of the @c linear_congruential generator. */
- IntType operator()()
- {
- _x = const_mod<IntType, m>::mult_add(a, _x, c);
- return _x;
- }
-
- static bool validation(IntType x) { return val == x; }
-#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
+ friend bool operator==(const linear_congruential_engine& x,
+ const linear_congruential_engine& y)
+ { return x._x == y._x; }
+ friend bool operator!=(const linear_congruential_engine& x,
+ const linear_congruential_engine& y)
+ { return !(x == y); }
- // Use a member function; Streamable concept not supported.
- bool operator==(const linear_congruential& rhs) const
- { return _x == rhs._x; }
- bool operator!=(const linear_congruential& rhs) const
- { return !(*this == rhs); }
-
-#else
- friend bool operator==(const linear_congruential& x,
- const linear_congruential& y)
- { return x._x == y._x; }
- friend bool operator!=(const linear_congruential& x,
- const linear_congruential& y)
- { return !(x == y); }
-
-#if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os,
- const linear_congruential& lcg)
- {
- return os << lcg._x;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is,
- linear_congruential& lcg)
- {
- return is >> lcg._x;
- }
-
-private:
-#endif
+#if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS)
+ /** Writes a @c linear_congruential_engine to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const linear_congruential_engine& lcg)
+ {
+ return os << lcg._x;
+ }
+
+ /** Reads a @c linear_congruential_engine from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is,
+ linear_congruential_engine& lcg)
+ {
+ lcg.read(is);
+ return is;
+ }
#endif
- IntType _x;
-};
+private:
-// probably needs the "no native streams" caveat for STLPort
-#if !defined(__SGI_STL_PORT) && BOOST_WORKAROUND(__GNUC__, == 2)
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-std::ostream&
-operator<<(std::ostream& os,
- const linear_congruential<IntType,a,c,m,val>& lcg)
-{
- return os << lcg._x;
-}
+ /// \cond show_private
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-std::istream&
-operator>>(std::istream& is,
- linear_congruential<IntType,a,c,m,val>& lcg)
-{
- return is >> lcg._x;
-}
-#elif defined(BOOST_RANDOM_NO_STREAM_OPERATORS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
-template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
-std::basic_ostream<CharT,Traits>&
-operator<<(std::basic_ostream<CharT,Traits>& os,
- const linear_congruential<IntType,a,c,m,val>& lcg)
-{
- return os << lcg._x;
-}
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is) {
+ IntType x;
+ if(is >> x) {
+ if(x >= (min)() && x <= (max)()) {
+ _x = x;
+ } else {
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ }
-template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
-std::basic_istream<CharT,Traits>&
-operator>>(std::basic_istream<CharT,Traits>& is,
- linear_congruential<IntType,a,c,m,val>& lcg)
-{
- return is >> lcg._x;
-}
-#endif
+ /// \endcond
+
+ IntType _x;
+};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-const bool linear_congruential<IntType, a, c, m, val>::has_fixed_range;
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::min_value;
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::max_value;
-template<class IntType, IntType a, IntType c, IntType m, IntType val>
-const IntType linear_congruential<IntType,a,c,m,val>::modulus;
-#endif
+template<class IntType, IntType a, IntType c, IntType m>
+const bool linear_congruential_engine<IntType, a, c, m>::has_fixed_range;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::multiplier;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::increment;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::modulus;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::default_seed;
+#endif
+
+/// \cond show_deprecated
+
+// provided for backwards compatibility
+template<class IntType, IntType a, IntType c, IntType m, IntType val = 0>
+class linear_congruential : public linear_congruential_engine<IntType, a, c, m>
+{
+ typedef linear_congruential_engine<IntType, a, c, m> base_type;
+public:
+ linear_congruential(IntType x0 = 1) : base_type(x0) {}
+ template<class It>
+ linear_congruential(It& first, It last) : base_type(first, last) {}
+};
-} // namespace random
+/// \endcond
-// validation values from the publications
/**
* The specialization \minstd_rand0 was originally suggested in
*
@@ -270,8 +320,7 @@
* the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201
* @endblockquote
*/
-typedef random::linear_congruential<int32_t, 16807, 0, 2147483647,
- 1043618065> minstd_rand0;
+typedef linear_congruential_engine<uint32_t, 16807, 0, 2147483647> minstd_rand0;
/** The specialization \minstd_rand was suggested in
*
@@ -281,12 +330,12 @@
* the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201
* @endblockquote
*/
-typedef random::linear_congruential<int32_t, 48271, 0, 2147483647,
- 399268537> minstd_rand;
+typedef linear_congruential_engine<uint32_t, 48271, 0, 2147483647> minstd_rand;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-/** Class @c rand48 models a \pseudo_random_number_generator. It uses
+/**
+ * Class @c rand48 models a \pseudo_random_number_generator. It uses
* the linear congruential algorithm with the parameters a = 0x5DEECE66D,
* c = 0xB, m = 2**48. It delivers identical results to the @c lrand48()
* function available on some systems (assuming lcong48 has not been called).
@@ -298,104 +347,118 @@
class rand48
{
public:
- typedef int32_t result_type;
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const int32_t min_value = 0;
- static const int32_t max_value = integer_traits<int32_t>::const_max;
-#else
- enum { has_fixed_range = false };
-#endif
- /**
- * Returns the smallest value that the generator can produce
- */
- int32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
- /**
- * Returns the largest value that the generator can produce
- */
- int32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<int32_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }
-
-#ifdef BOOST_RANDOM_DOXYGEN
- /**
- * If T is an integral type smaller than int46_t, constructs
- * a \rand48 generator with x(0) := (x0 << 16) | 0x330e. Otherwise
- * constructs a \rand48 generator with x(0) = x0.
- */
- template<class T> explicit rand48(T x0 = 1);
-#else
- rand48() : lcf(cnv(static_cast<int32_t>(1))) {}
- template<class T> explicit rand48(T x0) : lcf(cnv(x0)) { }
-#endif
- template<class It> rand48(It& first, It last) : lcf(first, last) { }
-
- // compiler-generated copy ctor and assignment operator are fine
+ typedef boost::uint32_t result_type;
-#ifdef BOOST_RANDOM_DOXYGEN
- /**
- * If T is an integral type smaller than int46_t, changes
- * the current value x(n) of the generator to (x0 << 16) | 0x330e.
- * Otherwise changes the current value x(n) to x0.
- */
- template<class T> void seed(T x0 = 1);
-#else
- void seed() { seed(static_cast<int32_t>(1)); }
- template<class T> void seed(T x0) { lcf.seed(cnv(x0)); }
-#endif
- template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
-
- /**
- * Returns the next value of the generator.
- */
- int32_t operator()() { return static_cast<int32_t>(lcf() >> 17); }
- // by experiment from lrand48()
- static bool validation(int32_t x) { return x == 1993516219; }
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ /**
+ * Returns the smallest value that the generator can produce
+ */
+ static uint32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ /**
+ * Returns the largest value that the generator can produce
+ */
+ static uint32_t max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return 0x7FFFFFFF; }
+
+ /** Seeds the generator with the default seed. */
+ rand48() : lcf(cnv(static_cast<uint32_t>(1))) {}
+ /**
+ * Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0)
+ { seed(x0); }
+ /**
+ * Seeds the generator with values produced by @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq)
+ { seed(seq); }
+ /**
+ * Seeds the generator using values from an iterator range,
+ * and updates first to point one past the last value consumed.
+ */
+ template<class It> rand48(It& first, It last) : lcf(first, last) { }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Seeds the generator with the default seed. */
+ void seed() { seed(static_cast<uint32_t>(1)); }
+ /**
+ * Changes the current value x(n) of the generator to (x0 << 16) | 0x330e.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0)
+ { lcf.seed(cnv(x0)); }
+ /**
+ * Seeds the generator using values from an iterator range,
+ * and updates first to point one past the last value consumed.
+ */
+ template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
+ /**
+ * Seeds the generator with values produced by @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq)
+ { lcf.seed(seq); }
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
+ /** Returns the next value of the generator. */
+ uint32_t operator()() { return static_cast<uint32_t>(lcf() >> 17); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z) { lcf.discard(z); }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ {
+ for(; first != last; ++first) {
+ *first = (*this)();
+ }
+ }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT,class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
- { os << r.lcf; return os; }
-
- template<class CharT,class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
- { is >> r.lcf; return is; }
-#endif
-
- friend bool operator==(const rand48& x, const rand48& y)
- { return x.lcf == y.lcf; }
- friend bool operator!=(const rand48& x, const rand48& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const rand48& rhs) const
- { return lcf == rhs.lcf; }
- bool operator!=(const rand48& rhs) const
- { return !(*this == rhs); }
-#endif
+ /** Writes a @c rand48 to a @c std::ostream. */
+ template<class CharT,class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
+ { os << r.lcf; return os; }
+
+ /** Reads a @c rand48 from a @c std::istream. */
+ template<class CharT,class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
+ { is >> r.lcf; return is; }
+#endif
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of values.
+ */
+ friend bool operator==(const rand48& x, const rand48& y)
+ { return x.lcf == y.lcf; }
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of values.
+ */
+ friend bool operator!=(const rand48& x, const rand48& y)
+ { return !(x == y); }
private:
- /// \cond hide_private_members
- random::linear_congruential<uint64_t,
- uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32), // xxxxULL is not portable
- 0xB, uint64_t(1)<<48, /* unknown */ 0> lcf;
- template<class T>
- static uint64_t cnv(T x)
- {
- if(sizeof(T) < sizeof(uint64_t)) {
- return (static_cast<uint64_t>(x) << 16) | 0x330e;
- } else {
- return(static_cast<uint64_t>(x));
- }
- }
- static uint64_t cnv(float x) { return(static_cast<uint64_t>(x)); }
- static uint64_t cnv(double x) { return(static_cast<uint64_t>(x)); }
- static uint64_t cnv(long double x) { return(static_cast<uint64_t>(x)); }
- /// \endcond
+ /// \cond show_private
+ typedef random::linear_congruential_engine<uint64_t,
+ // xxxxULL is not portable
+ uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32),
+ 0xB, uint64_t(1)<<48> lcf_t;
+ lcf_t lcf;
+
+ static boost::uint64_t cnv(boost::uint32_t x)
+ { return (static_cast<uint64_t>(x) << 16) | 0x330e; }
+ /// \endcond
};
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
+} // namespace random
+
+using random::minstd_rand0;
+using random::minstd_rand;
+using random::rand48;
+
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
Modified: branches/release/boost/random/linear_feedback_shift.hpp
==============================================================================
--- branches/release/boost/random/linear_feedback_shift.hpp (original)
+++ branches/release/boost/random/linear_feedback_shift.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
-/* boost random/tausworthe.hpp header file
+/* boost random/linear_feedback_shift.hpp header file
*
* Copyright Jens Maurer 2002
+ * 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)
@@ -14,19 +15,22 @@
#ifndef BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
#define BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
-#include <iostream>
-#include <cassert>
+#include <iosfwd>
#include <stdexcept>
#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
-#include <boost/limits.hpp>
+#include <boost/integer/integer_mask.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/seed_impl.hpp>
namespace boost {
namespace random {
/**
- * Instatiation of @c linear_feedback_shift model a
+ * Instatiations of @c linear_feedback_shift model a
* \pseudo_random_number_generator. It was originally
* proposed in
*
@@ -35,125 +39,178 @@
* Tausworthe, R. C.(1965), Mathematics of Computation 19, 201-209.
* @endblockquote
*/
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-class linear_feedback_shift
+template<class UIntType, int w, int k, int q, int s>
+class linear_feedback_shift_engine
{
public:
- typedef UIntType result_type;
- // avoid the warning trouble when using (1<<w) on 32 bit machines
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, word_size = w);
- BOOST_STATIC_CONSTANT(int, exponent1 = k);
- BOOST_STATIC_CONSTANT(int, exponent2 = q);
- BOOST_STATIC_CONSTANT(int, step_size = s);
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return wordmask; }
-
- // MSVC 6 and possibly others crash when encountering complicated integral
- // constant expressions. Avoid the checks for now.
- // BOOST_STATIC_ASSERT(w > 0);
- // BOOST_STATIC_ASSERT(q > 0);
- // BOOST_STATIC_ASSERT(k < w);
- // BOOST_STATIC_ASSERT(0 < 2*q && 2*q < k);
- // BOOST_STATIC_ASSERT(0 < s && s <= k-q);
-
- explicit linear_feedback_shift(UIntType s0 = 341) : wordmask(0)
- {
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<UIntType>::is_integer);
- BOOST_STATIC_ASSERT(!std::numeric_limits<UIntType>::is_signed);
-#endif
-
- // avoid "left shift count >= with of type" warning
- for(int i = 0; i < w; ++i)
- wordmask |= (1u << i);
- seed(s0);
- }
-
- template<class It> linear_feedback_shift(It& first, It last) : wordmask(0)
- {
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<UIntType>::is_integer);
- BOOST_STATIC_ASSERT(!std::numeric_limits<UIntType>::is_signed);
-#endif
-
- // avoid "left shift count >= with of type" warning
- for(int i = 0; i < w; ++i)
- wordmask |= (1u << i);
- seed(first, last);
- }
-
- void seed(UIntType s0 = 341) {
- if(s0 < (1 << (w-k))) {
- s0 += 1 << (w-k);
- }
- value = s0;
- }
- template<class It> void seed(It& first, It last)
- {
- if(first == last)
- throw std::invalid_argument("linear_feedback_shift::seed");
- value = *first++;
- assert(value >= (1 << (w-k)));
- }
-
- result_type operator()()
- {
- const UIntType b = (((value << q) ^ value) & wordmask) >> (k-s);
- const UIntType mask = ( (~static_cast<UIntType>(0)) << (w-k) ) & wordmask;
- value = ((value & mask) << s) ^ b;
- return value;
- }
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, linear_feedback_shift x)
- { os << x.value; return os; }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, linear_feedback_shift& x)
- { is >> x.value; return is; }
-#endif
-
- friend bool operator==(linear_feedback_shift x, linear_feedback_shift y)
- { return x.value == y.value; }
- friend bool operator!=(linear_feedback_shift x, linear_feedback_shift y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(linear_feedback_shift rhs) const
- { return value == rhs.value; }
- bool operator!=(linear_feedback_shift rhs) const
- { return !(*this == rhs); }
-#endif
+ typedef UIntType result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(int, word_size = w);
+ BOOST_STATIC_CONSTANT(int, exponent1 = k);
+ BOOST_STATIC_CONSTANT(int, exponent2 = q);
+ BOOST_STATIC_CONSTANT(int, step_size = s);
+ BOOST_STATIC_CONSTANT(UIntType, default_seed = 341);
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return wordmask(); }
+
+ BOOST_STATIC_ASSERT(w > 0);
+ BOOST_STATIC_ASSERT(q > 0);
+ BOOST_STATIC_ASSERT(k < w);
+ BOOST_STATIC_ASSERT(0 < 2*q && 2*q < k);
+ BOOST_STATIC_ASSERT(0 < s && s <= k-q);
+
+ /** Constructs a @c linear_feedback_shift_engine, using the default seed. */
+ linear_feedback_shift_engine() { seed(); }
+
+ /** Constructs a @c linear_feedback_shift_engine, seeding it with s0. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift_engine,
+ UIntType, s0)
+ { seed(s0); }
+
+ /** Constructs a @c linear_feedback_shift_engine, seeding it with seq. */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ /**
+ * Constructs a @c linear_feedback_shift_engine, seeding it with
+ * values from the range [first, last).
+ */
+ template<class It> linear_feedback_shift_engine(It& first, It last)
+ { seed(first, last); }
+
+ /** Seeds a @c linear_feedback_shift_engine with the default seed. */
+ void seed() { seed(default_seed); }
+
+ /** Seeds a @c linear_feedback_shift_engine with @c s0. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_feedback_shift_engine,
+ UIntType, s0)
+ {
+ value = s0 & wordmask();
+ if(value < (1 << (w-k))) {
+ value += 1 << (w-k);
+ }
+ }
+
+ /**
+ * Seeds a @c linear_feedback_shift_engine with values
+ * produced by @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_feedback_shift_engine,
+ SeedSeq, seq)
+ { seed(detail::seed_one_int<UIntType, (UIntType(2) << (w - 1))>(seq)); }
+
+ /**
+ * Seeds a @c linear_feedback_shift_engine with values
+ * from the range [first, last).
+ */
+ template<class It> void seed(It& first, It last)
+ {
+ seed(detail::get_one_int<UIntType, (UIntType(2) << (w - 1))>(first, last));
+ }
+
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ const UIntType b = (((value << q) ^ value) & wordmask()) >> (k-s);
+ const UIntType mask = (wordmask() << (w-k)) & wordmask();
+ value = ((value & mask) << s) ^ b;
+ return value;
+ }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
+
+ /**
+ * Writes the textual representation of the generator to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, linear_feedback_shift_engine, x)
+ {
+ os << x.value;
+ return os;
+ }
+
+ /**
+ * Reads the textual representation of the generator from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, linear_feedback_shift_engine, x)
+ {
+ is >> x.value;
+ return is;
+ }
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(linear_feedback_shift_engine, x, y)
+ { return x.value == y.value; }
+
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of outputs.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(linear_feedback_shift_engine)
private:
- UIntType wordmask; // avoid "left shift count >= width of type" warnings
- UIntType value;
+ /// \cond show_private
+ static UIntType wordmask() { return boost::low_bits_mask_t<w>::sig_bits; }
+ /// \endcond
+ UIntType value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-const bool linear_feedback_shift<UIntType, w, k, q, s, val>::has_fixed_range;
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-const int linear_feedback_shift<UIntType, w, k, q, s, val>::word_size;
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-const int linear_feedback_shift<UIntType, w, k, q, s, val>::exponent1;
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-const int linear_feedback_shift<UIntType, w, k, q, s, val>::exponent2;
-template<class UIntType, int w, int k, int q, int s, UIntType val>
-const int linear_feedback_shift<UIntType, w, k, q, s, val>::step_size;
+template<class UIntType, int w, int k, int q, int s>
+const bool linear_feedback_shift_engine<UIntType, w, k, q, s>::has_fixed_range;
+template<class UIntType, int w, int k, int q, int s>
+const int linear_feedback_shift_engine<UIntType, w, k, q, s>::word_size;
+template<class UIntType, int w, int k, int q, int s>
+const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent1;
+template<class UIntType, int w, int k, int q, int s>
+const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent2;
+template<class UIntType, int w, int k, int q, int s>
+const int linear_feedback_shift_engine<UIntType, w, k, q, s>::step_size;
+template<class UIntType, int w, int k, int q, int s>
+const UIntType linear_feedback_shift_engine<UIntType, w, k, q, s>::default_seed;
#endif
+/// \cond show_deprecated
+
+/** Provided for backwards compatibility. */
+template<class UIntType, int w, int k, int q, int s, UIntType v = 0>
+class linear_feedback_shift :
+ public linear_feedback_shift_engine<UIntType, w, k, q, s>
+{
+ typedef linear_feedback_shift_engine<UIntType, w, k, q, s> base_type;
+public:
+ linear_feedback_shift() {}
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift,
+ SeedSeq, seq)
+ { seed(seq); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift,
+ UIntType, val)
+ { seed(val); }
+ template<class It>
+ linear_feedback_shift(It& first, It last) : base_type(first, last) {}
+};
+
+/// \endcond
+
} // namespace random
} // namespace boost
Modified: branches/release/boost/random/lognormal_distribution.hpp
==============================================================================
--- branches/release/boost/random/lognormal_distribution.hpp (original)
+++ branches/release/boost/random/lognormal_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/lognormal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,112 +19,236 @@
#include <boost/config/no_tr1/cmath.hpp> // std::exp, std::sqrt
#include <cassert>
-#include <iostream>
+#include <iosfwd>
+#include <istream>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
#include <boost/random/normal_distribution.hpp>
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std {
- using ::log;
- using ::sqrt;
-}
-#endif
-
namespace boost {
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-// Special gcc workaround: gcc 2.95.x ignores using-declarations
-// in template classes (confirmed by gcc author Martin v. Loewis)
- using std::sqrt;
- using std::exp;
-#endif
+namespace random {
/**
* Instantiations of class template lognormal_distribution model a
* \random_distribution. Such a distribution produces random numbers
- * with \f$p(x) = \frac{1}{x \sigma_N \sqrt{2\pi}} e^{\frac{-\left(\log(x)-\mu_N\right)^2}{2\sigma_N^2}}\f$
- * for x > 0, where \f$\mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
- * \f$\sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$.
+ * with \f$\displaystyle p(x) = \frac{1}{x s \sqrt{2\pi}} e^{\frac{-\left(\log(x)-m\right)^2}{2s^2}}\f$
+ * for x > 0.
+ *
+ * @xmlwarning
+ * This distribution has been updated to match the C++ standard.
+ * Its behavior has changed from the original
+ * boost::lognormal_distribution. A backwards compatible
+ * version is provided in namespace boost.
+ * @endxmlwarning
*/
template<class RealType = double>
class lognormal_distribution
{
public:
- typedef typename normal_distribution<RealType>::input_type input_type;
- typedef RealType result_type;
+ typedef typename normal_distribution<RealType>::input_type input_type;
+ typedef RealType result_type;
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
-
- /**
- * Constructs a lognormal_distribution. @c mean and @c sigma are the
- * mean and standard deviation of the lognormal distribution.
- */
- explicit lognormal_distribution(result_type mean_arg = result_type(1),
- result_type sigma_arg = result_type(1))
- : _mean(mean_arg), _sigma(sigma_arg)
- {
- assert(_mean > result_type(0));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- RealType mean() const { return _mean; }
- RealType sigma() const { return _sigma; }
- void reset() { _normal.reset(); }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp;
-#endif
- return exp(_normal(eng) * _nsigma + _nmean);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const lognormal_distribution& ld)
- {
- os << ld._normal << " " << ld._mean << " " << ld._sigma;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, lognormal_distribution& ld)
- {
- is >> std::ws >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
- ld.init();
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef lognormal_distribution distribution_type;
+
+ /** Constructs the parameters of a lognormal_distribution. */
+ explicit param_type(RealType m_arg = RealType(0.0),
+ RealType s_arg = RealType(1.0))
+ : _m(m_arg), _s(s_arg) {}
+
+ /** Returns the "m" parameter of the distribution. */
+ RealType m() const { return _m; }
+
+ /** Returns the "s" parameter of the distribution. */
+ RealType s() const { return _s; }
+
+ /** Writes the parameters to a std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._m << " " << parm._s;
+ return os;
+ }
+
+ /** Reads the parameters from a std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._m >> std::ws >> parm._s;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._m == rhs._m && lhs._s == rhs._s; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _m;
+ RealType _s;
+ };
+
+ /**
+ * Constructs a lognormal_distribution. @c m and @c s are the
+ * parameters of the distribution.
+ */
+ explicit lognormal_distribution(RealType m_arg = RealType(0.0),
+ RealType s_arg = RealType(1.0))
+ : _normal(m_arg, s_arg) {}
+
+ /**
+ * Constructs a lognormal_distribution from its parameters.
+ */
+ explicit lognormal_distribution(const param_type& parm)
+ : _normal(parm.m(), parm.s()) {}
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the m parameter of the distribution. */
+ RealType m() const { return _normal.mean(); }
+ /** Returns the s parameter of the distribution. */
+ RealType s() const { return _normal.sigma(); }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return RealType(0); }
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return (std::numeric_limits<RealType>::infinity)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(m(), s()); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ typedef normal_distribution<RealType> normal_type;
+ typename normal_type::param_type normal_param(parm.m(), parm.s());
+ _normal.param(normal_param);
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _normal.reset(); }
+
+ /**
+ * Returns a random variate distributed according to the
+ * lognormal distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
+ using std::exp;
+ return exp(_normal(eng));
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * lognormal distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm)
+ { return lognormal_distribution(parm)(eng); }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
+ {
+ os << ld._normal;
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
+ {
+ is >> ld._normal;
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lognormal_distribution, lhs, rhs)
+ { return lhs._normal == rhs._normal; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lognormal_distribution)
private:
+ normal_distribution<result_type> _normal;
+};
- /// \cond hide_private_members
- void init()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp; using std::log; using std::sqrt;
-#endif
- _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
- _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
- }
- /// \endcond
-
- RealType _mean, _sigma;
- RealType _nmean, _nsigma;
- normal_distribution<result_type> _normal;
+} // namespace random
+
+/// \cond show_deprecated
+
+/**
+ * Provided for backwards compatibility. This class is
+ * deprecated. It provides the old behavior of lognormal_distribution with
+ * \f$\displaystyle p(x) = \frac{1}{x \sigma_N \sqrt{2\pi}} e^{\frac{-\left(\log(x)-\mu_N\right)^2}{2\sigma_N^2}}\f$
+ * for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
+ * \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$.
+ */
+template<class RealType = double>
+class lognormal_distribution
+{
+public:
+ typedef typename normal_distribution<RealType>::input_type input_type;
+ typedef RealType result_type;
+
+ lognormal_distribution(RealType mean_arg = RealType(1.0),
+ RealType sigma_arg = RealType(1.0))
+ : _mean(mean_arg), _sigma(sigma_arg)
+ {
+ init();
+ }
+ RealType mean() const { return _mean; }
+ RealType sigma() const { return _sigma; }
+ void reset() { _normal.reset(); }
+ template<class Engine>
+ RealType operator()(Engine& eng)
+ {
+ using std::exp;
+ return exp(_normal(eng) * _nsigma + _nmean);
+ }
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
+ {
+ os << ld._normal << " " << ld._mean << " " << ld._sigma;
+ return os;
+ }
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
+ {
+ is >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
+ ld.init();
+ return is;
+ }
+private:
+ /// \cond show_private
+ void init()
+ {
+ using std::log;
+ using std::sqrt;
+ _nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
+ _nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
+ }
+ RealType _mean;
+ RealType _sigma;
+ RealType _nmean;
+ RealType _nsigma;
+ normal_distribution<RealType> _normal;
+ /// \endcond
};
+/// \endcond
+
} // namespace boost
#endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
Modified: branches/release/boost/random/mersenne_twister.hpp
==============================================================================
--- branches/release/boost/random/mersenne_twister.hpp (original)
+++ branches/release/boost/random/mersenne_twister.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/mersenne_twister.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * 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)
@@ -16,25 +17,23 @@
#ifndef BOOST_RANDOM_MERSENNE_TWISTER_HPP
#define BOOST_RANDOM_MERSENNE_TWISTER_HPP
-#include <iostream>
-#include <algorithm> // std::copy
+#include <iosfwd>
+#include <istream>
#include <stdexcept>
#include <boost/config.hpp>
-#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/integer_traits.hpp>
#include <boost/cstdint.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/detail/workaround.hpp>
+#include <boost/integer/integer_mask.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/ptr_helper.hpp>
#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/seed_impl.hpp>
+#include <boost/random/detail/generator_seed_seq.hpp>
namespace boost {
namespace random {
/**
- * Instantiations of class template mersenne_twister model a
+ * Instantiations of class template mersenne_twister_engine model a
* \pseudo_random_number_generator. It uses the algorithm described in
*
* @blockquote
@@ -61,277 +60,406 @@
* its state array. For example, \mt11213b requires about 1408 bytes and
* \mt19937 requires about 2496 bytes.
*/
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-class mersenne_twister
+template<class UIntType,
+ std::size_t w, std::size_t n, std::size_t m, std::size_t r,
+ UIntType a, std::size_t u, UIntType d, std::size_t s,
+ UIntType b, std::size_t t,
+ UIntType c, std::size_t l, UIntType f>
+class mersenne_twister_engine
{
public:
- typedef UIntType result_type;
- BOOST_STATIC_CONSTANT(int, word_size = w);
- BOOST_STATIC_CONSTANT(int, state_size = n);
- BOOST_STATIC_CONSTANT(int, shift_size = m);
- BOOST_STATIC_CONSTANT(int, mask_bits = r);
- BOOST_STATIC_CONSTANT(UIntType, parameter_a = a);
- BOOST_STATIC_CONSTANT(int, output_u = u);
- BOOST_STATIC_CONSTANT(int, output_s = s);
- BOOST_STATIC_CONSTANT(UIntType, output_b = b);
- BOOST_STATIC_CONSTANT(int, output_t = t);
- BOOST_STATIC_CONSTANT(UIntType, output_c = c);
- BOOST_STATIC_CONSTANT(int, output_l = l);
-
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-
- /**
- * Constructs a @c mersenne_twister and calls @c seed().
- */
- mersenne_twister() { seed(); }
-
- /**
- * Constructs a @c mersenne_twister and calls @c seed(value).
- */
- BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(mersenne_twister, UIntType, value)
- { seed(value); }
- template<class It> mersenne_twister(It& first, It last) { seed(first,last); }
-
- /**
- * Constructs a mersenne_twister and calls @c seed(gen).
- *
- * @xmlnote
- * The copy constructor will always be preferred over
- * the templated constructor.
- * @endxmlnote
- */
- BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(mersenne_twister, Generator, gen)
- { seed(gen); }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /** Calls @c seed(result_type(5489)). */
- void seed() { seed(UIntType(5489)); }
-
- /**
- * Sets the state x(0) to v mod 2w. Then, iteratively,
- * sets x(i) to (i + 1812433253 * (x(i-1) xor (x(i-1) rshift w-2))) mod 2<sup>w</sup>
- * for i = 1 .. n-1. x(n) is the first value to be returned by operator().
- */
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister, UIntType, value)
- {
- // New seeding algorithm from
- // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
- // In the previous versions, MSBs of the seed affected only MSBs of the
- // state x[].
- const UIntType mask = ~0u;
- x[0] = value & mask;
- for (i = 1; i < n; i++) {
- // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
- x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
- }
- }
-
- /**
- * Sets the state of this mersenne_twister to the values
- * returned by n invocations of gen.
- *
- * Complexity: Exactly n invocations of gen.
- */
- BOOST_RANDOM_DETAIL_GENERATOR_SEED(mersenne_twister, Generator, gen)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_signed);
-#endif
- // I could have used std::generate_n, but it takes "gen" by value
- for(int j = 0; j < n; j++)
- x[j] = gen();
- i = n;
- }
-
- template<class It>
- void seed(It& first, It last)
- {
- int j;
- for(j = 0; j < n && first != last; ++j, ++first)
- x[j] = *first;
- i = n;
- if(first == last && j < n)
- throw std::invalid_argument("mersenne_twister::seed");
- }
+ typedef UIntType result_type;
+ BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
+ BOOST_STATIC_CONSTANT(std::size_t, state_size = n);
+ BOOST_STATIC_CONSTANT(std::size_t, shift_size = m);
+ BOOST_STATIC_CONSTANT(std::size_t, mask_bits = r);
+ BOOST_STATIC_CONSTANT(UIntType, xor_mask = a);
+ BOOST_STATIC_CONSTANT(std::size_t, tempering_u = u);
+ BOOST_STATIC_CONSTANT(UIntType, tempering_d = d);
+ BOOST_STATIC_CONSTANT(std::size_t, tempering_s = s);
+ BOOST_STATIC_CONSTANT(UIntType, tempering_b = b);
+ BOOST_STATIC_CONSTANT(std::size_t, tempering_t = t);
+ BOOST_STATIC_CONSTANT(UIntType, tempering_c = c);
+ BOOST_STATIC_CONSTANT(std::size_t, tempering_l = l);
+ BOOST_STATIC_CONSTANT(UIntType, initialization_multiplier = f);
+ BOOST_STATIC_CONSTANT(UIntType, default_seed = 5489u);
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
- {
- // avoid "left shift count >= with of type" warning
- result_type res = 0;
- for(int j = 0; j < w; ++j)
- res |= (1u << j);
- return res;
- }
+ // backwards compatibility
+ BOOST_STATIC_CONSTANT(UIntType, parameter_a = a);
+ BOOST_STATIC_CONSTANT(std::size_t, output_u = u);
+ BOOST_STATIC_CONSTANT(std::size_t, output_s = s);
+ BOOST_STATIC_CONSTANT(UIntType, output_b = b);
+ BOOST_STATIC_CONSTANT(std::size_t, output_t = t);
+ BOOST_STATIC_CONSTANT(UIntType, output_c = c);
+ BOOST_STATIC_CONSTANT(std::size_t, output_l = l);
+
+ // old Boost.Random concept requirements
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- result_type operator()();
- static bool validation(result_type v) { return val == v; }
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
+ /**
+ * Constructs a @c mersenne_twister_engine and calls @c seed().
+ */
+ mersenne_twister_engine() { seed(); }
+
+ /**
+ * Constructs a @c mersenne_twister_engine and calls @c seed(value).
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(mersenne_twister_engine,
+ UIntType, value)
+ { seed(value); }
+ template<class It> mersenne_twister_engine(It& first, It last)
+ { seed(first,last); }
+
+ /**
+ * Constructs a mersenne_twister_engine and calls @c seed(gen).
+ *
+ * @xmlnote
+ * The copy constructor will always be preferred over
+ * the templated constructor.
+ * @endxmlnote
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(mersenne_twister_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Calls @c seed(default_seed). */
+ void seed() { seed(default_seed); }
+
+ /**
+ * Sets the state x(0) to v mod 2w. Then, iteratively,
+ * sets x(i) to
+ * (i + f * (x(i-1) xor (x(i-1) rshift w-2))) mod 2<sup>w</sup>
+ * for i = 1 .. n-1. x(n) is the first value to be returned by operator().
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister_engine, UIntType, value)
+ {
+ // New seeding algorithm from
+ // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
+ // In the previous versions, MSBs of the seed affected only MSBs of the
+ // state x[].
+ const UIntType mask = (max)();
+ x[0] = value & mask;
+ for (i = 1; i < n; i++) {
+ // See Knuth "The Art of Computer Programming"
+ // Vol. 2, 3rd ed., page 106
+ x[i] = (f * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
+ }
+ }
+
+ /**
+ * Seeds a mersenne_twister_engine using values produced by seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(mersenne_twister_engine, SeeqSeq, seq)
+ {
+ detail::seed_array_int<w>(seq, x);
+ i = n;
+
+ // fix up the state if it's all zeroes.
+ if((x[0] & (~static_cast<UIntType>(0) << r)) == 0) {
+ for(std::size_t j = 1; i < n; ++j) {
+ if(x[j] != 0) return;
+ }
+ x[0] = static_cast<UIntType>(1) << (w-1);
+ }
+ }
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const mersenne_twister& mt)
- {
- for(int j = 0; j < mt.state_size; ++j)
- os << mt.compute(j) << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, mersenne_twister& mt)
- {
- for(int j = 0; j < mt.state_size; ++j)
- is >> mt.x[j] >> std::ws;
- // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template
- // value parameter "n" available from the class template scope, so use
- // the static constant with the same value
- mt.i = mt.state_size;
- return is;
- }
-#endif
+ /** Sets the state of the generator using values from an iterator range. */
+ template<class It>
+ void seed(It& first, It last)
+ {
+ detail::fill_array_int<w>(first, last, x);
+ i = n;
+
+ // fix up the state if it's all zeroes.
+ if((x[0] & (~static_cast<UIntType>(0) << r)) == 0) {
+ for(std::size_t j = 1; i < n; ++j) {
+ if(x[j] != 0) return;
+ }
+ x[0] = static_cast<UIntType>(1) << (w-1);
+ }
+ }
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return 0; }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return boost::low_bits_mask_t<w>::sig_bits; }
+
+ /** Produces the next value of the generator. */
+ result_type operator()();
- friend bool operator==(const mersenne_twister& x, const mersenne_twister& y)
- {
- for(int j = 0; j < state_size; ++j)
- if(x.compute(j) != y.compute(j))
- return false;
- return true;
- }
-
- friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const mersenne_twister& rhs) const
- {
- for(int j = 0; j < state_size; ++j)
- if(compute(j) != rhs.compute(j))
- return false;
- return true;
- }
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /**
+ * Advances the state of the generator by @c z steps. Equivalent to
+ *
+ * @code
+ * for(unsigned long long i = 0; i < z; ++i) {
+ * gen();
+ * }
+ * @endcode
+ */
+ void discard(boost::uintmax_t z)
+ {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
+ (*this)();
+ }
+ }
- bool operator!=(const mersenne_twister& rhs) const
- { return !(*this == rhs); }
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes a mersenne_twister_engine to a @c std::ostream */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const mersenne_twister_engine& mt)
+ {
+ mt.print(os);
+ return os;
+ }
+
+ /** Reads a mersenne_twister_engine from a @c std::istream */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is,
+ mersenne_twister_engine& mt)
+ {
+ for(std::size_t j = 0; j < mt.state_size; ++j)
+ is >> mt.x[j] >> std::ws;
+ // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template
+ // value parameter "n" available from the class template scope, so use
+ // the static constant with the same value
+ mt.i = mt.state_size;
+ return is;
+ }
#endif
+ /**
+ * Returns true if the two generators are in the same state,
+ * and will thus produce identical sequences.
+ */
+ friend bool operator==(const mersenne_twister_engine& x,
+ const mersenne_twister_engine& y)
+ {
+ if(x.i < y.i) return x.equal_imp(y);
+ else return y.equal_imp(x);
+ }
+
+ /**
+ * Returns true if the two generators are in different states.
+ */
+ friend bool operator!=(const mersenne_twister_engine& x,
+ const mersenne_twister_engine& y)
+ { return !(x == y); }
+
private:
- /// \cond hide_private_members
- // returns x(i-n+index), where index is in 0..n-1
- UIntType compute(unsigned int index) const
- {
- // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
- return x[ (i + n + index) % (2*n) ];
- }
- void twist(int block);
- /// \endcond
-
- // state representation: next output is o(x(i))
- // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
- // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
- // The goal is to always have x(i-n) ... x(i-1) available for
- // operator== and save/restore.
+ /// \cond show_private
+
+ void twist();
+
+ /**
+ * Does the work of operator==. This is in a member function
+ * for portability. Some compilers, such as msvc 7.1 and
+ * Sun CC 5.10 can't access template parameters or static
+ * members of the class from inline friend functions.
+ *
+ * requires i <= other.i
+ */
+ bool equal_imp(const mersenne_twister_engine& other) const
+ {
+ UIntType back[n];
+ std::size_t offset = other.i - i;
+ for(std::size_t j = 0; j + offset < n; ++j)
+ if(x[j] != other.x[j+offset])
+ return false;
+ rewind(&back[n-1], offset);
+ for(std::size_t j = 0; j < offset; ++j)
+ if(back[j + n - offset] != other.x[j])
+ return false;
+ return true;
+ }
+
+ /**
+ * Does the work of operator<<. This is in a member function
+ * for portability.
+ */
+ template<class CharT, class Traits>
+ void print(std::basic_ostream<CharT, Traits>& os) const
+ {
+ UIntType data[n];
+ for(std::size_t j = 0; j < i; ++j) {
+ data[j + n - i] = x[j];
+ }
+ if(i != n) {
+ rewind(&data[n - i - 1], n - i);
+ }
+ os << data[0];
+ for(std::size_t j = 1; j < n; ++j) {
+ os << ' ' << data[j];
+ }
+ }
+
+ /**
+ * Copies z elements of the state preceding x[0] into
+ * the array whose last element is last.
+ */
+ void rewind(UIntType* last, std::size_t z) const
+ {
+ const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
+ const UIntType lower_mask = ~upper_mask;
+ UIntType y0 = x[m-1] ^ x[n-1];
+ if(y0 & (static_cast<UIntType>(1) << (w-1))) {
+ y0 = ((y0 ^ a) << 1) | 1;
+ } else {
+ y0 = y0 << 1;
+ }
+ for(std::size_t sz = 0; sz < z; ++sz) {
+ UIntType y1 =
+ rewind_find(last, sz, m-1) ^ rewind_find(last, sz, n-1);
+ if(y1 & (static_cast<UIntType>(1) << (w-1))) {
+ y1 = ((y1 ^ a) << 1) | 1;
+ } else {
+ y1 = y1 << 1;
+ }
+ *(last - sz) = (y0 & upper_mask) | (y1 & lower_mask);
+ y0 = y1;
+ }
+ }
+
+ /**
+ * Given a pointer to the last element of the rewind array,
+ * and the current size of the rewind array, finds an element
+ * relative to the next available slot in the rewind array.
+ */
+ UIntType
+ rewind_find(UIntType* last, std::size_t size, std::size_t j) const
+ {
+ std::size_t index = (j + n - size + n - 1) % n;
+ if(index < n - size) {
+ return x[index];
+ } else {
+ return *(last - (n - 1 - index));
+ }
+ }
+
+ /// \endcond
- UIntType x[2*n];
- int i;
+ // state representation: next output is o(x(i))
+ // x[0] ... x[k] x[k+1] ... x[n-1] represents
+ // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1)
+
+ UIntType x[n];
+ std::size_t i;
};
+/// \cond show_private
+
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const bool mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
+#define BOOST_RANDOM_MT_DEFINE_CONSTANT(type, name) \
+template<class UIntType, std::size_t w, std::size_t n, std::size_t m, \
+ std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, \
+ UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> \
+const type mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::name
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, word_size);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, state_size);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, shift_size);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, mask_bits);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, xor_mask);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_u);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_d);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_s);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_b);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_t);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_c);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_l);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, initialization_multiplier);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, default_seed);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, parameter_a);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_u );
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_s);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, output_b);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_t);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, output_c);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_l);
+BOOST_RANDOM_MT_DEFINE_CONSTANT(bool, has_fixed_range);
+#undef BOOST_RANDOM_MT_DEFINE_CONSTANT
#endif
-/// \cond hide_private_members
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-void mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
+template<class UIntType,
+ std::size_t w, std::size_t n, std::size_t m, std::size_t r,
+ UIntType a, std::size_t u, UIntType d, std::size_t s,
+ UIntType b, std::size_t t,
+ UIntType c, std::size_t l, UIntType f>
+void
+mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::twist()
{
- const UIntType upper_mask = (~0u) << r;
- const UIntType lower_mask = ~upper_mask;
+ const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
+ const UIntType lower_mask = ~upper_mask;
+
+ const std::size_t unroll_factor = 6;
+ const std::size_t unroll_extra1 = (n-m) % unroll_factor;
+ const std::size_t unroll_extra2 = (m-1) % unroll_factor;
- if(block == 0) {
- for(int j = n; j < 2*n; j++) {
- UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
- x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
- }
- } else if (block == 1) {
// split loop to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
- for(int j = 0; j < n-m; j++) {
- UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
- x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
- }
+ for(std::size_t j = 0; j < n-m-unroll_extra1; j++) {
+ UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
+ x[j] = x[j+m] ^ (y >> 1) ^ ((x[j+1]&1) * a);
+ }
}
-
- for(int j = n-m; j < n-1; j++) {
- UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
- x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
+ {
+ for(std::size_t j = n-m-unroll_extra1; j < n-m; j++) {
+ UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
+ x[j] = x[j+m] ^ (y >> 1) ^ ((x[j+1]&1) * a);
+ }
+ }
+ {
+ for(std::size_t j = n-m; j < n-1-unroll_extra2; j++) {
+ UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
+ x[j] = x[j-(n-m)] ^ (y >> 1) ^ ((x[j+1]&1) * a);
+ }
+ }
+ {
+ for(std::size_t j = n-1-unroll_extra2; j < n-1; j++) {
+ UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
+ x[j] = x[j-(n-m)] ^ (y >> 1) ^ ((x[j+1]&1) * a);
+ }
}
// last iteration
- UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
- x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
+ UIntType y = (x[n-1] & upper_mask) | (x[0] & lower_mask);
+ x[n-1] = x[m-1] ^ (y >> 1) ^ ((x[0]&1) * a);
i = 0;
- }
}
/// \endcond
-template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
- int s, UIntType b, int t, UIntType c, int l, UIntType val>
-inline typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
-mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
+template<class UIntType,
+ std::size_t w, std::size_t n, std::size_t m, std::size_t r,
+ UIntType a, std::size_t u, UIntType d, std::size_t s,
+ UIntType b, std::size_t t,
+ UIntType c, std::size_t l, UIntType f>
+inline typename
+mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::result_type
+mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::operator()()
{
- if(i == n)
- twist(0);
- else if(i >= 2*n)
- twist(1);
- // Step 4
- UIntType z = x[i];
- ++i;
- z ^= (z >> u);
- z ^= ((z << s) & b);
- z ^= ((z << t) & c);
- z ^= (z >> l);
- return z;
+ if(i == n)
+ twist();
+ // Step 4
+ UIntType z = x[i];
+ ++i;
+ z ^= ((z >> u) & d);
+ z ^= ((z << s) & b);
+ z ^= ((z << t) & c);
+ z ^= (z >> l);
+ return z;
}
-} // namespace random
-
/**
* The specializations \mt11213b and \mt19937 are from
*
@@ -343,8 +471,8 @@
* Generation, Vol. 8, No. 1, January 1998, pp. 3-30.
* @endblockquote
*/
-typedef random::mersenne_twister<uint32_t,32,351,175,19,0xccab8ee7,11,
- 7,0x31b6ab00,15,0xffe50000,17, 0xa37d3c92> mt11213b;
+typedef mersenne_twister_engine<uint32_t,32,351,175,19,0xccab8ee7,
+ 11,0xffffffff,7,0x31b6ab00,15,0xffe50000,17,1812433253> mt11213b;
/**
* The specializations \mt11213b and \mt19937 are from
@@ -357,11 +485,61 @@
* Generation, Vol. 8, No. 1, January 1998, pp. 3-30.
* @endblockquote
*/
-typedef random::mersenne_twister<uint32_t,32,624,397,31,0x9908b0df,11,
- 7,0x9d2c5680,15,0xefc60000,18, 3346425566U> mt19937;
+typedef mersenne_twister_engine<uint32_t,32,624,397,31,0x9908b0df,
+ 11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937;
+
+#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+typedef mersenne_twister_engine<uint64_t,64,312,156,31,
+ UINT64_C(0xb5026f5aa96619e9),29,UINT64_C(0x5555555555555555),17,
+ UINT64_C(0x71d67fffeda60000),37,UINT64_C(0xfff7eee000000000),43,
+ UINT64_C(6364136223846793005)> mt19937_64;
+#endif
+
+/// \cond show_deprecated
+
+template<class UIntType,
+ int w, int n, int m, int r,
+ UIntType a, int u, std::size_t s,
+ UIntType b, int t,
+ UIntType c, int l, UIntType v>
+class mersenne_twister :
+ public mersenne_twister_engine<UIntType,
+ w, n, m, r, a, u, ~(UIntType)0, s, b, t, c, l, 1812433253>
+{
+ typedef mersenne_twister_engine<UIntType,
+ w, n, m, r, a, u, ~(UIntType)0, s, b, t, c, l, 1812433253> base_type;
+public:
+ mersenne_twister() {}
+ BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(mersenne_twister, Gen, gen)
+ { seed(gen); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(mersenne_twister, UIntType, val)
+ { seed(val); }
+ template<class It>
+ mersenne_twister(It& first, It last) : base_type(first, last) {}
+ void seed() { base_type::seed(); }
+ BOOST_RANDOM_DETAIL_GENERATOR_SEED(mersenne_twister, Gen, gen)
+ {
+ detail::generator_seed_seq<Gen> seq(gen);
+ base_type::seed(seq);
+ }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister, UIntType, val)
+ { base_type::seed(val); }
+ template<class It>
+ void seed(It& first, It last) { base_type::seed(first, last); }
+};
+
+/// \endcond
+
+} // namespace random
+
+using random::mt11213b;
+using random::mt19937;
+using random::mt19937_64;
} // namespace boost
+BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt11213b)
BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937)
+BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937_64)
#endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP
Copied: branches/release/boost/random/negative_binomial_distribution.hpp (from r65157, /trunk/boost/random/negative_binomial_distribution.hpp)
==============================================================================
--- /trunk/boost/random/negative_binomial_distribution.hpp (original)
+++ branches/release/boost/random/negative_binomial_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,8 +10,8 @@
* $Id$
*/
-#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
-#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
+#ifndef BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
+#define BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#include <iosfwd>
@@ -196,7 +196,7 @@
private:
- /// @cond
+ /// @cond \show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
Modified: branches/release/boost/random/normal_distribution.hpp
==============================================================================
--- branches/release/boost/random/normal_distribution.hpp (original)
+++ branches/release/boost/random/normal_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/normal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,115 +18,206 @@
#define BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
-#include <iostream>
+#include <istream>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/uniform_01.hpp>
namespace boost {
+namespace random {
+
+// deterministic Box-Muller method, uses trigonometric functions
/**
* Instantiations of class template normal_distribution model a
* \random_distribution. Such a distribution produces random numbers
* @c x distributed with probability density function
- * \f$p(x) = \frac{1}{\sqrt{2\pi\sigma}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}\f$,
+ * \f$\displaystyle p(x) =
+ * \frac{1}{\sqrt{2\pi\sigma}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
+ * \f$,
* where mean and sigma are the parameters of the distribution.
*/
-// deterministic Box-Muller method, uses trigonometric functions
template<class RealType = double>
class normal_distribution
{
public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
+
+ class param_type {
+ public:
+ typedef normal_distribution distribution_type;
+
+ /**
+ * Constructs a @c param_type with a given mean and
+ * standard deviation.
+ *
+ * Requires: sigma >= 0
+ */
+ explicit param_type(RealType mean_arg = RealType(0.0),
+ RealType sigma_arg = RealType(1.0))
+ : _mean(mean_arg),
+ _sigma(sigma_arg)
+ {}
+
+ /** Returns the mean of the distribution. */
+ RealType mean() const { return _mean; }
+
+ /** Returns the standand deviation of the distribution. */
+ RealType sigma() const { return _sigma; }
+
+ /** Writes a @c param_type to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ { os << parm._mean << " " << parm._sigma ; return os; }
+
+ /** Reads a @c param_type from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ { is >> parm._mean >> std::ws >> parm._sigma; return is; }
+
+ /** Returns true if the two sets of parameters are the same. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
+
+ /** Returns true if the two sets of parameters are the different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _mean;
+ RealType _sigma;
+ };
+
+ /**
+ * Constructs a @c normal_distribution object. @c mean and @c sigma are
+ * the parameters for the distribution.
+ *
+ * Requires: sigma >= 0
+ */
+ explicit normal_distribution(const RealType& mean_arg = RealType(0.0),
+ const RealType& sigma_arg = RealType(1.0))
+ : _mean(mean_arg), _sigma(sigma_arg),
+ _r1(0), _r2(0), _cached_rho(0), _valid(false)
+ {
+ BOOST_ASSERT(_sigma >= RealType(0));
+ }
+
+ /**
+ * Constructs a @c normal_distribution object from its parameters.
+ */
+ explicit normal_distribution(const param_type& parm)
+ : _mean(parm.mean()), _sigma(parm.sigma()),
+ _r1(0), _r2(0), _cached_rho(0), _valid(false)
+ {}
+
+ /** Returns the mean of the distribution. */
+ RealType mean() const { return _mean; }
+ /** Returns the standard deviation of the distribution. */
+ RealType sigma() const { return _sigma; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return -std::numeric_limits<RealType>::infinity(); }
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ { return std::numeric_limits<RealType>::infinity(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_mean, _sigma); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _mean = parm.mean();
+ _sigma = parm.sigma();
+ _valid = false;
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _valid = false; }
+
+ /** Returns a normal variate. */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
+ using std::sqrt;
+ using std::log;
+ using std::sin;
+ using std::cos;
+
+ if(!_valid) {
+ _r1 = boost::uniform_01<RealType>()(eng);
+ _r2 = boost::uniform_01<RealType>()(eng);
+ _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2));
+ _valid = true;
+ } else {
+ _valid = false;
+ }
+ // Can we have a boost::mathconst please?
+ const result_type pi = result_type(3.14159265358979323846);
+
+ return _cached_rho * (_valid ?
+ cos(result_type(2)*pi*_r1) :
+ sin(result_type(2)*pi*_r1))
+ * _sigma + _mean;
+ }
+
+ /** Returns a normal variate with parameters specified by @c param. */
+ template<class URNG>
+ result_type operator()(URNG& urng, const param_type& parm)
+ {
+ return normal_distribution(parm)(urng);
+ }
+
+ /** Writes a @c normal_distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution, nd)
+ {
+ os << nd._mean << " " << nd._sigma << " "
+ << nd._valid << " " << nd._cached_rho << " " << nd._r1;
+ return os;
+ }
+
+ /** Reads a @c normal_distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution, nd)
+ {
+ is >> std::ws >> nd._mean >> std::ws >> nd._sigma
+ >> std::ws >> nd._valid >> std::ws >> nd._cached_rho
+ >> std::ws >> nd._r1;
+ return is;
+ }
+
+ /**
+ * Returns true if the two instances of @c normal_distribution will
+ * return identical sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution, lhs, rhs)
+ {
+ return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma
+ && lhs._valid == rhs._valid
+ && (!lhs._valid || (lhs._r1 == rhs._r1 && lhs._r2 == rhs._r2));
+ }
+
+ /**
+ * Returns true if the two instances of @c normal_distribution will
+ * return different sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(normal_distribution)
-#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
-
- /**
- * Constructs a normal_distribution object. @c mean and @c sigma are
- * the parameters for the distribution.
- *
- * Requires: sigma > 0
- */
- explicit normal_distribution(const result_type& mean_arg = result_type(0),
- const result_type& sigma_arg = result_type(1))
- : _mean(mean_arg), _sigma(sigma_arg), _valid(false)
- {
- assert(_sigma >= result_type(0));
- }
-
- // compiler-generated copy constructor is NOT fine, need to purge cache
- normal_distribution(const normal_distribution& other)
- : _mean(other._mean), _sigma(other._sigma), _valid(false)
- {
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: The "mean" parameter of the distribution.
- */
- RealType mean() const { return _mean; }
- /**
- * Returns: The "sigma" parameter of the distribution.
- */
- RealType sigma() const { return _sigma; }
-
- void reset() { _valid = false; }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::sqrt; using std::log; using std::sin; using std::cos;
-#endif
- if(!_valid) {
- _r1 = eng();
- _r2 = eng();
- _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2));
- _valid = true;
- } else {
- _valid = false;
- }
- // Can we have a boost::mathconst please?
- const result_type pi = result_type(3.14159265358979323846);
-
- return _cached_rho * (_valid ?
- cos(result_type(2)*pi*_r1) :
- sin(result_type(2)*pi*_r1))
- * _sigma + _mean;
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const normal_distribution& nd)
- {
- os << nd._mean << " " << nd._sigma << " "
- << nd._valid << " " << nd._cached_rho << " " << nd._r1;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, normal_distribution& nd)
- {
- is >> std::ws >> nd._mean >> std::ws >> nd._sigma
- >> std::ws >> nd._valid >> std::ws >> nd._cached_rho
- >> std::ws >> nd._r1;
- return is;
- }
-#endif
private:
- result_type _mean, _sigma;
- result_type _r1, _r2, _cached_rho;
- bool _valid;
+ RealType _mean, _sigma;
+ RealType _r1, _r2, _cached_rho;
+ bool _valid;
+
};
+} // namespace random
+
+using random::normal_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
Copied: branches/release/boost/random/piecewise_constant_distribution.hpp (from r67740, /trunk/boost/random/piecewise_constant_distribution.hpp)
==============================================================================
--- /trunk/boost/random/piecewise_constant_distribution.hpp (original)
+++ branches/release/boost/random/piecewise_constant_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,8 +14,8 @@
#define BOOST_RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_HPP_INCLUDED
#include <vector>
-#include <cassert>
#include <numeric>
+#include <boost/assert.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/detail/config.hpp>
@@ -38,11 +38,14 @@
template<class RealType = double, class WeightType = double>
class piecewise_constant_distribution {
public:
- typedef RealType input_type;
+ typedef std::size_t input_type;
typedef RealType result_type;
class param_type {
public:
+
+ typedef piecewise_constant_distribution distribution_type;
+
/**
* Constructs a @c param_type object, representing a distribution
* that produces values uniformly distributed in the range [0, 1).
@@ -73,6 +76,7 @@
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
+ _weights.push_back(WeightType(1));
} else {
_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
@@ -93,14 +97,15 @@
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
- template<class F>
- param_type(const std::initializer_list<RealType>& il, F f)
- : _intervals(il)
+ template<class T, class F>
+ param_type(const std::initializer_list<T>& il, F f)
+ : _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
+ _weights.push_back(WeightType(1));
} else {
_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
@@ -129,6 +134,7 @@
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
+ _weights.push_back(WeightType(1));
}
}
@@ -144,7 +150,7 @@
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
- assert(delta > 0);
+ BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_weights.push_back(f(xmin + k*delta + delta/2));
_intervals.push_back(xmin + k*delta);
@@ -159,11 +165,11 @@
* Returns a vector containing the probability densities
* over all the intervals of the distribution.
*/
- std::vector<WeightType> densities() const
+ std::vector<RealType> densities() const
{
- WeightType sum = std::accumulate(_weights.begin(), _weights.end(),
- static_cast<WeightType>(0));
- std::vector<WeightType> result;
+ RealType sum = std::accumulate(_weights.begin(), _weights.end(),
+ static_cast<RealType>(0));
+ std::vector<RealType> result;
result.reserve(_weights.size());
for(std::size_t i = 0; i < _weights.size(); ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
@@ -205,19 +211,15 @@
private:
- /// @cond
-
friend class piecewise_constant_distribution;
std::vector<RealType> _intervals;
std::vector<WeightType> _weights;
-
- /// @endcond
};
/**
* Creates a new @c piecewise_constant_distribution with
- * a single interval, [0, 1)$.
+ * a single interval, [0, 1).
*/
piecewise_constant_distribution()
{
@@ -282,9 +284,9 @@
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
- template<class F>
- piecewise_constant_distribution(std::initializer_list<RealType> il, F f)
- : _intervals(il)
+ template<class T, class F>
+ piecewise_constant_distribution(std::initializer_list<T> il, F f)
+ : _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
_intervals.clear();
@@ -387,9 +389,9 @@
* Returns a vector containing the probability density
* over each interval.
*/
- std::vector<WeightType> densities() const
+ std::vector<RealType> densities() const
{
- std::vector<WeightType> result(_bins.probabilities());
+ std::vector<RealType> result(_bins.probabilities());
for(std::size_t i = 0; i < result.size(); ++i) {
result[i] /= (_intervals[i+1] - _intervals[i]);
}
@@ -454,13 +456,8 @@
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(piecewise_constant_distribution)
private:
-
- /// @cond
-
discrete_distribution<std::size_t, WeightType> _bins;
std::vector<RealType> _intervals;
-
- /// @endcond
};
}
Copied: branches/release/boost/random/piecewise_linear_distribution.hpp (from r68028, /trunk/boost/random/piecewise_linear_distribution.hpp)
==============================================================================
--- /trunk/boost/random/piecewise_linear_distribution.hpp (original)
+++ branches/release/boost/random/piecewise_linear_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -15,9 +15,9 @@
#include <vector>
#include <algorithm>
-#include <cassert>
#include <cmath>
#include <cstdlib>
+#include <boost/assert.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/detail/config.hpp>
@@ -37,10 +37,10 @@
/**
* The class @c piecewise_linear_distribution models a \random_distribution.
*/
-template<class RealType = double, class WeightType = double>
+template<class RealType = double>
class piecewise_linear_distribution {
public:
- typedef RealType input_type;
+ typedef std::size_t input_type;
typedef RealType result_type;
class param_type {
@@ -54,8 +54,8 @@
*/
param_type()
{
- _weights.push_back(WeightType(1));
- _weights.push_back(WeightType(1));
+ _weights.push_back(RealType(1));
+ _weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
@@ -78,8 +78,8 @@
{
if(_intervals.size() < 2) {
_intervals.clear();
- _weights.push_back(WeightType(1));
- _weights.push_back(WeightType(1));
+ _weights.push_back(RealType(1));
+ _weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
@@ -107,8 +107,8 @@
{
if(_intervals.size() < 2) {
_intervals.clear();
- _weights.push_back(WeightType(1));
- _weights.push_back(WeightType(1));
+ _weights.push_back(RealType(1));
+ _weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
@@ -139,8 +139,8 @@
{
if(_intervals.size() < 2) {
_weights.clear();
- _weights.push_back(WeightType(1));
- _weights.push_back(WeightType(1));
+ _weights.push_back(RealType(1));
+ _weights.push_back(RealType(1));
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
@@ -159,7 +159,7 @@
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
- assert(delta > 0);
+ BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_weights.push_back(f(xmin + k*delta));
_intervals.push_back(xmin + k*delta);
@@ -175,16 +175,16 @@
* Returns a vector containing the probability densities
* at all the interval boundaries.
*/
- std::vector<WeightType> densities() const
+ std::vector<RealType> densities() const
{
- WeightType sum = static_cast<WeightType>(0);
+ RealType sum = static_cast<RealType>(0);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
sum += (_weights[i] + _weights[i + 1]) * width / 2;
}
- std::vector<WeightType> result;
+ std::vector<RealType> result;
result.reserve(_weights.size());
- for(typename std::vector<WeightType>::const_iterator
+ for(typename std::vector<RealType>::const_iterator
iter = _weights.begin(), end = _weights.end();
iter != end; ++iter)
{
@@ -205,7 +205,7 @@
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
std::vector<RealType> new_intervals;
- std::vector<WeightType> new_weights;
+ std::vector<RealType> new_weights;
detail::read_vector(is, new_intervals);
detail::read_vector(is, new_weights);
if(is) {
@@ -225,15 +225,10 @@
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
-
- /// @cond
-
friend class piecewise_linear_distribution;
std::vector<RealType> _intervals;
- std::vector<WeightType> _weights;
-
- /// @endcond
+ std::vector<RealType> _weights;
};
/**
@@ -383,9 +378,9 @@
if(is_in_rectangle) {
return dist(urng);
} else if(_weights[i] < _weights[i+1]) {
- return std::max(dist(urng), dist(urng));
+ return (std::max)(dist(urng), dist(urng));
} else {
- return std::min(dist(urng), dist(urng));
+ return (std::min)(dist(urng), dist(urng));
}
}
@@ -410,16 +405,16 @@
* Returns a vector containing the probability densities
* at the interval boundaries.
*/
- std::vector<WeightType> densities() const
+ std::vector<RealType> densities() const
{
- WeightType sum = static_cast<WeightType>(0);
+ RealType sum = static_cast<RealType>(0);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
sum += (_weights[i] + _weights[i + 1]) * width / 2;
}
- std::vector<WeightType> result;
+ std::vector<RealType> result;
result.reserve(_weights.size());
- for(typename std::vector<WeightType>::const_iterator
+ for(typename std::vector<RealType>::const_iterator
iter = _weights.begin(), end = _weights.end();
iter != end; ++iter)
{
@@ -439,7 +434,7 @@
void param(const param_type& parm)
{
std::vector<RealType> new_intervals(parm._intervals);
- std::vector<WeightType> new_weights(parm._weights);
+ std::vector<RealType> new_weights(parm._weights);
init(new_intervals, new_weights);
_intervals.swap(new_intervals);
_weights.swap(new_weights);
@@ -487,21 +482,21 @@
private:
- /// @cond
+ /// @cond \show_private
void init(const std::vector<RealType>& intervals_arg,
- const std::vector<WeightType>& weights_arg)
+ const std::vector<RealType>& weights_arg)
{
- std::vector<WeightType> bin_weights;
+ std::vector<RealType> bin_weights;
bin_weights.reserve((intervals_arg.size() - 1) * 2);
for(std::size_t i = 0; i < intervals_arg.size() - 1; ++i) {
RealType width = intervals_arg[i + 1] - intervals_arg[i];
- WeightType w1 = weights_arg[i];
- WeightType w2 = weights_arg[i + 1];
- bin_weights.push_back(std::min(w1, w2) * width);
+ RealType w1 = weights_arg[i];
+ RealType w2 = weights_arg[i + 1];
+ bin_weights.push_back((std::min)(w1, w2) * width);
bin_weights.push_back(std::abs(w1 - w2) * width / 2);
}
- typedef discrete_distribution<std::size_t, WeightType> bins_type;
+ typedef discrete_distribution<std::size_t, RealType> bins_type;
typename bins_type::param_type bins_param(bin_weights);
_bins.param(bins_param);
}
@@ -517,14 +512,14 @@
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
_weights.clear();
- _weights.push_back(WeightType(1));
- _weights.push_back(WeightType(1));
+ _weights.push_back(RealType(1));
+ _weights.push_back(RealType(1));
init();
}
- discrete_distribution<std::size_t, WeightType> _bins;
+ discrete_distribution<std::size_t, RealType> _bins;
std::vector<RealType> _intervals;
- std::vector<WeightType> _weights;
+ std::vector<RealType> _weights;
/// @endcond
};
Modified: branches/release/boost/random/poisson_distribution.hpp
==============================================================================
--- branches/release/boost/random/poisson_distribution.hpp (original)
+++ branches/release/boost/random/poisson_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/poisson_distribution.hpp header file
*
* Copyright Jens Maurer 2002
+ * Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,102 +16,345 @@
#define BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
-#include <iostream>
+#include <cstdlib>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/disable_warnings.hpp>
+
namespace boost {
+namespace random {
+
+namespace detail {
+
+template<class RealType>
+struct poisson_table {
+ static RealType value[10];
+};
+
+template<class RealType>
+RealType poisson_table<RealType>::value[10] = {
+ 0.0,
+ 0.0,
+ 0.69314718055994529,
+ 1.7917594692280550,
+ 3.1780538303479458,
+ 4.7874917427820458,
+ 6.5792512120101012,
+ 8.5251613610654147,
+ 10.604602902745251,
+ 12.801827480081469
+};
-// Knuth
+}
/**
* An instantiation of the class template @c poisson_distribution is a
* model of \random_distribution. The poisson distribution has
* \f$p(i) = \frac{e^{-\lambda}\lambda^i}{i!}\f$
+ *
+ * This implementation is based on the PTRD algorithm described
+ *
+ * @blockquote
+ * "The transformed rejection method for generating Poisson random variables",
+ * Wolfgang Hormann, Insurance: Mathematics and Economics
+ * Volume 12, Issue 1, February 1993, Pages 39-45
+ * @endblockquote
*/
template<class IntType = int, class RealType = double>
-class poisson_distribution
-{
+class poisson_distribution {
public:
- typedef RealType input_type;
- typedef IntType result_type;
+ typedef IntType result_type;
+ typedef RealType input_type;
- /**
- * Constructs a @c poisson_distribution with the parameter @c mean.
- *
- * Requires: mean > 0
- */
- explicit poisson_distribution(const RealType& mean_arg = RealType(1))
- : _mean(mean_arg)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
- BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
+ class param_type {
+ public:
+ typedef poisson_distribution distribution_type;
+ /**
+ * Construct a param_type object with the parameter "mean"
+ *
+ * Requires: mean > 0
+ */
+ explicit param_type(RealType mean_arg = RealType(1))
+ : _mean(mean_arg)
+ {
+ BOOST_ASSERT(_mean > 0);
+ }
+ /* Returns the "mean" parameter of the distribution. */
+ RealType mean() const { return _mean; }
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os,
+ const param_type& parm)
+ {
+ os << parm._mean;
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
+ {
+ is >> parm._mean;
+ return is;
+ }
#endif
+ /** Returns true if the parameters have the same values. */
+ friend bool operator==(const param_type& lhs, const param_type& rhs)
+ {
+ return lhs._mean == rhs._mean;
+ }
+ /** Returns true if the parameters have different values. */
+ friend bool operator!=(const param_type& lhs, const param_type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ private:
+ RealType _mean;
+ };
+
+ /**
+ * Constructs a @c poisson_distribution with the parameter @c mean.
+ *
+ * Requires: mean > 0
+ */
+ explicit poisson_distribution(RealType mean_arg = RealType(1))
+ : _mean(mean_arg)
+ {
+ BOOST_ASSERT(_mean > 0);
+ init();
+ }
+
+ /**
+ * Construct an @c poisson_distribution object from the
+ * parameters.
+ */
+ explicit poisson_distribution(const param_type& parm)
+ : _mean(parm.mean())
+ {
+ init();
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * poisson distribution.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng) const
+ {
+ if(use_inversion()) {
+ return invert(urng);
+ } else {
+ return generate(urng);
+ }
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * poisson distribution with parameters specified by param.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng, const param_type& parm) const
+ {
+ return poisson_distribution(parm)(urng);
+ }
- assert(_mean > RealType(0));
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: the "mean" parameter of the distribution.
- */
- RealType mean() const { return _mean; }
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- // TODO: This is O(_mean), but it should be O(log(_mean)) for large _mean
- RealType product = RealType(1);
- for(result_type m = 0; ; ++m) {
- product *= eng();
- if(product <= _exp_mean)
- return m;
+ /** Returns the "mean" parameter of the distribution. */
+ RealType mean() const { return _mean; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
+ /** Returns the largest value that the distribution can produce. */
+ IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
+ { return (std::numeric_limits<IntType>::max)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_mean); }
+ /** Sets parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _mean = parm.mean();
+ init();
}
- }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const poisson_distribution& pd)
- {
- os << pd._mean;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, poisson_distribution& pd)
- {
- is >> std::ws >> pd._mean;
- pd.init();
- return is;
- }
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const poisson_distribution& pd)
+ {
+ os << pd.param();
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, poisson_distribution& pd)
+ {
+ pd.read(is);
+ return is;
+ }
#endif
+
+ /** Returns true if the two distributions will produce the same
+ sequence of values, given equal generators. */
+ friend bool operator==(const poisson_distribution& lhs,
+ const poisson_distribution& rhs)
+ {
+ return lhs._mean == rhs._mean;
+ }
+ /** Returns true if the two distributions could produce different
+ sequences of values, given equal generators. */
+ friend bool operator!=(const poisson_distribution& lhs,
+ const poisson_distribution& rhs)
+ {
+ return !(lhs == rhs);
+ }
private:
- /// \cond hide_private_members
- void init()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::exp;
-#endif
- _exp_mean = exp(-_mean);
- }
- /// \endcond
-
- RealType _mean;
- // some precomputed data from the parameters
- RealType _exp_mean;
+
+ /// @cond show_private
+
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is) {
+ param_type parm;
+ if(is >> parm) {
+ param(parm);
+ }
+ }
+
+ bool use_inversion() const
+ {
+ return _mean < 10;
+ }
+
+ static RealType log_factorial(IntType k)
+ {
+ BOOST_ASSERT(k >= 0);
+ BOOST_ASSERT(k < 10);
+ return detail::poisson_table<RealType>::value[k];
+ }
+
+ void init()
+ {
+ using std::sqrt;
+ using std::exp;
+
+ if(use_inversion()) {
+ _exp_mean = exp(-_mean);
+ } else {
+ _ptrd.smu = sqrt(_mean);
+ _ptrd.b = 0.931 + 2.53 * _ptrd.smu;
+ _ptrd.a = -0.059 + 0.02483 * _ptrd.b;
+ _ptrd.inv_alpha = 1.1239 + 1.1328 / (_ptrd.b - 3.4);
+ _ptrd.v_r = 0.9277 - 3.6224 / (_ptrd.b - 2);
+ }
+ }
+
+ template<class URNG>
+ IntType generate(URNG& urng) const
+ {
+ using std::floor;
+ using std::abs;
+ using std::log;
+
+ while(true) {
+ RealType u;
+ RealType v = uniform_01<RealType>()(urng);
+ if(v <= 0.86 * _ptrd.v_r) {
+ u = v / _ptrd.v_r - 0.43;
+ return static_cast<IntType>(floor(
+ (2*_ptrd.a/(0.5-abs(u)) + _ptrd.b)*u + _mean + 0.445));
+ }
+
+ if(v >= _ptrd.v_r) {
+ u = uniform_01<RealType>()(urng) - 0.5;
+ } else {
+ u = v/_ptrd.v_r - 0.93;
+ u = ((u < 0)? -0.5 : 0.5) - u;
+ v = uniform_01<RealType>()(urng) * _ptrd.v_r;
+ }
+
+ RealType us = 0.5 - abs(u);
+ if(us < 0.013 && v > us) {
+ continue;
+ }
+
+ RealType k = floor((2*_ptrd.a/us + _ptrd.b)*u+_mean+0.445);
+ v = v*_ptrd.inv_alpha/(_ptrd.a/(us*us) + _ptrd.b);
+
+ RealType log_sqrt_2pi = 0.91893853320467267;
+
+ if(k >= 10) {
+ if(log(v*_ptrd.smu) <= (k + 0.5)*log(_mean/k)
+ - _mean
+ - log_sqrt_2pi
+ + k
+ - (1/12. - (1/360. - 1/(1260.*k*k))/(k*k))/k) {
+ return static_cast<IntType>(k);
+ }
+ } else if(k >= 0) {
+ if(log(v) <= k*log(_mean)
+ - _mean
+ - log_factorial(static_cast<IntType>(k))) {
+ return static_cast<IntType>(k);
+ }
+ }
+ }
+ }
+
+ template<class URNG>
+ IntType invert(URNG& urng) const
+ {
+ RealType p = _exp_mean;
+ IntType x = 0;
+ RealType u = uniform_01<RealType>()(urng);
+ while(u > p) {
+ u = u - p;
+ ++x;
+ p = _mean * p / x;
+ }
+ return x;
+ }
+
+ RealType _mean;
+
+ union {
+ // for ptrd
+ struct {
+ RealType v_r;
+ RealType a;
+ RealType b;
+ RealType smu;
+ RealType inv_alpha;
+ } _ptrd;
+ // for inversion
+ RealType _exp_mean;
+ };
+
+ /// @endcond
};
+} // namespace random
+
+using random::poisson_distribution;
+
} // namespace boost
+#include <boost/random/detail/enable_warnings.hpp>
+
#endif // BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
Copied: branches/release/boost/random/random_device.hpp (from r68814, /trunk/boost/random/random_device.hpp)
==============================================================================
--- /trunk/boost/random/random_device.hpp (original)
+++ branches/release/boost/random/random_device.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -71,13 +71,16 @@
*
* The test program <a href="\boost/libs/random/performance/nondet_random_speed.cpp">
* nondet_random_speed.cpp</a> measures the execution times of the
- * nondet_random.hpp implementation of the above algorithms in a tight
- * loop. The performance has been evaluated on a Pentium Pro 200 MHz
- * with gcc 2.95.2, Linux 2.2.13, glibc 2.1.2.
+ * random_device.hpp implementation of the above algorithms in a tight
+ * loop. The performance has been evaluated on an
+ * Intel(R) Core(TM) i7 CPU Q 840 \@ 1.87GHz, 1867 Mhz with
+ * Visual C++ 2010, Microsoft Windows 7 Professional and with gcc 4.4.5,
+ * Ubuntu Linux 2.6.35-25-generic.
*
* <table cols="2">
- * <tr><th>class</th><th>time per invocation [usec]</th></tr>
- * <tr><td> @xmlonly <classname alt="boost::random_device">random_device</classname> @endxmlonly </td><td>92.0</td></tr>
+ * <tr><th>Platform</th><th>time per invocation [microseconds]</th></tr>
+ * <tr><td> Windows </td><td>2.9</td></tr>
+ * <tr><td> Linux </td><td>1.7</td></tr>
* </table>
*
* The measurement error is estimated at +/- 1 usec.
Modified: branches/release/boost/random/random_number_generator.hpp
==============================================================================
--- branches/release/boost/random/random_number_generator.hpp (original)
+++ branches/release/boost/random/random_number_generator.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,13 +16,13 @@
#ifndef BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
-#include <boost/config.hpp>
-#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/variate_generator.hpp>
+#include <boost/assert.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+
+#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
+namespace random {
/**
* Instantiations of class template random_number_generator model a
@@ -32,40 +32,42 @@
*
* The template parameter IntType shall denote some integer-like value type.
*/
-template<class UniformRandomNumberGenerator, class IntType = long>
+template<class URNG, class IntType = long>
class random_number_generator
{
public:
- typedef UniformRandomNumberGenerator base_type;
- typedef IntType argument_type;
- typedef IntType result_type;
- /**
- * Constructs a random_number_generator functor with the given
- * \uniform_random_number_generator as the underlying source of
- * random numbers.
- */
- random_number_generator(base_type& rng) : _rng(rng)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
-#endif
- }
- // compiler-generated copy ctor is fine
- // assignment is disallowed because there is a reference member
-
- /**
- * Returns a value in the range [0, n)
- */
- result_type operator()(argument_type n)
- {
- typedef uniform_int<IntType> dist_type;
- return variate_generator<base_type&, dist_type>(_rng, dist_type(0, n-1))();
- }
+ typedef URNG base_type;
+ typedef IntType argument_type;
+ typedef IntType result_type;
+ /**
+ * Constructs a random_number_generator functor with the given
+ * \uniform_random_number_generator as the underlying source of
+ * random numbers.
+ */
+ random_number_generator(base_type& rng) : _rng(rng) {}
+
+ // compiler-generated copy ctor is fine
+ // assignment is disallowed because there is a reference member
+
+ /**
+ * Returns a value in the range [0, n)
+ */
+ result_type operator()(argument_type n)
+ {
+ BOOST_ASSERT(n > 0);
+ return uniform_int_distribution<IntType>(0, n-1)(_rng);
+ }
private:
- base_type& _rng;
+ base_type& _rng;
};
+} // namespace random
+
+using random::random_number_generator;
+
} // namespace boost
+#include <boost/random/detail/enable_warnings.hpp>
+
#endif // BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
Modified: branches/release/boost/random/ranlux.hpp
==============================================================================
--- branches/release/boost/random/ranlux.hpp (original)
+++ branches/release/boost/random/ranlux.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -23,12 +23,7 @@
namespace boost {
namespace random {
- typedef subtract_with_carry<int, (1<<24), 10, 24, 0> ranlux_base;
- typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01;
- typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01;
-}
-namespace random {
namespace detail {
/**
* The ranlux family of generators are described in
@@ -49,33 +44,56 @@
*/
class ranlux_documentation {};
}
-}
+
+typedef subtract_with_carry_engine<uint32_t, 24, 10, 24> ranlux_base;
+typedef subtract_with_carry_01_engine<float, 24, 10, 24> ranlux_base_01;
+typedef subtract_with_carry_01_engine<double, 48, 10, 24> ranlux64_base_01;
+
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux_base, 223, 24> ranlux3;
+typedef discard_block_engine<ranlux_base, 223, 24> ranlux3;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux_base, 389, 24> ranlux4;
+typedef discard_block_engine<ranlux_base, 389, 24> ranlux4;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux_base_01, 223, 24> ranlux3_01;
+typedef discard_block_engine<ranlux_base_01, 223, 24> ranlux3_01;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux_base_01, 389, 24> ranlux4_01;
+typedef discard_block_engine<ranlux_base_01, 389, 24> ranlux4_01;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux64_base_01, 223, 24> ranlux64_3_01;
+typedef discard_block_engine<ranlux64_base_01, 223, 24> ranlux64_3_01;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux64_base_01, 389, 24> ranlux64_4_01;
+typedef discard_block_engine<ranlux64_base_01, 389, 24> ranlux64_4_01;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-namespace random {
- typedef random::subtract_with_carry<int64_t, (int64_t(1)<<48), 10, 24, 0> ranlux64_base;
-}
+typedef subtract_with_carry_engine<uint64_t, 48, 10, 24> ranlux64_base;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux64_base, 223, 24> ranlux64_3;
+typedef discard_block_engine<ranlux64_base, 223, 24> ranlux64_3;
/** @copydoc boost::random::detail::ranlux_documentation */
-typedef random::discard_block<random::ranlux64_base, 389, 24> ranlux64_4;
+typedef discard_block_engine<ranlux64_base, 389, 24> ranlux64_4;
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
+
+typedef subtract_with_carry_engine<uint32_t, 24, 10, 24> ranlux24_base;
+typedef subtract_with_carry_engine<uint64_t, 48, 5, 12> ranlux48_base;
+
+typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
+#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
+#endif
+}
+
+using random::ranlux3;
+using random::ranlux4;
+using random::ranlux3_01;
+using random::ranlux4_01;
+using random::ranlux64_3_01;
+using random::ranlux64_4_01;
+#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+using random::ranlux64_3;
+using random::ranlux64_4;
+#endif
+
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
Copied: branches/release/boost/random/seed_seq.hpp (from r63217, /trunk/boost/random/seed_seq.hpp)
==============================================================================
--- /trunk/boost/random/seed_seq.hpp (original)
+++ branches/release/boost/random/seed_seq.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -30,21 +30,37 @@
namespace boost {
namespace random {
+/**
+ * The class @c seed_seq stores a sequence of 32-bit words
+ * for seeding a \pseudo_random_number_generator. These
+ * words will be combined to fill the entire state of the
+ * generator.
+ */
class seed_seq {
public:
typedef boost::uint_least32_t result_type;
+ /** Initializes a seed_seq to hold an empty sequence. */
seed_seq() {}
#ifndef BOOST_NO_INITIALIZER_LISTS
+ /** Initializes the sequence from an initializer_list. */
template<class T>
seed_seq(const std::initializer_list<T>& il) : v(il.begin(), il.end()) {}
#endif
+ /** Initializes the sequence from an iterator range. */
template<class Iter>
seed_seq(Iter first, Iter last) : v(first, last) {}
+ /** Initializes the sequence from Boost.Range range. */
template<class Range>
explicit seed_seq(const Range& range)
: v(boost::begin(range), boost::end(range)) {}
+ /**
+ * Fills a range with 32-bit values based on the stored sequence.
+ *
+ * Requires: Iter must be a Random Access Iterator whose value type
+ * is an unsigned integral type at least 32 bits wide.
+ */
template<class Iter>
void generate(Iter first, Iter last) const
{
@@ -87,7 +103,9 @@
*(first + k%n) = r4;
}
}
+ /** Returns the size of the sequence. */
std::size_t size() const { return v.size(); }
+ /** Writes the stored sequence to iter. */
template<class Iter>
void param(Iter out) { std::copy(v.begin(), v.end(), out); }
private:
Copied: branches/release/boost/random/shuffle_order.hpp (from r63327, /trunk/boost/random/shuffle_order.hpp)
==============================================================================
--- /trunk/boost/random/shuffle_order.hpp (original)
+++ branches/release/boost/random/shuffle_order.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -111,8 +111,17 @@
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
- template<class T>
- void seed(T s) { _rng.seed(s); init(); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(shuffle_order_engine,
+ result_type, seed_arg)
+ { _rng.seed(seed_arg); init(); }
+ /**
+ * Invokes the one-argument seed method of the base generator
+ * with the parameter seq and re-initializes the internal buffer array.
+ *
+ * Complexity: Exactly k+1 invocations of the base generator.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(shuffle_order_engine, SeedSeq, seq)
+ { _rng.seed(seq); init(); }
template<class It> void seed(It& first, It last)
{ _rng.seed(first, last); init(); }
@@ -134,36 +143,15 @@
// try to do it in the native type if we know that it won't
// overflow
j = k * off / (brange + 1);
- }
-#if !defined(BOOST_NO_INT64_T)
- else if(brange < (std::numeric_limits<uint64_t>::max)() / k) {
+ } else if(brange < (std::numeric_limits<uintmax_t>::max)() / k) {
// Otherwise try to use uint64_t
j = static_cast<base_unsigned>(
- static_cast<uint64_t>(off) * k /
- (static_cast<uint64_t>(brange) + 1));
- }
-#endif
- else {
- // If all else fails, fall back to a general algorithm that
- // never overflows.
-
- const base_unsigned r_mod_k = ((brange % k) + 1) % k;
- const base_unsigned bucket_size = (brange - k + 1)/k + 1;
- // if the candidate from the first round is zero, we're safe.
- base_unsigned candidate = 0;
- base_unsigned old_candidate;
- base_unsigned error = 0;
- do {
- old_candidate = candidate;
- candidate = (off - error) / bucket_size;
- base_unsigned possible = (off - error + 1) / bucket_size;
- error = possible - possible * (k - r_mod_k) / k;
- } while(old_candidate != candidate);
-
- j = candidate;
-
- // Would cause overflow
- // assert(j == uint64_t(off)*k/(uint64_t(brange)+1));
+ static_cast<uintmax_t>(off) * k /
+ (static_cast<uintmax_t>(brange) + 1));
+ } else {
+ boost::uintmax_t divisor =
+ static_cast<boost::uintmax_t>(brange) + 1;
+ j = static_cast<base_unsigned>(detail::muldiv(off, k, divisor));
}
// assert(0 <= j && j < k);
y = v[j];
@@ -171,24 +159,18 @@
return y;
}
-#ifndef BOOST_NO_LONG_LONG
/** Advances the generator by z steps. */
- void discard(boost::ulong_long_type z)
+ void discard(boost::uintmax_t z)
{
- for(boost::ulong_long_type j = 0; j < z; ++j) {
+ for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
-#endif
/** Fills a range with pseudo-random values. */
template<class Iter>
void generate(Iter first, Iter last)
- {
- for(; first != last; ++first) {
- *first = (*this)();
- }
- }
+ { detail::generate_from_int(*this, first, last); }
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
@@ -201,7 +183,7 @@
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, shuffle_order_engine, s)
{
os << s._rng;
- for(int i = 0; i < k; ++i)
+ for(std::size_t i = 0; i < k; ++i)
os << ' ' << s.v[i];
os << ' ' << s.y;
return os;
@@ -211,7 +193,7 @@
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, shuffle_order_engine, s)
{
is >> s._rng;
- for(int i = 0; i < k; ++i)
+ for(std::size_t i = 0; i < k; ++i)
is >> std::ws >> s.v[i];
is >> std::ws >> s.y;
return is;
@@ -225,7 +207,7 @@
private:
- /// \cond
+ /// \cond show_private
void init()
{
@@ -252,7 +234,6 @@
const std::size_t shuffle_order_engine<URNG, k>::buffer_size;
#endif
-// validation by experiment from Harry Erwin's generator.h (private e-mail)
/**
* According to Harry Erwin (private e-mail), the specialization
* @c kreutzer1986 was suggested in:
@@ -266,6 +247,15 @@
linear_congruential_engine<uint32_t, 1366, 150889, 714025>,
97> kreutzer1986;
+/**
+ * The specialization @c knuth_b is specified by the C++ standard.
+ * It is described in
+ *
+ * @blockquote
+ * "The Art of Computer Programming, Second Edition, Volume 2,
+ * Seminumerical Algorithms", Donald Knuth, Addison-Wesley, 1981.
+ * @endblockquote
+ */
typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
} // namespace random
Modified: branches/release/boost/random/shuffle_output.hpp
==============================================================================
--- branches/release/boost/random/shuffle_output.hpp (original)
+++ branches/release/boost/random/shuffle_output.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,219 +16,36 @@
#ifndef BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
#define BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
-#include <iostream>
-#include <algorithm> // std::copy
-#include <cassert>
-#include <boost/config.hpp>
-#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/random/linear_congruential.hpp>
+#include <boost/random/shuffle_order.hpp>
namespace boost {
namespace random {
-/**
- * Instatiations of class template shuffle_output model a
- * \pseudo_random_number_generator. It mixes the output
- * of some (usually \linear_congruential) \uniform_random_number_generator
- * to get better statistical properties.
- * The algorithm is described in
- *
- * @blockquote
- * "Improving a poor random number generator", Carter Bays
- * and S.D. Durham, ACM Transactions on Mathematical Software,
- * Vol 2, No. 1, March 1976, pp. 59-64.
- * http://doi.acm.org/10.1145/355666.355670
- * @endblockquote
- *
- * The output of the base generator is buffered in an array of
- * length k. Every output X(n) has a second role: It gives an
- * index into the array where X(n+1) will be retrieved. Used
- * array elements are replaced with fresh output from the base
- * generator.
- *
- * Template parameters are the base generator and the array
- * length k, which should be around 100. The template parameter
- * val is the validation value checked by validation.
- */
-template<class UniformRandomNumberGenerator, int k,
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- typename UniformRandomNumberGenerator::result_type
-#else
- uint32_t
-#endif
- val = 0>
-class shuffle_output
+/// \cond
+
+template<typename URNG, int k,
+ typename URNG::result_type val = 0>
+class shuffle_output : public shuffle_order_engine<URNG, k>
{
+ typedef shuffle_order_engine<URNG, k> base_t;
+ typedef typename base_t::result_type result_type;
public:
- typedef UniformRandomNumberGenerator base_type;
- typedef typename base_type::result_type result_type;
-
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, buffer_size = k);
-
- /**
- * Constructs a @c shuffle_output generator by invoking the
- * default constructor of the base generator.
- *
- * Complexity: Exactly k+1 invocations of the base generator.
- */
- shuffle_output() : _rng() { init(); }
-#if defined(BOOST_MSVC) && _MSC_VER < 1300
- // MSVC does not implicitly generate the copy constructor here
- shuffle_output(const shuffle_output & x)
- : _rng(x._rng), y(x.y) { std::copy(x.v, x.v+k, v); }
-#endif
- /**
- * Constructs a shuffle_output generator by invoking the one-argument
- * constructor of the base generator with the parameter seed.
- *
- * Complexity: Exactly k+1 invocations of the base generator.
- */
- template<class T>
- explicit shuffle_output(T s) : _rng(s) { init(); }
- /**
- * Constructs a shuffle_output generator by using a copy
- * of the provided generator.
- *
- * Precondition: The template argument UniformRandomNumberGenerator
- * shall denote a CopyConstructible type.
- *
- * Complexity: Exactly k+1 invocations of the base generator.
- */
- explicit shuffle_output(const base_type & rng) : _rng(rng) { init(); }
- template<class It> shuffle_output(It& first, It last)
- : _rng(first, last) { init(); }
- void seed() { _rng.seed(); init(); }
- /**
- * Invokes the one-argument seed method of the base generator
- * with the parameter seed and re-initializes the internal buffer array.
- *
- * Complexity: Exactly k+1 invocations of the base generator.
- */
- template<class T>
- void seed(T s) { _rng.seed(s); init(); }
- template<class It> void seed(It& first, It last)
- {
- _rng.seed(first, last);
- init();
- }
-
- const base_type& base() const { return _rng; }
-
- result_type operator()() {
- // calculating the range every time may seem wasteful. However, this
- // makes the information locally available for the optimizer.
- result_type range = (max)()-(min)()+1;
- int j = k*(y-(min)())/range;
- // assert(0 <= j && j < k);
- y = v[j];
- v[j] = _rng();
- return y;
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); }
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const shuffle_output& s)
- {
- os << s._rng << " " << s.y << " ";
- for(int i = 0; i < s.buffer_size; ++i)
- os << s.v[i] << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, shuffle_output& s)
- {
- is >> s._rng >> std::ws >> s.y >> std::ws;
- for(int i = 0; i < s.buffer_size; ++i)
- is >> s.v[i] >> std::ws;
- return is;
- }
-#endif
-
- friend bool operator==(const shuffle_output& x, const shuffle_output& y)
- { return x._rng == y._rng && x.y == y.y && std::equal(x.v, x.v+k, y.v); }
- friend bool operator!=(const shuffle_output& x, const shuffle_output& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const shuffle_output& rhs) const
- { return _rng == rhs._rng && y == rhs.y && std::equal(v, v+k, rhs.v); }
- bool operator!=(const shuffle_output& rhs) const
- { return !(*this == rhs); }
-#endif
-private:
- void init()
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
-#endif
- result_type range = (max)()-(min)();
- assert(range > 0); // otherwise there would be little choice
- if(static_cast<unsigned long>(k * range) <
- static_cast<unsigned long>(range)) // not a sufficient condition
- // likely overflow with bucket number computation
- assert(!"overflow will occur");
-
- // we cannot use std::generate, because it uses pass-by-value for _rng
- for(result_type * p = v; p != v+k; ++p)
- *p = _rng();
- y = _rng();
- }
-
- base_type _rng;
- result_type v[k];
- result_type y;
+ shuffle_output() {}
+ template<class T>
+ shuffle_output(T& arg) : base_t(arg) {}
+ template<class T>
+ shuffle_output(const T& arg) : base_t(arg) {}
+ template<class It>
+ shuffle_output(It& first, It last) : base_t(first, last) {}
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (this->base().min)(); }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return (this->base().max)(); }
};
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-// A definition is required even for integral static constants
-template<class UniformRandomNumberGenerator, int k,
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- typename UniformRandomNumberGenerator::result_type
-#else
- uint32_t
-#endif
- val>
-const bool shuffle_output<UniformRandomNumberGenerator, k, val>::has_fixed_range;
-
-template<class UniformRandomNumberGenerator, int k,
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- typename UniformRandomNumberGenerator::result_type
-#else
- uint32_t
-#endif
- val>
-const int shuffle_output<UniformRandomNumberGenerator, k, val>::buffer_size;
-#endif
-
-} // namespace random
-
-// validation by experiment from Harry Erwin's generator.h (private e-mail)
-/**
- * According to Harry Erwin (private e-mail), the specialization
- * @c kreutzer1986 was suggested in:
- *
- * @blockquote
- * "System Simulation: Programming Styles and Languages (International
- * Computer Science Series)", Wolfgang Kreutzer, Addison-Wesley, December 1986.
- * @endblockquote
- */
-typedef random::shuffle_output<
- random::linear_congruential<uint32_t, 1366, 150889, 714025, 0>,
- 97, 139726> kreutzer1986;
-
+/// \endcond
-} // namespace boost
+}
+}
#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
Copied: branches/release/boost/random/student_t_distribution.hpp (from r67710, /trunk/boost/random/student_t_distribution.hpp)
==============================================================================
--- /trunk/boost/random/student_t_distribution.hpp (original)
+++ branches/release/boost/random/student_t_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -31,7 +31,7 @@
* It has \f$\displaystyle p(x) =
* \frac{1}{\sqrt{n\pi}}
* \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
- * \left(1}\frac{x^2}{n}\right)^{-(n+1)/2}
+ * \left(1+\frac{x^2}{n}\right)^{-(n+1)/2}
* \f$.
*/
template<class RealType = double>
@@ -113,10 +113,10 @@
RealType n() const { return _chi_squared.n(); }
/** Returns the smallest value that the distribution can produce. */
- RealType min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -std::numeric_limits<RealType>::infinity(); }
/** Returns the largest value that the distribution can produce. */
- RealType max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
Modified: branches/release/boost/random/subtract_with_carry.hpp
==============================================================================
--- branches/release/boost/random/subtract_with_carry.hpp (original)
+++ branches/release/boost/random/subtract_with_carry.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -16,56 +16,88 @@
#ifndef BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
#define BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
-#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/config/no_tr1/cmath.hpp> // std::pow
#include <iostream>
#include <algorithm> // std::equal
#include <stdexcept>
-#include <boost/config/no_tr1/cmath.hpp> // std::pow
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
+#include <boost/integer/static_log2.hpp>
+#include <boost/integer/integer_mask.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/seed_impl.hpp>
+#include <boost/random/detail/generator_seed_seq.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
-#if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
-# define BOOST_RANDOM_EXTRACT_SWC_01
-#endif
-
-#if defined(__APPLE_CC__) && defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
-# define BOOST_RANDOM_EXTRACT_SWC_01
-#endif
-
-# ifdef BOOST_RANDOM_EXTRACT_SWC_01
-namespace detail
+namespace detail {
+
+struct subtract_with_carry_discard
{
- template <class IStream, class SubtractWithCarry, class RealType>
- void extract_subtract_with_carry_01(
- IStream& is
- , SubtractWithCarry& f
- , RealType& carry
- , RealType* x
- , RealType modulus)
- {
- RealType value;
- for(unsigned int j = 0; j < f.long_lag; ++j) {
- is >> value >> std::ws;
- x[j] = value / modulus;
- }
- is >> value >> std::ws;
- carry = value / modulus;
- }
+ template<class Engine>
+ static void apply(Engine& eng, boost::uintmax_t z)
+ {
+ typedef typename Engine::result_type IntType;
+ const std::size_t short_lag = Engine::short_lag;
+ const std::size_t long_lag = Engine::long_lag;
+ std::size_t k = eng.k;
+ IntType carry = eng.carry;
+ if(k != 0) {
+ // increment k until it becomes 0.
+ if(k < short_lag) {
+ std::size_t limit = (short_lag - k) < z?
+ short_lag : (k + static_cast<std::size_t>(z));
+ for(std::size_t j = k; j < limit; ++j) {
+ carry = eng.do_update(j, j + long_lag - short_lag, carry);
+ }
+ }
+ std::size_t limit = (long_lag - k) < z?
+ long_lag : (k + static_cast<std::size_t>(z));
+ std::size_t start = (k < short_lag ? short_lag : k);
+ for(std::size_t j = start; j < limit; ++j) {
+ carry = eng.do_update(j, j - short_lag, carry);
+ }
+ }
+
+ k = ((z % long_lag) + k) % long_lag;
+
+ if(k < z) {
+ // main loop: update full blocks from k = 0 to long_lag
+ for(std::size_t i = 0; i < (z - k) / long_lag; ++i) {
+ for(std::size_t j = 0; j < short_lag; ++j) {
+ carry = eng.do_update(j, j + long_lag - short_lag, carry);
+ }
+ for(std::size_t j = short_lag; j < long_lag; ++j) {
+ carry = eng.do_update(j, j - short_lag, carry);
+ }
+ }
+
+ // Update the last partial block
+ std::size_t limit = short_lag < k? short_lag : k;
+ for(std::size_t j = 0; j < limit; ++j) {
+ carry = eng.do_update(j, j + long_lag - short_lag, carry);
+ }
+ for(std::size_t j = short_lag; j < k; ++j) {
+ carry = eng.do_update(j, j - short_lag, carry);
+ }
+ }
+ eng.carry = carry;
+ eng.k = k;
+ }
+};
+
}
-# endif
/**
- * Instantiations of @c subtract_with_carry model a
+ * Instantiations of @c subtract_with_carry_engine model a
* \pseudo_random_number_generator. The algorithm is
* described in
*
@@ -75,388 +107,497 @@
* Volume 1, Number 3 (1991), 462-480.
* @endblockquote
*/
-template<class IntType, IntType m, unsigned int s, unsigned int r,
- IntType val>
-class subtract_with_carry
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+class subtract_with_carry_engine
{
public:
- typedef IntType result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = true);
- BOOST_STATIC_CONSTANT(result_type, min_value = 0);
- BOOST_STATIC_CONSTANT(result_type, max_value = m-1);
- BOOST_STATIC_CONSTANT(result_type, modulus = m);
- BOOST_STATIC_CONSTANT(unsigned int, long_lag = r);
- BOOST_STATIC_CONSTANT(unsigned int, short_lag = s);
-
- subtract_with_carry() {
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_signed);
+ typedef IntType result_type;
+ BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
+ BOOST_STATIC_CONSTANT(std::size_t, long_lag = r);
+ BOOST_STATIC_CONSTANT(std::size_t, short_lag = s);
+ BOOST_STATIC_CONSTANT(uint32_t, default_seed = 19780503u);
+
+ // Required by the old Boost.Random concepts
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ // Backwards compatibility
+ BOOST_STATIC_CONSTANT(result_type, modulus = (result_type(1) << w));
+
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
-#endif
- seed();
- }
- BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry, uint32_t, value)
- { seed(value); }
- BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry, Generator, gen)
- { seed(gen); }
- template<class It> subtract_with_carry(It& first, It last) { seed(first,last); }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- void seed() { seed(19780503u); }
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry, uint32_t, value)
- {
- random::linear_congruential<int32_t, 40014, 0, 2147483563, 0> intgen(value);
- seed(intgen);
- }
-
- // For GCC, moving this function out-of-line prevents inlining, which may
- // reduce overall object code size. However, MSVC does not grok
- // out-of-line template member functions.
- BOOST_RANDOM_DETAIL_GENERATOR_SEED(subtract_with_carry, Generator, gen)
- {
- // I could have used std::generate_n, but it takes "gen" by value
- for(unsigned int j = 0; j < long_lag; ++j)
- x[j] = gen() % modulus;
- carry = (x[long_lag-1] == 0);
- k = 0;
- }
-
- template<class It>
- void seed(It& first, It last)
- {
- unsigned int j;
- for(j = 0; j < long_lag && first != last; ++j, ++first)
- x[j] = *first % modulus;
- if(first == last && j < long_lag)
- throw std::invalid_argument("subtract_with_carry::seed");
- carry = (x[long_lag-1] == 0);
- k = 0;
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return min_value; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return max_value; }
-
- result_type operator()()
- {
- int short_index = k - short_lag;
- if(short_index < 0)
- short_index += long_lag;
- IntType delta;
- if (x[short_index] >= x[k] + carry) {
- // x(n) >= 0
- delta = x[short_index] - (x[k] + carry);
- carry = 0;
- } else {
- // x(n) < 0
- delta = modulus - x[k] - carry + x[short_index];
- carry = 1;
- }
- x[k] = delta;
- ++k;
- if(k >= long_lag)
- k = 0;
- return delta;
- }
-public:
- static bool validation(result_type x) { return x == val; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os,
- const subtract_with_carry& f)
- {
- for(unsigned int j = 0; j < f.long_lag; ++j)
- os << f.compute(j) << " ";
- os << f.carry << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, subtract_with_carry& f)
- {
- for(unsigned int j = 0; j < f.long_lag; ++j)
- is >> f.x[j] >> std::ws;
- is >> f.carry >> std::ws;
- f.k = 0;
- return is;
- }
-#endif
+ /**
+ * Constructs a new @c subtract_with_carry_engine and seeds
+ * it with the default seed.
+ */
+ subtract_with_carry_engine() { seed(); }
+ /**
+ * Constructs a new @c subtract_with_carry_engine and seeds
+ * it with @c value.
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_engine,
+ IntType, value)
+ { seed(value); }
+ /**
+ * Constructs a new @c subtract_with_carry_engine and seeds
+ * it with values produced by @c seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(subtract_with_carry_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+ /**
+ * Constructs a new @c subtract_with_carry_engine and seeds
+ * it with values from a range. first is updated to point
+ * one past the last value consumed. If there are not
+ * enough elements in the range to fill the entire state of
+ * the generator, throws @c std::invalid_argument.
+ */
+ template<class It> subtract_with_carry_engine(It& first, It last)
+ { seed(first,last); }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Seeds the generator with the default seed. */
+ void seed() { seed(default_seed); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_engine,
+ IntType, value)
+ {
+ typedef linear_congruential_engine<uint32_t,40014,0,2147483563> gen_t;
+ gen_t intgen(static_cast<boost::uint32_t>(value));
+ detail::generator_seed_seq<gen_t> gen(intgen);
+ seed(gen);
+ }
- friend bool operator==(const subtract_with_carry& x, const subtract_with_carry& y)
- {
- for(unsigned int j = 0; j < r; ++j)
- if(x.compute(j) != y.compute(j))
- return false;
- return true;
- }
-
- friend bool operator!=(const subtract_with_carry& x, const subtract_with_carry& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const subtract_with_carry& rhs) const
- {
- for(unsigned int j = 0; j < r; ++j)
- if(compute(j) != rhs.compute(j))
- return false;
- return true;
- }
+ /** Seeds the generator with values produced by @c seq.generate(). */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(subtract_with_carry, SeedSeq, seq)
+ {
+ detail::seed_array_int<w>(seq, x);
+ carry = (x[long_lag-1] == 0);
+ k = 0;
+ }
- bool operator!=(const subtract_with_carry& rhs) const
- { return !(*this == rhs); }
-#endif
+ /**
+ * Seeds the generator with values from a range. Updates @c first to
+ * point one past the last consumed value. If the range does not
+ * contain enough elements to fill the entire state of the generator,
+ * throws @c std::invalid_argument.
+ */
+ template<class It>
+ void seed(It& first, It last)
+ {
+ detail::fill_array_int<w>(first, last, x);
+ carry = (x[long_lag-1] == 0);
+ k = 0;
+ }
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return 0; }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return boost::low_bits_mask_t<w>::sig_bits; }
+
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ std::size_t short_index =
+ (k < short_lag)?
+ (k + long_lag - short_lag) :
+ (k - short_lag);
+ carry = do_update(k, short_index, carry);
+ IntType result = x[k];
+ ++k;
+ if(k >= long_lag)
+ k = 0;
+ return result;
+ }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ detail::subtract_with_carry_discard::apply(*this, z);
+ }
+
+ /** Fills a range with random values. */
+ template<class It>
+ void generate(It first, It last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Writes a @c subtract_with_carry_engine to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, subtract_with_carry_engine, f)
+ {
+ for(unsigned int j = 0; j < f.long_lag; ++j)
+ os << f.compute(j) << ' ';
+ os << f.carry;
+ return os;
+ }
+
+ /** Reads a @c subtract_with_carry_engine from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, subtract_with_carry_engine, f)
+ {
+ for(unsigned int j = 0; j < f.long_lag; ++j)
+ is >> f.x[j] >> std::ws;
+ is >> f.carry;
+ f.k = 0;
+ return is;
+ }
+
+ /**
+ * Returns true if the two generators will produce identical
+ * sequences of values.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(subtract_with_carry_engine, x, y)
+ {
+ for(unsigned int j = 0; j < r; ++j)
+ if(x.compute(j) != y.compute(j))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns true if the two generators will produce different
+ * sequences of values.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(subtract_with_carry_engine)
private:
- /// \cond hide_private_members
- // returns x(i-r+index), where index is in 0..r-1
- IntType compute(unsigned int index) const
- {
- return x[(k+index) % long_lag];
- }
- /// \endcond
-
- // state representation; next output (state) is x(i)
- // x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
- // x(i-k) ... x(i) x(i+1) ... x(i-k+long_lag-1)
- // speed: base: 20-25 nsec
- // ranlux_4: 230 nsec, ranlux_7: 430 nsec, ranlux_14: 810 nsec
- // This state representation makes operator== and save/restore more
- // difficult, because we've already computed "too much" and thus
- // have to undo some steps to get at x(i-r) etc.
-
- // state representation: next output (state) is x(i)
- // x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
- // x(i-k) ... x(i) x(i-long_lag+1) ... x(i-k-1)
- // speed: base 28 nsec
- // ranlux_4: 370 nsec, ranlux_7: 688 nsec, ranlux_14: 1343 nsec
- IntType x[long_lag];
- unsigned int k;
- int carry;
+ /// \cond show_private
+ // returns x(i-r+index), where index is in 0..r-1
+ IntType compute(unsigned int index) const
+ {
+ return x[(k+index) % long_lag];
+ }
+
+ friend struct detail::subtract_with_carry_discard;
+
+ IntType do_update(std::size_t current, std::size_t short_index, IntType carry)
+ {
+ IntType delta;
+ IntType temp = x[current] + carry;
+ if (x[short_index] >= temp) {
+ // x(n) >= 0
+ delta = x[short_index] - temp;
+ carry = 0;
+ } else {
+ // x(n) < 0
+ delta = modulus - temp + x[short_index];
+ carry = 1;
+ }
+ x[current] = delta;
+ return carry;
+ }
+ /// \endcond
+
+ // state representation; next output (state) is x(i)
+ // x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
+ // x(i-k) ... x(i) x(i+1) ... x(i-k+long_lag-1)
+ // speed: base: 20-25 nsec
+ // ranlux_4: 230 nsec, ranlux_7: 430 nsec, ranlux_14: 810 nsec
+ // This state representation makes operator== and save/restore more
+ // difficult, because we've already computed "too much" and thus
+ // have to undo some steps to get at x(i-r) etc.
+
+ // state representation: next output (state) is x(i)
+ // x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
+ // x(i-k) ... x(i) x(i-long_lag+1) ... x(i-k-1)
+ // speed: base 28 nsec
+ // ranlux_4: 370 nsec, ranlux_7: 688 nsec, ranlux_14: 1343 nsec
+ IntType x[long_lag];
+ std::size_t k;
+ IntType carry;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const bool subtract_with_carry<IntType, m, s, r, val>::has_fixed_range;
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const IntType subtract_with_carry<IntType, m, s, r, val>::min_value;
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const IntType subtract_with_carry<IntType, m, s, r, val>::max_value;
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const IntType subtract_with_carry<IntType, m, s, r, val>::modulus;
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const unsigned int subtract_with_carry<IntType, m, s, r, val>::long_lag;
-template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
-const unsigned int subtract_with_carry<IntType, m, s, r, val>::short_lag;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const bool subtract_with_carry_engine<IntType, w, s, r>::has_fixed_range;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const IntType subtract_with_carry_engine<IntType, w, s, r>::modulus;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_engine<IntType, w, s, r>::word_size;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_engine<IntType, w, s, r>::long_lag;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_engine<IntType, w, s, r>::short_lag;
+template<class IntType, std::size_t w, std::size_t s, std::size_t r>
+const uint32_t subtract_with_carry_engine<IntType, w, s, r>::default_seed;
#endif
// use a floating-point representation to produce values in [0..1)
-/** @copydoc boost::random::subtract_with_carry */
-template<class RealType, int w, unsigned int s, unsigned int r, int val=0>
-class subtract_with_carry_01
+/**
+ * Instantiations of \subtract_with_carry_01_engine model a
+ * \pseudo_random_number_generator. The algorithm is
+ * described in
+ *
+ * @blockquote
+ * "A New Class of Random Number Generators", George
+ * Marsaglia and Arif Zaman, Annals of Applied Probability,
+ * Volume 1, Number 3 (1991), 462-480.
+ * @endblockquote
+ */
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+class subtract_with_carry_01_engine
{
public:
- typedef RealType result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, word_size = w);
- BOOST_STATIC_CONSTANT(unsigned int, long_lag = r);
- BOOST_STATIC_CONSTANT(unsigned int, short_lag = s);
-
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_integer);
-#endif
-
- subtract_with_carry_01() { init_modulus(); seed(); }
- explicit subtract_with_carry_01(uint32_t value)
- { init_modulus(); seed(value); }
- template<class It> subtract_with_carry_01(It& first, It last)
- { init_modulus(); seed(first,last); }
+ typedef RealType result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
+ BOOST_STATIC_CONSTANT(std::size_t, long_lag = r);
+ BOOST_STATIC_CONSTANT(std::size_t, short_lag = s);
+ BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 19780503u);
+
+ BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_integer);
+
+ /** Creates a new \subtract_with_carry_01_engine using the default seed. */
+ subtract_with_carry_01_engine() { init_modulus(); seed(); }
+ /** Creates a new subtract_with_carry_01_engine and seeds it with value. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_01_engine,
+ boost::uint32_t, value)
+ { init_modulus(); seed(value); }
+ /**
+ * Creates a new \subtract_with_carry_01_engine and seeds with with values
+ * produced by seq.generate().
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(subtract_with_carry_01_engine,
+ SeedSeq, seq)
+ { init_modulus(); seed(seq); }
+ /**
+ * Creates a new \subtract_with_carry_01_engine and seeds it with values
+ * from a range. Advances first to point one past the last consumed
+ * value. If the range does not contain enough elements to fill the
+ * entire state, throws @c std::invalid_argument.
+ */
+ template<class It> subtract_with_carry_01_engine(It& first, It last)
+ { init_modulus(); seed(first,last); }
private:
- /// \cond hide_private_members
- void init_modulus()
- {
+ /// \cond show_private
+ void init_modulus()
+ {
#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::pow;
+ // allow for Koenig lookup
+ using std::pow;
#endif
- _modulus = pow(RealType(2), word_size);
- }
- /// \endcond hide_private_members
+ _modulus = pow(RealType(2), RealType(word_size));
+ }
+ /// \endcond
public:
- // compiler-generated copy ctor and assignment operator are fine
+ // compiler-generated copy ctor and assignment operator are fine
- void seed(uint32_t value = 19780503u)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::fmod;
-#endif
- random::linear_congruential<int32_t, 40014, 0, 2147483563, 0> gen(value);
- unsigned long array[(w+31)/32 * long_lag];
- for(unsigned int j = 0; j < sizeof(array)/sizeof(unsigned long); ++j)
- array[j] = gen();
- unsigned long * start = array;
- seed(start, array + sizeof(array)/sizeof(unsigned long));
- }
-
- template<class It>
- void seed(It& first, It last)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::fmod;
- using std::pow;
-#endif
- unsigned long mask = ~((~0u) << (w%32)); // now lowest (w%32) bits set
- RealType two32 = pow(RealType(2), 32);
- unsigned int j;
- for(j = 0; j < long_lag && first != last; ++j) {
- x[j] = RealType(0);
- for(int i = 0; i < w/32 && first != last; ++i, ++first)
- x[j] += *first / pow(two32,i+1);
- if(first != last && mask != 0) {
- x[j] += fmod((*first & mask) / _modulus, RealType(1));
- ++first;
- }
- }
- if(first == last && j < long_lag)
- throw std::invalid_argument("subtract_with_carry_01::seed");
- carry = (x[long_lag-1] ? 0 : 1 / _modulus);
- k = 0;
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
-
- result_type operator()()
- {
- int short_index = k - short_lag;
- if(short_index < 0)
- short_index += long_lag;
- RealType delta = x[short_index] - x[k] - carry;
- if(delta < 0) {
- delta += RealType(1);
- carry = RealType(1)/_modulus;
- } else {
- carry = 0;
- }
- x[k] = delta;
- ++k;
- if(k >= long_lag)
- k = 0;
- return delta;
- }
-
- static bool validation(result_type x)
- { return x == val/pow(RealType(2), word_size); }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os,
- const subtract_with_carry_01& f)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- // allow for Koenig lookup
- using std::pow;
-#endif
- std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
- for(unsigned int j = 0; j < f.long_lag; ++j)
- os << (f.compute(j) * f._modulus) << " ";
- os << (f.carry * f._modulus);
- os.flags(oldflags);
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, subtract_with_carry_01& f)
- {
-# ifdef BOOST_RANDOM_EXTRACT_SWC_01
- detail::extract_subtract_with_carry_01(is, f, f.carry, f.x, f._modulus);
-# else
- // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template type
- // parameter "RealType" available from the class template scope, so use
- // the member typedef
- typename subtract_with_carry_01::result_type value;
- for(unsigned int j = 0; j < long_lag; ++j) {
- is >> value >> std::ws;
- f.x[j] = value / f._modulus;
- }
- is >> value >> std::ws;
- f.carry = value / f._modulus;
-# endif
- f.k = 0;
- return is;
- }
-#endif
+ /** Seeds the generator with the default seed. */
+ void seed() { seed(default_seed); }
- friend bool operator==(const subtract_with_carry_01& x,
- const subtract_with_carry_01& y)
- {
- for(unsigned int j = 0; j < r; ++j)
- if(x.compute(j) != y.compute(j))
- return false;
- return true;
- }
-
- friend bool operator!=(const subtract_with_carry_01& x,
- const subtract_with_carry_01& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const subtract_with_carry_01& rhs) const
- {
- for(unsigned int j = 0; j < r; ++j)
- if(compute(j) != rhs.compute(j))
- return false;
- return true;
- }
+ /** Seeds the generator with @c value. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_01_engine,
+ boost::uint32_t, value)
+ {
+ typedef linear_congruential_engine<uint32_t, 40014, 0, 2147483563> gen_t;
+ gen_t intgen(value);
+ detail::generator_seed_seq<gen_t> gen(intgen);
+ seed(gen);
+ }
- bool operator!=(const subtract_with_carry_01& rhs) const
- { return !(*this == rhs); }
-#endif
+ /** Seeds the generator with values produced by @c seq.generate(). */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(subtract_with_carry_01_engine,
+ SeedSeq, seq)
+ {
+ detail::seed_array_real<w>(seq, x);
+ carry = (x[long_lag-1] ? 0 : 1 / _modulus);
+ k = 0;
+ }
+
+ /**
+ * Seeds the generator with values from a range. Updates first to
+ * point one past the last consumed element. If there are not
+ * enough elements in the range to fill the entire state, throws
+ * @c std::invalid_argument.
+ */
+ template<class It>
+ void seed(It& first, It last)
+ {
+ detail::fill_array_real<w>(first, last, x);
+ carry = (x[long_lag-1] ? 0 : 1 / _modulus);
+ k = 0;
+ }
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return result_type(0); }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ { return result_type(1); }
+
+ /**
+ * INTERNAL ONLY
+ * Returns the number of random bits.
+ * This is not part of the standard, and I'm not sure that
+ * it's the best solution, but something like this is needed
+ * to implement generate_canonical. For now, mark it as
+ * an implementation detail.
+ */
+ static std::size_t precision() { return w; }
+
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ std::size_t short_index =
+ (k < short_lag) ?
+ (k + long_lag - short_lag) :
+ (k - short_lag);
+ carry = do_update(k, short_index, carry);
+ RealType result = x[k];
+ ++k;
+ if(k >= long_lag)
+ k = 0;
+ return result;
+ }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ { detail::subtract_with_carry_discard::apply(*this, z); }
+
+ /** Fills a range with random values. */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_real(*this, first, last); }
+
+ /** Writes a \subtract_with_carry_01_engine to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, subtract_with_carry_01_engine, f)
+ {
+ std::ios_base::fmtflags oldflags =
+ os.flags(os.dec | os.fixed | os.left);
+ for(unsigned int j = 0; j < f.long_lag; ++j)
+ os << (f.compute(j) * f._modulus) << ' ';
+ os << (f.carry * f._modulus);
+ os.flags(oldflags);
+ return os;
+ }
+
+ /** Reads a \subtract_with_carry_01_engine from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, subtract_with_carry_01_engine, f)
+ {
+ RealType value;
+ for(unsigned int j = 0; j < long_lag; ++j) {
+ is >> value >> std::ws;
+ f.x[j] = value / f._modulus;
+ }
+ is >> value;
+ f.carry = value / f._modulus;
+ f.k = 0;
+ return is;
+ }
+
+ /** Returns true if the two generators will produce identical sequences. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(subtract_with_carry_01_engine, x, y)
+ {
+ for(unsigned int j = 0; j < r; ++j)
+ if(x.compute(j) != y.compute(j))
+ return false;
+ return true;
+ }
+
+ /** Returns true if the two generators will produce different sequences. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(subtract_with_carry_01_engine)
private:
- /// \cond hide_private_members
- RealType compute(unsigned int index) const;
- /// \endcond
- unsigned int k;
- RealType carry;
- RealType x[long_lag];
- RealType _modulus;
+ /// \cond show_private
+ RealType compute(unsigned int index) const
+ {
+ return x[(k+index) % long_lag];
+ }
+
+ friend struct detail::subtract_with_carry_discard;
+
+ RealType do_update(std::size_t current, std::size_t short_index, RealType carry)
+ {
+ RealType delta = x[short_index] - x[current] - carry;
+ if(delta < 0) {
+ delta += RealType(1);
+ carry = RealType(1)/_modulus;
+ } else {
+ carry = 0;
+ }
+ x[current] = delta;
+ return carry;
+ }
+ /// \endcond
+ std::size_t k;
+ RealType carry;
+ RealType x[long_lag];
+ RealType _modulus;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class RealType, int w, unsigned int s, unsigned int r, int val>
-const bool subtract_with_carry_01<RealType, w, s, r, val>::has_fixed_range;
-template<class RealType, int w, unsigned int s, unsigned int r, int val>
-const int subtract_with_carry_01<RealType, w, s, r, val>::word_size;
-template<class RealType, int w, unsigned int s, unsigned int r, int val>
-const unsigned int subtract_with_carry_01<RealType, w, s, r, val>::long_lag;
-template<class RealType, int w, unsigned int s, unsigned int r, int val>
-const unsigned int subtract_with_carry_01<RealType, w, s, r, val>::short_lag;
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+const bool subtract_with_carry_01_engine<RealType, w, s, r>::has_fixed_range;
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::word_size;
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::long_lag;
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::short_lag;
+template<class RealType, std::size_t w, std::size_t s, std::size_t r>
+const uint32_t subtract_with_carry_01_engine<RealType, w, s, r>::default_seed;
#endif
-/// \cond hide_private_members
-template<class RealType, int w, unsigned int s, unsigned int r, int val>
-RealType subtract_with_carry_01<RealType, w, s, r, val>::compute(unsigned int index) const
+
+/// \cond show_deprecated
+
+template<class IntType, IntType m, unsigned s, unsigned r, IntType v>
+class subtract_with_carry :
+ public subtract_with_carry_engine<IntType,
+ boost::static_log2<m>::value, s, r>
{
- return x[(k+index) % long_lag];
-}
+ typedef subtract_with_carry_engine<IntType,
+ boost::static_log2<m>::value, s, r> base_type;
+public:
+ subtract_with_carry() {}
+ BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry, Gen, gen)
+ { seed(gen); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry,
+ IntType, val)
+ { seed(val); }
+ template<class It>
+ subtract_with_carry(It& first, It last) : base_type(first, last) {}
+ void seed() { base_type::seed(); }
+ BOOST_RANDOM_DETAIL_GENERATOR_SEED(subtract_with_carry, Gen, gen)
+ {
+ detail::generator_seed_seq<Gen> seq(gen);
+ base_type::seed(seq);
+ }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry, IntType, val)
+ { base_type::seed(val); }
+ template<class It>
+ void seed(It& first, It last) { base_type::seed(first, last); }
+};
+
+template<class RealType, int w, unsigned s, unsigned r, int v = 0>
+class subtract_with_carry_01 :
+ public subtract_with_carry_01_engine<RealType, w, s, r>
+{
+ typedef subtract_with_carry_01_engine<RealType, w, s, r> base_type;
+public:
+ subtract_with_carry_01() {}
+ BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry_01, Gen, gen)
+ { seed(gen); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_01,
+ uint32_t, val)
+ { seed(val); }
+ template<class It>
+ subtract_with_carry_01(It& first, It last) : base_type(first, last) {}
+ void seed() { base_type::seed(); }
+ BOOST_RANDOM_DETAIL_GENERATOR_SEED(subtract_with_carry_01, Gen, gen)
+ {
+ detail::generator_seed_seq<Gen> seq(gen);
+ base_type::seed(seq);
+ }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_01, uint32_t, val)
+ { base_type::seed(val); }
+ template<class It>
+ void seed(It& first, It last) { base_type::seed(first, last); }
+};
+
/// \endcond
} // namespace random
Modified: branches/release/boost/random/triangle_distribution.hpp
==============================================================================
--- branches/release/boost/random/triangle_distribution.hpp (original)
+++ branches/release/boost/random/triangle_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/triangle_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,11 +18,16 @@
#define BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
-#include <cassert>
+#include <iosfwd>
+#include <ios>
+#include <istream>
+#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
+namespace random {
/**
* Instantiations of @c triangle_distribution model a \random_distribution.
@@ -33,86 +39,194 @@
class triangle_distribution
{
public:
- typedef RealType input_type;
- typedef RealType result_type;
+ typedef RealType input_type;
+ typedef RealType result_type;
- /**
- * Constructs a @c triangle_distribution with the parameters
- * @c a, @c b, and @c c.
- *
- * Preconditions: a <= b <= c.
- */
- explicit triangle_distribution(result_type a_arg = result_type(0),
- result_type b_arg = result_type(0.5),
- result_type c_arg = result_type(1))
- : _a(a_arg), _b(b_arg), _c(c_arg)
- {
- assert(_a <= _b && _b <= _c);
- init();
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /** Returns the @c a parameter of the distribution */
- result_type a() const { return _a; }
- /** Returns the @c b parameter of the distribution */
- result_type b() const { return _b; }
- /** Returns the @c c parameter of the distribution */
- result_type c() const { return _c; }
-
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::sqrt;
-#endif
- result_type u = eng();
- if( u <= q1 )
- return _a + p1*sqrt(u);
- else
- return _c - d3*sqrt(d2*u-d1);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const triangle_distribution& td)
- {
- os << td._a << " " << td._b << " " << td._c;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, triangle_distribution& td)
- {
- is >> std::ws >> td._a >> std::ws >> td._b >> std::ws >> td._c;
- td.init();
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef triangle_distribution distribution_type;
+
+ /** Constructs the parameters of a @c triangle_distribution. */
+ explicit param_type(RealType a_arg = RealType(0.0),
+ RealType b_arg = RealType(0.5),
+ RealType c_arg = RealType(1.0))
+ : _a(a_arg), _b(b_arg), _c(c_arg)
+ {
+ BOOST_ASSERT(_a <= _b && _b <= _c);
+ }
+
+ /** Returns the minimum value of the distribution. */
+ RealType a() const { return _a; }
+ /** Returns the mode of the distribution. */
+ RealType b() const { return _b; }
+ /** Returns the maximum value of the distribution. */
+ RealType c() const { return _c; }
+
+ /** Writes the parameters to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._a << " " << parm._b << " " << parm._c;
+ return os;
+ }
+
+ /** Reads the parameters from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ double a_in, b_in, c_in;
+ if(is >> a_in >> std::ws >> b_in >> std::ws >> c_in) {
+ if(a_in <= b_in && b_in <= c_in) {
+ parm._a = a_in;
+ parm._b = b_in;
+ parm._c = c_in;
+ } else {
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ RealType _a;
+ RealType _b;
+ RealType _c;
+ };
+
+ /**
+ * Constructs a @c triangle_distribution with the parameters
+ * @c a, @c b, and @c c.
+ *
+ * Preconditions: a <= b <= c.
+ */
+ explicit triangle_distribution(RealType a_arg = RealType(0.0),
+ RealType b_arg = RealType(0.5),
+ RealType c_arg = RealType(1.0))
+ : _a(a_arg), _b(b_arg), _c(c_arg)
+ {
+ BOOST_ASSERT(_a <= _b && _b <= _c);
+ init();
+ }
+
+ /** Constructs a @c triangle_distribution from its parameters. */
+ explicit triangle_distribution(const param_type& parm)
+ : _a(parm.a()), _b(parm.b()), _c(parm.c())
+ {
+ init();
+ }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the @c a parameter of the distribution */
+ result_type a() const { return _a; }
+ /** Returns the @c b parameter of the distribution */
+ result_type b() const { return _b; }
+ /** Returns the @c c parameter of the distribution */
+ result_type c() const { return _c; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _a; }
+ /** Returns the largest value that the distribution can produce. */
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c; }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_a, _b, _c); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _a = parm.a();
+ _b = parm.b();
+ _c = parm.c();
+ init();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /**
+ * Returns a random variate distributed according to the
+ * triangle distribution.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng)
+ {
+ using std::sqrt;
+ result_type u = uniform_01<>()(eng);
+ if( u <= q1 )
+ return _a + p1*sqrt(u);
+ else
+ return _c - d3*sqrt(d2*u-d1);
+ }
+
+ /**
+ * Returns a random variate distributed according to the
+ * triangle distribution with parameters specified by param.
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm)
+ { return triangle_distribution(parm)(eng); }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, triangle_distribution, td)
+ {
+ os << td.param();
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, triangle_distribution, td)
+ {
+ param_type parm;
+ if(is >> parm) {
+ td.param(parm);
+ }
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(triangle_distribution, lhs, rhs)
+ { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(triangle_distribution)
private:
- /// \cond hide_private_members
- void init()
- {
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::sqrt;
-#endif
- d1 = _b - _a;
- d2 = _c - _a;
- d3 = sqrt(_c - _b);
- q1 = d1 / d2;
- p1 = sqrt(d1 * d2);
- }
- /// \endcond
+ /// \cond show_private
+ void init()
+ {
+ using std::sqrt;
+ d1 = _b - _a;
+ d2 = _c - _a;
+ d3 = sqrt(_c - _b);
+ q1 = d1 / d2;
+ p1 = sqrt(d1 * d2);
+ }
+ /// \endcond
- result_type _a, _b, _c;
- result_type d1, d2, d3, q1, p1;
+ RealType _a, _b, _c;
+ RealType d1, d2, d3, q1, p1;
};
+} // namespace random
+
+using random::triangle_distribution;
+
} // namespace boost
#endif // BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
Modified: branches/release/boost/random/uniform_01.hpp
==============================================================================
--- branches/release/boost/random/uniform_01.hpp (original)
+++ branches/release/boost/random/uniform_01.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -21,11 +21,12 @@
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
-#include <boost/random/detail/pass_through_engine.hpp>
+#include <boost/random/detail/ptr_helper.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
+namespace random {
#ifdef BOOST_RANDOM_DOXYGEN
@@ -121,7 +122,6 @@
class backward_compatible_uniform_01
{
typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
- typedef boost::random::detail::pass_through_engine<UniformRandomNumberGenerator> internal_engine_type;
public:
typedef UniformRandomNumberGenerator base_type;
typedef RealType result_type;
@@ -135,7 +135,7 @@
explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
: _rng(rng),
_factor(result_type(1) /
- (result_type((_rng.max)()-(_rng.min)()) +
+ (result_type((base().max)()-(base().min)()) +
result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
{
}
@@ -143,13 +143,13 @@
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
- typename traits::value_type& base() { return _rng.base(); }
- const typename traits::value_type& base() const { return _rng.base(); }
+ typename traits::value_type& base() { return traits::ref(_rng); }
+ const typename traits::value_type& base() const { return traits::ref(_rng); }
void reset() { }
result_type operator()() {
for (;;) {
- result_type result = result_type(_rng() - (_rng.min)()) * _factor;
+ result_type result = result_type(base()() - (base().min)()) * _factor;
if (result < result_type(1))
return result;
}
@@ -174,8 +174,8 @@
#endif
private:
- typedef typename internal_engine_type::result_type base_result;
- internal_engine_type _rng;
+ typedef typename traits::value_type::result_type base_result;
+ UniformRandomNumberGenerator _rng;
result_type _factor;
};
@@ -266,6 +266,10 @@
#endif
+} // namespace random
+
+using random::uniform_01;
+
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
Modified: branches/release/boost/random/uniform_int.hpp
==============================================================================
--- branches/release/boost/random/uniform_int.hpp (original)
+++ branches/release/boost/random/uniform_int.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,15 +17,8 @@
#ifndef BOOST_RANDOM_UNIFORM_INT_HPP
#define BOOST_RANDOM_UNIFORM_INT_HPP
-#include <cassert>
-#include <iostream>
-#include <boost/config.hpp>
-#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/random/detail/config.hpp>
-#include <boost/random/detail/signed_unsigned_tools.hpp>
-#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/assert.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
namespace boost {
@@ -35,264 +28,70 @@
* distributed in the set of integer numbers {min, min+1, min+2, ..., max}.
*
* The template parameter IntType shall denote an integer-like value type.
+ *
+ * This class is deprecated. Please use @c uniform_int_distribution in
+ * new code.
*/
template<class IntType = int>
-class uniform_int
+class uniform_int : public random::uniform_int_distribution<IntType>
{
+ typedef random::uniform_int_distribution<IntType> base_type;
public:
- typedef IntType input_type;
- typedef IntType result_type;
- /// \cond hide_private_members
- typedef typename make_unsigned<result_type>::type range_type;
- /// \endcond
-
- /**
- * Constructs a uniform_int object. @c min and @c max are
- * the parameters of the distribution.
- *
- * Requires: min <= max
- */
- explicit uniform_int(IntType min_arg = 0, IntType max_arg = 9)
- : _min(min_arg), _max(max_arg)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
- BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
-#endif
- assert(min_arg <= max_arg);
- init();
- }
-
- /**
- * Returns: The "min" parameter of the distribution
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
- /**
- * Returns: The "max" parameter of the distribution
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
- void reset() { }
-
- // can't have member function templates out-of-line due to MSVC bugs
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- return generate(eng, _min, _max, _range);
- }
-
- template<class Engine>
- result_type operator()(Engine& eng, result_type n)
- {
- assert(n > 0);
-
- if (n == 1)
- {
- return 0;
- }
-
- return generate(eng, 0, n - 1, n - 1);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int& ud)
- {
- os << ud._min << " " << ud._max;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, uniform_int& ud)
- {
- is >> std::ws >> ud._min >> std::ws >> ud._max;
- ud.init();
- return is;
- }
-#endif
-
-private:
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-// disable division by zero warning, since we can't
-// actually divide by zero.
-#pragma warning(disable:4723)
-#endif
-
- /// \cond hide_private_members
- template<class Engine>
- static result_type generate(Engine& eng, result_type min_value, result_type /*max_value*/, range_type range)
- {
- typedef typename Engine::result_type base_result;
- // ranges are always unsigned
- typedef typename make_unsigned<base_result>::type base_unsigned;
- const base_result bmin = (eng.min)();
- const base_unsigned brange =
- random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
-
- if(range == 0) {
- return min_value;
- } else if(brange == range) {
- // this will probably never happen in real life
- // basically nothing to do; just take care we don't overflow / underflow
- base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
- return random::detail::add<base_unsigned, result_type>()(v, min_value);
- } else if(brange < range) {
- // use rejection method to handle things like 0..3 --> 0..4
- for(;;) {
- // concatenate several invocations of the base RNG
- // take extra care to avoid overflows
-
- // limit == floor((range+1)/(brange+1))
- // Therefore limit*(brange+1) <= range+1
- range_type limit;
- if(range == (std::numeric_limits<range_type>::max)()) {
- limit = range/(range_type(brange)+1);
- if(range % (range_type(brange)+1) == range_type(brange))
- ++limit;
- } else {
- limit = (range+1)/(range_type(brange)+1);
- }
-
- // We consider "result" as expressed to base (brange+1):
- // For every power of (brange+1), we determine a random factor
- range_type result = range_type(0);
- range_type mult = range_type(1);
-
- // loop invariants:
- // result < mult
- // mult <= range
- while(mult <= limit) {
- // Postcondition: result <= range, thus no overflow
- //
- // limit*(brange+1)<=range+1 def. of limit (1)
- // eng()-bmin<=brange eng() post. (2)
- // and mult<=limit. loop condition (3)
- // Therefore mult*(eng()-bmin+1)<=range+1 by (1),(2),(3) (4)
- // Therefore mult*(eng()-bmin)+mult<=range+1 rearranging (4) (5)
- // result<mult loop invariant (6)
- // Therefore result+mult*(eng()-bmin)<range+1 by (5), (6) (7)
- //
- // Postcondition: result < mult*(brange+1)
- //
- // result<mult loop invariant (1)
- // eng()-bmin<=brange eng() post. (2)
- // Therefore result+mult*(eng()-bmin) <
- // mult+mult*(eng()-bmin) by (1) (3)
- // Therefore result+(eng()-bmin)*mult <
- // mult+mult*brange by (2), (3) (4)
- // Therefore result+(eng()-bmin)*mult <
- // mult*(brange+1) by (4)
- result += static_cast<range_type>(random::detail::subtract<base_result>()(eng(), bmin) * mult);
-
- // equivalent to (mult * (brange+1)) == range+1, but avoids overflow.
- if(mult * range_type(brange) == range - mult + 1) {
- // The destination range is an integer power of
- // the generator's range.
- return(result);
- }
-
- // Postcondition: mult <= range
- //
- // limit*(brange+1)<=range+1 def. of limit (1)
- // mult<=limit loop condition (2)
- // Therefore mult*(brange+1)<=range+1 by (1), (2) (3)
- // mult*(brange+1)!=range+1 preceding if (4)
- // Therefore mult*(brange+1)<range+1 by (3), (4) (5)
- //
- // Postcondition: result < mult
- //
- // See the second postcondition on the change to result.
- mult *= range_type(brange)+range_type(1);
- }
- // loop postcondition: range/mult < brange+1
- //
- // mult > limit loop condition (1)
- // Suppose range/mult >= brange+1 Assumption (2)
- // range >= mult*(brange+1) by (2) (3)
- // range+1 > mult*(brange+1) by (3) (4)
- // range+1 > (limit+1)*(brange+1) by (1), (4) (5)
- // (range+1)/(brange+1) > limit+1 by (5) (6)
- // limit < floor((range+1)/(brange+1)) by (6) (7)
- // limit==floor((range+1)/(brange+1)) def. of limit (8)
- // not (2) reductio (9)
- //
- // loop postcondition: (range/mult)*mult+(mult-1) >= range
- //
- // (range/mult)*mult + range%mult == range identity (1)
- // range%mult < mult def. of % (2)
- // (range/mult)*mult+mult > range by (1), (2) (3)
- // (range/mult)*mult+(mult-1) >= range by (3) (4)
- //
- // Note that the maximum value of result at this point is (mult-1),
- // so after this final step, we generate numbers that can be
- // at least as large as range. We have to really careful to avoid
- // overflow in this final addition and in the rejection. Anything
- // that overflows is larger than range and can thus be rejected.
-
- // range/mult < brange+1 -> no endless loop
- range_type result_increment = uniform_int<range_type>(0, range/mult)(eng);
- if((std::numeric_limits<range_type>::max)() / mult < result_increment) {
- // The multiplcation would overflow. Reject immediately.
- continue;
- }
- result_increment *= mult;
- // unsigned integers are guaranteed to wrap on overflow.
- result += result_increment;
- if(result < result_increment) {
- // The addition overflowed. Reject.
- continue;
- }
- if(result > range) {
- // Too big. Reject.
- continue;
- }
- return random::detail::add<range_type, result_type>()(result, min_value);
- }
- } else { // brange > range
- base_unsigned bucket_size;
- // it's safe to add 1 to range, as long as we cast it first,
- // because we know that it is less than brange. However,
- // we do need to be careful not to cause overflow by adding 1
- // to brange.
- if(brange == (std::numeric_limits<base_unsigned>::max)()) {
- bucket_size = brange / (static_cast<base_unsigned>(range)+1);
- if(brange % (static_cast<base_unsigned>(range)+1) == static_cast<base_unsigned>(range)) {
- ++bucket_size;
- }
- } else {
- bucket_size = (brange+1) / (static_cast<base_unsigned>(range)+1);
- }
- for(;;) {
- base_unsigned result =
- random::detail::subtract<base_result>()(eng(), bmin);
- result /= bucket_size;
- // result and range are non-negative, and result is possibly larger
- // than range, so the cast is safe
- if(result <= static_cast<base_unsigned>(range))
- return random::detail::add<base_unsigned, result_type>()(result, min_value);
- }
+ class param_type : public base_type::param_type
+ {
+ public:
+ typedef uniform_int distribution_type;
+ /**
+ * Constructs the parameters of a uniform_int distribution.
+ *
+ * Requires: min <= max
+ */
+ explicit param_type(IntType min_arg = 0, IntType max_arg = 9)
+ : base_type::param_type(min_arg, max_arg)
+ {}
+ };
+
+ /**
+ * Constructs a uniform_int object. @c min and @c max are
+ * the parameters of the distribution.
+ *
+ * Requires: min <= max
+ */
+ explicit uniform_int(IntType min_arg = 0, IntType max_arg = 9)
+ : base_type(min_arg, max_arg)
+ {}
+
+ /** Constructs a uniform_int distribution from its parameters. */
+ explicit uniform_int(const param_type& parm)
+ : base_type(parm)
+ {}
+
+ /** Returns the parameters of the distribution */
+ param_type param() const { return param_type(this->a(), this->b()); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm) { this->base_type::param(parm); }
+
+ // Codergear seems to have trouble with a using declaration here
+
+ template<class Engine>
+ IntType operator()(Engine& eng) const
+ {
+ return static_cast<const base_type&>(*this)(eng);
+ }
+
+ template<class Engine>
+ IntType operator()(Engine& eng, const param_type& parm) const
+ {
+ return static_cast<const base_type&>(*this)(eng, parm);
}
- }
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-
- void init()
- {
- _range = random::detail::subtract<result_type>()(_max, _min);
- }
-
- /// \endcond
-
- // The result_type may be signed or unsigned, but the _range is always
- // unsigned.
- result_type _min, _max;
- range_type _range;
+ template<class Engine>
+ IntType operator()(Engine& eng, IntType n) const
+ {
+ BOOST_ASSERT(n > 0);
+ return static_cast<const base_type&>(*this)(eng, param_type(0, n - 1));
+ }
};
} // namespace boost
Copied: branches/release/boost/random/uniform_int_distribution.hpp (from r68440, /trunk/boost/random/uniform_int_distribution.hpp)
==============================================================================
--- /trunk/boost/random/uniform_int_distribution.hpp (original)
+++ branches/release/boost/random/uniform_int_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -18,16 +18,15 @@
#ifndef BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
#define BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
-#include <cassert>
#include <iosfwd>
#include <ios>
#include <istream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
+#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/uniform_int_float.hpp>
-#include <boost/random/detail/pass_through_engine.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_integral.hpp>
@@ -218,8 +217,7 @@
Engine& eng, T min_value, T max_value,
boost::mpl::false_ /** is_integral<Engine::result_type> */)
{
- pass_through_engine<Engine&> ref_wrapper(eng);
- uniform_int_float<pass_through_engine<Engine&> > wrapper(ref_wrapper);
+ uniform_int_float<Engine> wrapper(eng);
return generate_uniform_int(wrapper, min_value, max_value, boost::mpl::true_());
}
@@ -263,7 +261,7 @@
IntType max_arg = (std::numeric_limits<IntType>::max)())
: _min(min_arg), _max(max_arg)
{
- assert(_min <= _max);
+ BOOST_ASSERT(_min <= _max);
}
/** Returns the minimum value of the distribution. */
@@ -317,7 +315,7 @@
IntType max_arg = (std::numeric_limits<IntType>::max)())
: _min(min_arg), _max(max_arg)
{
- assert(min_arg <= max_arg);
+ BOOST_ASSERT(min_arg <= max_arg);
}
/** Constructs a uniform_int_distribution from its parameters. */
explicit uniform_int_distribution(const param_type& parm)
Modified: branches/release/boost/random/uniform_on_sphere.hpp
==============================================================================
--- branches/release/boost/random/uniform_on_sphere.hpp (original)
+++ branches/release/boost/random/uniform_on_sphere.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/uniform_on_sphere.hpp header file
*
* Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -19,10 +20,13 @@
#include <vector>
#include <algorithm> // std::transform
#include <functional> // std::bind2nd, std::divides
+#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
#include <boost/random/normal_distribution.hpp>
namespace boost {
+namespace random {
/**
* Instantiations of class template uniform_on_sphere model a
@@ -30,72 +34,196 @@
* numbers uniformly distributed on the unit sphere of arbitrary
* dimension @c dim. The @c Cont template parameter must be a STL-like
* container type with begin and end operations returning non-const
- * ForwardIterators of type @c Cont::iterator. Each invocation of the
- * @c UniformRandomNumberGenerator shall result in a floating-point
- * value in the range [0,1).
+ * ForwardIterators of type @c Cont::iterator.
*/
template<class RealType = double, class Cont = std::vector<RealType> >
class uniform_on_sphere
{
public:
- typedef RealType input_type;
- typedef Cont result_type;
+ typedef RealType input_type;
+ typedef Cont result_type;
- /**
- * Constructs a @c uniform_on_sphere distribution.
- * @c dim is the dimension of the sphere.
- */
- explicit uniform_on_sphere(int dim = 2) : _container(dim), _dim(dim) { }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- void reset() { _normal.reset(); }
-
- template<class Engine>
- const result_type & operator()(Engine& eng)
- {
- RealType sqsum = 0;
- for(typename Cont::iterator it = _container.begin();
- it != _container.end();
- ++it) {
- RealType val = _normal(eng);
- *it = val;
- sqsum += val * val;
- }
-#ifndef BOOST_NO_STDC_NAMESPACE
- using std::sqrt;
-#endif
- // for all i: result[i] /= sqrt(sqsum)
- std::transform(_container.begin(), _container.end(), _container.begin(),
- std::bind2nd(std::divides<RealType>(), sqrt(sqsum)));
- return _container;
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_on_sphere& sd)
- {
- os << sd._dim;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, uniform_on_sphere& sd)
- {
- is >> std::ws >> sd._dim;
- sd._container.resize(sd._dim);
- return is;
- }
-#endif
+ class param_type
+ {
+ public:
+
+ typedef uniform_on_sphere distribution_type;
+
+ /**
+ * Constructs the parameters of a uniform_on_sphere
+ * distribution, given the dimension of the sphere.
+ */
+ explicit param_type(int dim_arg = 2) : _dim(dim_arg)
+ {
+ BOOST_ASSERT(_dim >= 0);
+ }
+
+ /** Returns the dimension of the sphere. */
+ int dim() const { return _dim; }
+
+ /** Writes the parameters to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._dim;
+ return os;
+ }
+
+ /** Reads the parameters from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._dim;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._dim == rhs._dim; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ int _dim;
+ };
+
+ /**
+ * Constructs a @c uniform_on_sphere distribution.
+ * @c dim is the dimension of the sphere.
+ *
+ * Requires: dim >= 0
+ */
+ explicit uniform_on_sphere(int dim_arg = 2)
+ : _container(dim_arg), _dim(dim_arg) { }
+
+ /**
+ * Constructs a @c uniform_on_sphere distribution from its parameters.
+ */
+ explicit uniform_on_sphere(const param_type& parm)
+ : _container(parm.dim()), _dim(parm.dim()) { }
+
+ // compiler-generated copy ctor and assignment operator are fine
+
+ /** Returns the dimension of the sphere. */
+ int dim() const { return _dim; }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_dim); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _dim = parm.dim();
+ _container.resize(_dim);
+ }
+
+ /**
+ * Returns the smallest value that the distribution can produce.
+ * Note that this is required to approximate the standard library's
+ * requirements. The behavior is defined according to lexicographical
+ * comparison so that for a container type of std::vector,
+ * dist.min() <= x <= dist.max() where x is any value produced
+ * by the distribution.
+ */
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ {
+ result_type result(_dim);
+ if(_dim != 0) {
+ result.front() = RealType(-1.0);
+ }
+ return result;
+ }
+ /**
+ * Returns the largest value that the distribution can produce.
+ * Note that this is required to approximate the standard library's
+ * requirements. The behavior is defined according to lexicographical
+ * comparison so that for a container type of std::vector,
+ * dist.min() <= x <= dist.max() where x is any value produced
+ * by the distribution.
+ */
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ {
+ result_type result(_dim);
+ if(_dim != 0) {
+ result.front() = RealType(1.0);
+ }
+ return result;
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { _normal.reset(); }
+
+ /**
+ * Returns a point uniformly distributed over the surface of
+ * a sphere of dimension dim().
+ */
+ template<class Engine>
+ const result_type & operator()(Engine& eng)
+ {
+ RealType sqsum = 0;
+ for(typename Cont::iterator it = _container.begin();
+ it != _container.end();
+ ++it) {
+ RealType val = _normal(eng);
+ *it = val;
+ sqsum += val * val;
+ }
+ using std::sqrt;
+ // for all i: result[i] /= sqrt(sqsum)
+ std::transform(_container.begin(), _container.end(), _container.begin(),
+ std::bind2nd(std::divides<RealType>(), sqrt(sqsum)));
+ return _container;
+ }
+
+ /**
+ * Returns a point uniformly distributed over the surface of
+ * a sphere of dimension param.dim().
+ */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm) const
+ {
+ return uniform_on_sphere(parm)(eng);
+ }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_on_sphere, sd)
+ {
+ os << sd._dim;
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_on_sphere, sd)
+ {
+ is >> sd._dim;
+ sd._container.resize(sd._dim);
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values, given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_on_sphere, lhs, rhs)
+ { return lhs._dim == rhs._dim && lhs._normal == rhs._normal; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values, given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_on_sphere)
private:
- normal_distribution<RealType> _normal;
- result_type _container;
- int _dim;
+ normal_distribution<RealType> _normal;
+ result_type _container;
+ int _dim;
};
+} // namespace random
+
+using random::uniform_on_sphere;
+
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
Modified: branches/release/boost/random/uniform_real.hpp
==============================================================================
--- branches/release/boost/random/uniform_real.hpp (original)
+++ branches/release/boost/random/uniform_real.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,90 +17,64 @@
#ifndef BOOST_RANDOM_UNIFORM_REAL_HPP
#define BOOST_RANDOM_UNIFORM_REAL_HPP
-#include <cassert>
-#include <iostream>
+#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/random/detail/config.hpp>
+#include <boost/random/uniform_real_distribution.hpp>
namespace boost {
/**
* The distribution function uniform_real models a random distribution.
* On each invocation, it returns a random floating-point value uniformly
- * distributed in the range [min..max). The value is computed using
- * std::numeric_limits<RealType>::digits random binary digits, i.e.
- * the mantissa of the floating-point value is completely filled with
- * random bits.
+ * distributed in the range [min..max).
*
- * Note: The current implementation is buggy, because it may not fill
- * all of the mantissa with random bits.
+ * This class is deprecated. Please use @c uniform_real_distribution in
+ * new code.
*/
template<class RealType = double>
-class uniform_real
+class uniform_real : public random::uniform_real_distribution<RealType>
{
+ typedef random::uniform_real_distribution<RealType> base_type;
public:
- typedef RealType input_type;
- typedef RealType result_type;
- /**
- * Constructs a uniform_real object. @c min and @c max are the
- * parameters of the distribution.
- *
- * Requires: min <= max
- */
- explicit uniform_real(RealType min_arg = RealType(0),
- RealType max_arg = RealType(1))
- : _min(min_arg), _max(max_arg)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
-#endif
- assert(min_arg <= max_arg);
- }
-
- // compiler-generated copy ctor and assignment operator are fine
-
- /**
- * Returns: The "min" parameter of the distribution
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
- /**
- * Returns: The "max" parameter of the distribution
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng) {
- result_type numerator = static_cast<result_type>(eng() - eng.min BOOST_PREVENT_MACRO_SUBSTITUTION());
- result_type divisor = static_cast<result_type>(eng.max BOOST_PREVENT_MACRO_SUBSTITUTION() - eng.min BOOST_PREVENT_MACRO_SUBSTITUTION());
- assert(divisor > 0);
- assert(numerator >= 0 && numerator <= divisor);
- return numerator / divisor * (_max - _min) + _min;
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_real& ud)
- {
- os << ud._min << " " << ud._max;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, uniform_real& ud)
- {
- is >> std::ws >> ud._min >> std::ws >> ud._max;
- return is;
- }
-#endif
-
-private:
- RealType _min, _max;
+ class param_type : public base_type::param_type
+ {
+ public:
+ typedef uniform_real distribution_type;
+ /**
+ * Constructs the parameters of a uniform_real distribution.
+ *
+ * Requires: min <= max
+ */
+ explicit param_type(RealType min_arg = RealType(0.0),
+ RealType max_arg = RealType(1.0))
+ : base_type::param_type(min_arg, max_arg)
+ {}
+ };
+
+ /**
+ * Constructs a uniform_real object. @c min and @c max are the
+ * parameters of the distribution.
+ *
+ * Requires: min <= max
+ */
+ explicit uniform_real(RealType min_arg = RealType(0.0),
+ RealType max_arg = RealType(1.0))
+ : base_type(min_arg, max_arg)
+ {
+ BOOST_ASSERT(min_arg <= max_arg);
+ }
+
+ /** Constructs a uniform_real distribution from its parameters. */
+ explicit uniform_real(const param_type& parm)
+ : base_type(parm)
+ {}
+
+ /** Returns the parameters of the distribution */
+ param_type param() const { return param_type(this->a(), this->b()); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm) { this->base_type::param(parm); }
};
} // namespace boost
Copied: branches/release/boost/random/uniform_real_distribution.hpp (from r68444, /trunk/boost/random/uniform_real_distribution.hpp)
==============================================================================
--- /trunk/boost/random/uniform_real_distribution.hpp (original)
+++ branches/release/boost/random/uniform_real_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -15,10 +15,10 @@
#ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
-#include <cassert>
#include <iosfwd>
#include <ios>
#include <istream>
+#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
@@ -39,8 +39,8 @@
typedef typename Engine::result_type base_result;
result_type numerator = static_cast<T>(eng() - (eng.min)());
result_type divisor = static_cast<T>((eng.max)() - (eng.min)());
- assert(divisor > 0);
- assert(numerator >= 0 && numerator <= divisor);
+ BOOST_ASSERT(divisor > 0);
+ BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
T result = numerator / divisor * (max_value - min_value) + min_value;
if(result < max_value) return result;
}
@@ -56,8 +56,8 @@
typedef typename Engine::result_type base_result;
result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)()));
result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1;
- assert(divisor > 0);
- assert(numerator >= 0 && numerator <= divisor);
+ BOOST_ASSERT(divisor > 0);
+ BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
T result = numerator / divisor * (max_value - min_value) + min_value;
if(result < max_value) return result;
}
@@ -100,7 +100,7 @@
RealType max_arg = RealType(1.0))
: _min(min_arg), _max(max_arg)
{
- assert(_min <= _max);
+ BOOST_ASSERT(_min <= _max);
}
/** Returns the minimum value of the distribution. */
@@ -154,7 +154,7 @@
RealType max_arg = RealType(1.0))
: _min(min_arg), _max(max_arg)
{
- assert(min_arg <= max_arg);
+ BOOST_ASSERT(min_arg <= max_arg);
}
/** Constructs a uniform_real_distribution from its parameters. */
explicit uniform_real_distribution(const param_type& parm)
Modified: branches/release/boost/random/uniform_smallint.hpp
==============================================================================
--- branches/release/boost/random/uniform_smallint.hpp (original)
+++ branches/release/boost/random/uniform_smallint.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,16 +17,20 @@
#ifndef BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#define BOOST_RANDOM_UNIFORM_SMALLINT_HPP
-#include <cassert>
-#include <iostream>
+#include <istream>
+#include <iosfwd>
+#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include <boost/random/detail/config.hpp>
+#include <boost/random/detail/operators.hpp>
+#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/detail/workaround.hpp>
namespace boost {
+namespace random {
// uniform integer distribution on a small range [min, max]
@@ -38,121 +42,247 @@
* underlying source of random numbers and thus makes no attempt to limit
* quantization errors.
*
- * Let r<sub>out</sub>=(max-min+1) the desired range of integer numbers, and
- * let r<sub>base</sub> be the range of the underlying source of random
+ * Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of
+ * integer numbers, and
+ * let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random
* numbers. Then, for the uniform distribution, the theoretical probability
- * for any number i in the range r<sub>out</sub> will be p<sub>out</sub>(i) =
- * 1/r<sub>out</sub>. Likewise, assume a uniform distribution on r<sub>base</sub> for
- * the underlying source of random numbers, i.e. p<sub>base</sub>(i) =
- * 1/r<sub>base</sub>. Let p<sub>out_s</sub>(i) denote the random
+ * for any number i in the range \f$r_{\mathtt{out}}\f$ will be
+ * \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$.
+ * Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for
+ * the underlying source of random numbers, i.e.
+ * \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$.
+ * Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random
* distribution generated by @c uniform_smallint. Then the sum over all
- * i in r<sub>out</sub> of (p<sub>out_s</sub>(i)/p<sub>out</sub>(i) - 1)<sup>2</sup>
- * shall not exceed r<sub>out</sub>/r<sub>base</sub><sup>2</sup>
- * (r<sub>base</sub> mod r<sub>out</sub>)(r<sub>out</sub> -
- * r<sub>base</sub> mod r<sub>out</sub>).
+ * i in \f$r_{\mathtt{out}}\f$ of
+ * \f$\displaystyle
+ * \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$
+ * shall not exceed
+ * \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2}
+ * (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
+ * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$.
*
* The template parameter IntType shall denote an integer-like value type.
*
- * Note: The property above is the square sum of the relative differences
+ * @xmlnote
+ * The property above is the square sum of the relative differences
* in probabilities between the desired uniform distribution
- * p<sub>out</sub>(i) and the generated distribution p<sub>out_s</sub>(i).
+ * \f$p_{\mathtt{out}}(i)\f$ and the generated distribution
+ * \f$p_{\mathtt{out\_s}}(i)\f$.
* The property can be fulfilled with the calculation
- * (base_rng mod r<sub>out</sub>), as follows: Let r = r<sub>base</sub> mod
- * r<sub>out</sub>. The base distribution on r<sub>base</sub> is folded onto the
- * range r<sub>out</sub>. The numbers i < r have assigned (r<sub>base</sub>
- * div r<sub>out</sub>)+1 numbers of the base distribution, the rest has
- * only (r<sub>base</sub> div r<sub>out</sub>). Therefore,
- * p<sub>out_s</sub>(i) = ((r<sub>base</sub> div r<sub>out</sub>)+1) /
- * r<sub>base</sub> for i < r and p<sub>out_s</sub>(i) = (r<sub>base</sub>
- * div r<sub>out</sub>)/r<sub>base</sub> otherwise. Substituting this in the
+ * \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows:
+ * Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$.
+ * The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the
+ * range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned
+ * \f$\displaystyle
+ * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$
+ * numbers of the base distribution, the rest has only \f$\displaystyle
+ * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$.
+ * Therefore,
+ * \f$\displaystyle p_{\mathtt{out\_s}}(i) =
+ * \left(\left\lfloor\frac{r_{\mathtt{base}}}
+ * {r_{\mathtt{out}}}\right\rfloor+1\right) /
+ * r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) =
+ * \left\lfloor\frac{r_{\mathtt{base}}}
+ * {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise.
+ * Substituting this in the
* above sum formula leads to the desired result.
+ * @endxmlnote
*
- * Note: The upper bound for (r<sub>base</sub> mod r<sub>out</sub>)
- * (r<sub>out</sub> - r<sub>base</sub> mod r<sub>out</sub>) is
- * r<sub>out</sub><sup>2</sup>/4. Regarding the upper bound for the
- * square sum of the relative quantization error of
- * r<sub>out</sub><sup>3</sup>/(4*r<sub>base</sub><sup>2</sup>), it
- * seems wise to either choose r<sub>base</sub> so that r<sub>base</sub> >
- * 10*r<sub>out</sub><sup>2</sup> or ensure that r<sub>base</sub> is
- * divisible by r<sub>out</sub>.
+ * Note: The upper bound for
+ * \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
+ * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is
+ * \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$. Regarding the upper bound
+ * for the square sum of the relative quantization error of
+ * \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it
+ * seems wise to either choose \f$r_{\mathtt{base}}\f$ so that
+ * \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that
+ * \f$r_{\mathtt{base}}\f$ is
+ * divisible by \f$r_{\mathtt{out}}\f$.
*/
template<class IntType = int>
class uniform_smallint
{
public:
- typedef IntType input_type;
- typedef IntType result_type;
+ typedef IntType input_type;
+ typedef IntType result_type;
- /**
- * Constructs a @c uniform_smallint. @c min and @c max are the
- * lower and upper bounds of the output range, respectively.
- */
- explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
- : _min(min_arg), _max(max_arg)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
- BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
-#endif
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
- void reset() { }
-
- template<class Engine>
- result_type operator()(Engine& eng)
- {
- typedef typename Engine::result_type base_result;
- base_result _range = static_cast<base_result>(_max-_min)+1;
- base_result _factor = 1;
+ class param_type
+ {
+ public:
+
+ typedef uniform_smallint distribution_type;
+
+ /** constructs the parameters of a @c uniform_smallint distribution. */
+ param_type(IntType min_arg = 0, IntType max_arg = 9)
+ : _min(min_arg), _max(max_arg)
+ {
+ BOOST_ASSERT(_min <= _max);
+ }
+
+ /** Returns the minimum value. */
+ IntType a() const { return _min; }
+ /** Returns the maximum value. */
+ IntType b() const { return _max; }
+
+
+ /** Writes the parameters to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+ {
+ os << parm._min << " " << parm._max;
+ return os;
+ }
- // LCGs get bad when only taking the low bits.
- // (probably put this logic into a partial template specialization)
- // Check how many low bits we can ignore before we get too much
- // quantization error.
- base_result r_base = (eng.max)() - (eng.min)();
- if(r_base == (std::numeric_limits<base_result>::max)()) {
- _factor = 2;
- r_base /= 2;
- }
- r_base += 1;
- if(r_base % _range == 0) {
- // No quantization effects, good
- _factor = r_base / _range;
- } else {
- // carefully avoid overflow; pessimizing here
- for( ; r_base/_range/32 >= _range; _factor *= 2)
- r_base /= 2;
- }
-
- return static_cast<result_type>(((eng() - (eng.min)()) / _factor) % _range + _min);
- }
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_smallint& ud)
- {
- os << ud._min << " " << ud._max;
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, uniform_smallint& ud)
- {
- is >> std::ws >> ud._min >> std::ws >> ud._max;
- return is;
- }
-#endif
+ /** Reads the parameters from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+ {
+ is >> parm._min >> std::ws >> parm._max;
+ return is;
+ }
+
+ /** Returns true if the two sets of parameters are equal. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+ { return lhs._min == rhs._min && lhs._max == rhs._max; }
+
+ /** Returns true if the two sets of parameters are different. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+ private:
+ IntType _min;
+ IntType _max;
+ };
+
+ /**
+ * Constructs a @c uniform_smallint. @c min and @c max are the
+ * lower and upper bounds of the output range, respectively.
+ */
+ explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
+ : _min(min_arg), _max(max_arg) {}
+
+ /**
+ * Constructs a @c uniform_smallint from its parameters.
+ */
+ explicit uniform_smallint(const param_type& parm)
+ : _min(parm.a()), _max(parm.b()) {}
+
+ /** Returns the minimum value of the distribution. */
+ result_type a() const { return _min; }
+ /** Returns the maximum value of the distribution. */
+ result_type b() const { return _max; }
+ /** Returns the minimum value of the distribution. */
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
+ /** Returns the maximum value of the distribution. */
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_min, _max); }
+ /** Sets the parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _min = parm.a();
+ _max = parm.b();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+ /** Returns a value uniformly distributed in the range [min(), max()]. */
+ template<class Engine>
+ result_type operator()(Engine& eng) const
+ {
+ typedef typename Engine::result_type base_result;
+ return generate(eng, boost::is_integral<base_result>());
+ }
+
+ /** Returns a value uniformly distributed in the range [param.a(), param.b()]. */
+ template<class Engine>
+ result_type operator()(Engine& eng, const param_type& parm) const
+ { return uniform_smallint(parm)(eng); }
+
+ /** Writes the distribution to a @c std::ostream. */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud)
+ {
+ os << ud._min << " " << ud._max;
+ return os;
+ }
+
+ /** Reads the distribution from a @c std::istream. */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud)
+ {
+ is >> ud._min >> std::ws >> ud._max;
+ return is;
+ }
+
+ /**
+ * Returns true if the two distributions will produce identical
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs)
+ { return lhs._min == rhs._min && lhs._max == rhs._max; }
+
+ /**
+ * Returns true if the two distributions may produce different
+ * sequences of values given equal generators.
+ */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint)
private:
+
+ // \cond show_private
+ template<class Engine>
+ result_type generate(Engine& eng, boost::mpl::true_) const
+ {
+ // equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min,
+ // but guarantees no overflow.
+ typedef typename Engine::result_type base_result;
+ typedef typename boost::make_unsigned<base_result>::type base_unsigned;
+ typedef typename boost::make_unsigned<result_type>::type range_type;
+ range_type range = random::detail::subtract<result_type>()(_max, _min);
+ base_unsigned base_range =
+ random::detail::subtract<result_type>()((eng.max)(), (eng.min)());
+ base_unsigned val =
+ random::detail::subtract<base_result>()(eng(), (eng.min)());
+ if(range >= base_range) {
+ return boost::random::detail::add<range_type, result_type>()(
+ static_cast<range_type>(val), _min);
+ } else {
+ base_unsigned modulus = static_cast<base_unsigned>(range) + 1;
+ return boost::random::detail::add<range_type, result_type>()(
+ static_cast<range_type>(val % modulus), _min);
+ }
+ }
+
+ template<class Engine>
+ result_type generate(Engine& eng, boost::mpl::false_) const
+ {
+ typedef typename Engine::result_type base_result;
+ typedef typename boost::make_unsigned<result_type>::type range_type;
+ range_type range = random::detail::subtract<result_type>()(_max, _min);
+ base_result val = boost::uniform_01<base_result>()(eng);
+ // what is the worst that can possibly happen here?
+ // base_result may not be able to represent all the values in [0, range]
+ // exactly. If this happens, it will cause round off error and we
+ // won't be able to produce all the values in the range. We don't
+ // care about this because the user has already told us not to by
+ // using uniform_smallint. However, we do need to be careful
+ // to clamp the result, or floating point rounding can produce
+ // an out of range result.
+ range_type offset = static_cast<range_type>(val * (static_cast<base_result>(range) + 1));
+ if(offset > range) return _max;
+ return boost::random::detail::add<range_type, result_type>()(offset , _min);
+ }
+ // \endcond
- result_type _min;
- result_type _max;
+ result_type _min;
+ result_type _max;
};
+} // namespace random
+
+using random::uniform_smallint;
+
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP
Modified: branches/release/boost/random/variate_generator.hpp
==============================================================================
--- branches/release/boost/random/variate_generator.hpp (original)
+++ branches/release/boost/random/variate_generator.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,6 +1,7 @@
/* boost random/variate_generator.hpp header file
*
* Copyright Jens Maurer 2002
+ * 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)
@@ -14,21 +15,8 @@
#ifndef BOOST_RANDOM_RANDOM_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_GENERATOR_HPP
-#include <boost/config.hpp>
-
-// implementation details
-#include <boost/detail/workaround.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/detail/pass_through_engine.hpp>
-#include <boost/random/detail/uniform_int_float.hpp>
#include <boost/random/detail/ptr_helper.hpp>
-// Borland C++ 5.6.0 has problems using its numeric_limits traits as
-// template parameters
-#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564)
-#include <boost/type_traits/is_integral.hpp>
-#endif
-
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
@@ -36,54 +24,6 @@
/// \cond hide_private_members
namespace random {
-namespace detail {
-
-template<bool have_int, bool want_int>
-struct engine_helper;
-
-// for consistency, always have two levels of decorations
-template<>
-struct engine_helper<true, true>
-{
- template<class Engine, class DistInputType>
- struct impl
- {
- typedef pass_through_engine<Engine> type;
- };
-};
-
-template<>
-struct engine_helper<false, false>
-{
- template<class Engine, class DistInputType>
- struct impl
- {
- typedef uniform_01<Engine, DistInputType> type;
- };
-};
-
-template<>
-struct engine_helper<true, false>
-{
- template<class Engine, class DistInputType>
- struct impl
- {
- typedef uniform_01<Engine, DistInputType> type;
- };
-};
-
-template<>
-struct engine_helper<false, true>
-{
- template<class Engine, class DistInputType>
- struct impl
- {
- typedef uniform_int_float<Engine, unsigned long> type;
- };
-};
-
-} // namespace detail
-} // namespace random
///\endcond
@@ -93,9 +33,6 @@
* Boost.Random provides a vast choice of \generators as well
* as \distributions.
*
- * Instantations of class template @c variate_generator model
- * a \number_generator.
- *
* The argument for the template parameter Engine shall be of
* the form U, U&, or U*, where U models a
* \uniform_random_number_generator. Then, the member
@@ -114,107 +51,72 @@
class variate_generator
{
private:
- typedef random::detail::pass_through_engine<Engine> decorated_engine;
-
+ typedef boost::random::detail::ptr_helper<Engine> helper_type;
public:
- typedef typename decorated_engine::base_type engine_value_type;
- typedef Engine engine_type;
- typedef Distribution distribution_type;
- typedef typename Distribution::result_type result_type;
-
- /**
- * Constructs a @c variate_generator object with the associated
- * \uniform_random_number_generator eng and the associated
- * \random_distribution d.
- *
- * Throws: If and what the copy constructor of Engine or
- * Distribution throws.
- */
- variate_generator(Engine e, Distribution d)
- : _eng(decorated_engine(e)), _dist(d) { }
-
- /**
- * Returns: distribution()(e)
- *
- * Notes: The sequence of numbers produced by the
- * \uniform_random_number_generator e, s<sub>e</sub>, is
- * obtained from the sequence of numbers produced by the
- * associated \uniform_random_number_generator eng, s<sub>eng</sub>,
- * as follows: Consider the values of @c numeric_limits<T>::is_integer
- * for @c T both @c Distribution::input_type and
- * @c engine_value_type::result_type. If the values for both types are
- * true, then se is identical to s<sub>eng</sub>. Otherwise, if the
- * values for both types are false, then the numbers in s<sub>eng</sub>
- * are divided by engine().max()-engine().min() to obtain the numbers
- * in s<sub>e</sub>. Otherwise, if the value for
- * @c engine_value_type::result_type is true and the value for
- * @c Distribution::input_type is false, then the numbers in s<sub>eng</sub>
- * are divided by engine().max()-engine().min()+1 to obtain the numbers in
- * s<sub>e</sub>. Otherwise, the mapping from s<sub>eng</sub> to
- * s<sub>e</sub> is implementation-defined. In all cases, an
- * implicit conversion from @c engine_value_type::result_type to
- * @c Distribution::input_type is performed. If such a conversion does
- * not exist, the program is ill-formed.
- */
- result_type operator()() { return _dist(_eng); }
- /**
- * Returns: distribution()(e, value).
- * For the semantics of e, see the description of operator()().
- */
- template<class T>
- result_type operator()(T value) { return _dist(_eng, value); }
-
- /**
- * Returns: A reference to the associated uniform random number generator.
- */
- engine_value_type& engine() { return _eng.base().base(); }
- /**
- * Returns: A reference to the associated uniform random number generator.
- */
- const engine_value_type& engine() const { return _eng.base().base(); }
-
- /**
- * Returns: A reference to the associated random distribution.
- */
- distribution_type& distribution() { return _dist; }
- /**
- * Returns: A reference to the associated random distribution.
- */
- const distribution_type& distribution() const { return _dist; }
-
- /**
- * Precondition: distribution().min() is well-formed
- *
- * Returns: distribution().min()
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().min)(); }
- /**
- * Precondition: distribution().max() is well-formed
- *
- * Returns: distribution().max()
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().max)(); }
+ typedef typename helper_type::value_type engine_value_type;
+ typedef Engine engine_type;
+ typedef Distribution distribution_type;
+ typedef typename Distribution::result_type result_type;
+
+ /**
+ * Constructs a @c variate_generator object with the associated
+ * \uniform_random_number_generator eng and the associated
+ * \random_distribution d.
+ *
+ * Throws: If and what the copy constructor of Engine or
+ * Distribution throws.
+ */
+ variate_generator(Engine e, Distribution d)
+ : _eng(e), _dist(d) { }
+
+ /** Returns: distribution()(engine()) */
+ result_type operator()() { return _dist(engine()); }
+ /**
+ * Returns: distribution()(engine(), value).
+ */
+ template<class T>
+ result_type operator()(const T& value) { return _dist(engine(), value); }
+
+ /**
+ * Returns: A reference to the associated uniform random number generator.
+ */
+ engine_value_type& engine() { return helper_type::ref(_eng); }
+ /**
+ * Returns: A reference to the associated uniform random number generator.
+ */
+ const engine_value_type& engine() const { return helper_type::ref(_eng); }
+
+ /** Returns: A reference to the associated \random_distribution. */
+ distribution_type& distribution() { return _dist; }
+ /**
+ * Returns: A reference to the associated random distribution.
+ */
+ const distribution_type& distribution() const { return _dist; }
+
+ /**
+ * Precondition: distribution().min() is well-formed
+ *
+ * Returns: distribution().min()
+ */
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().min)(); }
+ /**
+ * Precondition: distribution().max() is well-formed
+ *
+ * Returns: distribution().max()
+ */
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().max)(); }
private:
-#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564)
- typedef typename random::detail::engine_helper<
- ::boost::is_integral<typename decorated_engine::result_type>::value,
- ::boost::is_integral<typename Distribution::input_type>::value
- >::BOOST_NESTED_TEMPLATE impl<decorated_engine, typename Distribution::input_type>::type internal_engine_type;
-#else
- enum {
- have_int = std::numeric_limits<typename decorated_engine::result_type>::is_integer,
- want_int = std::numeric_limits<typename Distribution::input_type>::is_integer
- };
- typedef typename random::detail::engine_helper<have_int, want_int>::BOOST_NESTED_TEMPLATE impl<decorated_engine, typename Distribution::input_type>::type internal_engine_type;
-#endif
-
- internal_engine_type _eng;
- distribution_type _dist;
+ Engine _eng;
+ distribution_type _dist;
};
+} // namespace random
+
+using random::variate_generator;
+
} // namespace boost
-#include <boost/random/detail/disable_warnings.hpp>
+#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_RANDOM_GENERATOR_HPP
Copied: branches/release/boost/random/weibull_distribution.hpp (from r63328, /trunk/boost/random/weibull_distribution.hpp)
==============================================================================
--- /trunk/boost/random/weibull_distribution.hpp (original)
+++ branches/release/boost/random/weibull_distribution.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -83,7 +83,7 @@
explicit weibull_distribution(RealType a_arg = 1.0, RealType b_arg = 1.0)
: _a(a_arg), _b(b_arg)
{}
- /** Constructs a @c weilbull_distribution from its parameters. */
+ /** Constructs a @c weibull_distribution from its parameters. */
explicit weibull_distribution(const param_type& parm)
: _a(parm.a()), _b(parm.b())
{}
@@ -102,7 +102,7 @@
/**
* Returns a random variate distributed accordint to the Weibull
- * distribution with parameters specified by @c parm.
+ * distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
@@ -116,9 +116,9 @@
RealType b() const { return _b; }
/** Returns the smallest value that the distribution can produce. */
- RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+ RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/** Returns the largest value that the distribution can produce. */
- RealType max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
@@ -130,6 +130,12 @@
_b = parm.b();
}
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
/** Writes a @c weibull_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, weibull_distribution, wd)
{
Modified: branches/release/boost/random/xor_combine.hpp
==============================================================================
--- branches/release/boost/random/xor_combine.hpp (original)
+++ branches/release/boost/random/xor_combine.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,169 +14,192 @@
#ifndef BOOST_RANDOM_XOR_COMBINE_HPP
#define BOOST_RANDOM_XOR_COMBINE_HPP
-#include <iostream>
+#include <istream>
+#include <iosfwd>
#include <cassert>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/limits.hpp>
-#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp> // uint32_t
#include <boost/random/detail/config.hpp>
-
+#include <boost/random/detail/seed.hpp>
+#include <boost/random/detail/seed_impl.hpp>
namespace boost {
namespace random {
-/// \cond hide_private_members
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- #define BOOST_RANDOM_VAL_TYPE typename URNG1::result_type
-#else
- #define BOOST_RANDOM_VAL_TYPE uint32_t
-#endif
-/// \endcond
-
/**
- * Instantiations of @c xor_combine model a \pseudo_random_number_generator.
- * To produce its output it invokes each of the base generators, shifts
- * their results and xors them together.
+ * Instantiations of @c xor_combine_engine model a
+ * \pseudo_random_number_generator. To produce its output it
+ * invokes each of the base generators, shifts their results
+ * and xors them together.
*/
-template<class URNG1, int s1, class URNG2, int s2
-#ifndef BOOST_RANDOM_DOXYGEN
-, BOOST_RANDOM_VAL_TYPE val = 0
-#endif
->
-class xor_combine
+template<class URNG1, int s1, class URNG2, int s2>
+class xor_combine_engine
{
public:
- typedef URNG1 base1_type;
- typedef URNG2 base2_type;
- typedef typename base1_type::result_type result_type;
-
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- BOOST_STATIC_CONSTANT(int, shift1 = s1);
- BOOST_STATIC_CONSTANT(int, shift2 = s2);
-
- /**
- * Constructors a @c xor_combine by default constructing
- * both base generators.
- */
- xor_combine() : _rng1(), _rng2()
- { }
- /**
- * Constructs a @c xor_combine by copying two base generators.
- */
- xor_combine(const base1_type & rng1, const base2_type & rng2)
- : _rng1(rng1), _rng2(rng2) { }
- /**
- * Constructs a @c xor_combine, seeding both base generators
- * with @c v.
- */
- xor_combine(const result_type & v)
- : _rng1(v), _rng2(v) { }
- /**
- * Constructs a @c xor_combine, seeding both base generators
- * with values from the iterator range [first, last) and changes
- * first to point to the element after the last one used. If there
- * are not enough elements in the range to seed both generators,
- * throws @c std::invalid_argument.
- */
- template<class It> xor_combine(It& first, It last)
- : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
- /**
- * Calls @c seed() for both base generators.
- */
- void seed() { _rng1.seed(); _rng2.seed(); }
- /**
- * @c seeds both base generators with @c v.
- */
- void seed(const result_type & v) { _rng1.seed(v); _rng2.seed(v); }
- /**
- * seeds both base generators with values from the iterator
- * range [first, last) and changes first to point to the element
- * after the last one used. If there are not enough elements in
- * the range to seed both generators, throws @c std::invalid_argument.
- */
- template<class It> void seed(It& first, It last)
- {
- _rng1.seed(first, last);
- _rng2.seed(first, last);
- }
-
- /** Returns the first base generator. */
- const base1_type& base1() { return _rng1; }
- /** Returns the second base generator. */
- const base2_type& base2() { return _rng2; }
-
- /** Returns the next value of the generator. */
- result_type operator()()
- {
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base2_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::digits >= std::numeric_limits<typename base2_type::result_type>::digits);
-#endif
- return (_rng1() << s1) ^ (_rng2() << s2);
- }
-
- /**
- * Returns the smallest value that the generator can produce.
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::min BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.min)()); }
- /**
- * Returns the largest value that the generator can produce.
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::max BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.max)()); }
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const xor_combine& s)
- {
- os << s._rng1 << " " << s._rng2 << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, xor_combine& s)
- {
- is >> s._rng1 >> std::ws >> s._rng2 >> std::ws;
- return is;
- }
-#endif
-
- friend bool operator==(const xor_combine& x, const xor_combine& y)
- { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
- friend bool operator!=(const xor_combine& x, const xor_combine& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const xor_combine& rhs) const
- { return _rng1 == rhs._rng1 && _rng2 == rhs._rng2; }
- bool operator!=(const xor_combine& rhs) const
- { return !(*this == rhs); }
-#endif
+ typedef URNG1 base1_type;
+ typedef URNG2 base2_type;
+ typedef typename base1_type::result_type result_type;
+
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+ BOOST_STATIC_CONSTANT(int, shift1 = s1);
+ BOOST_STATIC_CONSTANT(int, shift2 = s2);
+
+ /**
+ * Constructors a @c xor_combine_engine by default constructing
+ * both base generators.
+ */
+ xor_combine_engine() : _rng1(), _rng2() { }
+
+ /** Constructs a @c xor_combine by copying two base generators. */
+ xor_combine_engine(const base1_type & rng1, const base2_type & rng2)
+ : _rng1(rng1), _rng2(rng2) { }
+
+ /**
+ * Constructs a @c xor_combine_engine, seeding both base generators
+ * with @c v.
+ *
+ * @xmlwarning
+ * The exact algorithm used by this function may change in the future.
+ * @endxmlwarning
+ */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine,
+ result_type, v)
+ { seed(v); }
+
+ /**
+ * Constructs a @c xor_combine_engine, seeding both base generators
+ * with values produced by @c seq.
+ */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine,
+ SeedSeq, seq)
+ { seed(seq); }
+
+ /**
+ * Constructs a @c xor_combine_engine, seeding both base generators
+ * with values from the iterator range [first, last) and changes
+ * first to point to the element after the last one used. If there
+ * are not enough elements in the range to seed both generators,
+ * throws @c std::invalid_argument.
+ */
+ template<class It> xor_combine_engine(It& first, It last)
+ : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
+
+ /** Calls @c seed() for both base generators. */
+ void seed() { _rng1.seed(); _rng2.seed(); }
+
+ /** @c seeds both base generators with @c v. */
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v)
+ { _rng1.seed(v); _rng2.seed(v); }
+
+ /** @c seeds both base generators with values produced by @c seq. */
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq)
+ { _rng1.seed(seq); _rng2.seed(seq); }
+
+ /**
+ * seeds both base generators with values from the iterator
+ * range [first, last) and changes first to point to the element
+ * after the last one used. If there are not enough elements in
+ * the range to seed both generators, throws @c std::invalid_argument.
+ */
+ template<class It> void seed(It& first, It last)
+ {
+ _rng1.seed(first, last);
+ _rng2.seed(first, last);
+ }
+
+ /** Returns the first base generator. */
+ const base1_type& base1() const { return _rng1; }
+
+ /** Returns the second base generator. */
+ const base2_type& base2() const { return _rng2; }
+
+ /** Returns the next value of the generator. */
+ result_type operator()()
+ {
+ return (_rng1() << s1) ^ (_rng2() << s2);
+ }
+
+ /** Fills a range with random values */
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ { detail::generate_from_int(*this, first, last); }
+
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::uintmax_t z)
+ {
+ _rng1.discard(z);
+ _rng2.discard(z);
+ }
+
+ /** Returns the smallest value that the generator can produce. */
+ static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::min)((URNG1::min)(), (URNG2::min)()); }
+ /** Returns the largest value that the generator can produce. */
+ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::max)((URNG1::min)(), (URNG2::max)()); }
+
+ /**
+ * Writes the textual representation of the generator to a @c std::ostream.
+ */
+ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s)
+ {
+ os << s._rng1 << ' ' << s._rng2;
+ return os;
+ }
+
+ /**
+ * Reads the textual representation of the generator from a @c std::istream.
+ */
+ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s)
+ {
+ is >> s._rng1 >> std::ws >> s._rng2;
+ return is;
+ }
+
+ /** Returns true if the two generators will produce identical sequences. */
+ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y)
+ { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
+
+ /** Returns true if the two generators will produce different sequences. */
+ BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine)
private:
- base1_type _rng1;
- base2_type _rng2;
+ base1_type _rng1;
+ base2_type _rng2;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
-template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
-const bool xor_combine<URNG1, s1, URNG2, s2, val>::has_fixed_range;
-template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
-const int xor_combine<URNG1, s1, URNG2, s2, val>::shift1;
-template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
-const int xor_combine<URNG1, s1, URNG2, s2, val>::shift2;
+template<class URNG1, int s1, class URNG2, int s2>
+const bool xor_combine_engine<URNG1, s1, URNG2, s2>::has_fixed_range;
+template<class URNG1, int s1, class URNG2, int s2>
+const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift1;
+template<class URNG1, int s1, class URNG2, int s2>
+const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift2;
#endif
-#undef BOOST_RANDOM_VAL_TYPE
+/// \cond show_private
+
+/** Provided for backwards compatibility. */
+template<class URNG1, int s1, class URNG2, int s2,
+ typename URNG1::result_type v = 0>
+class xor_combine : public xor_combine_engine<URNG1, s1, URNG2, s2>
+{
+ typedef xor_combine_engine<URNG1, s1, URNG2, s2> base_type;
+public:
+ typedef typename base_type::result_type result_type;
+ xor_combine() {}
+ xor_combine(result_type val) : base_type(val) {}
+ template<class It>
+ xor_combine(It& first, It last) : base_type(first, last) {}
+ xor_combine(const URNG1 & rng1, const URNG2 & rng2)
+ : base_type(rng1, rng2) { }
+
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); }
+};
+
+/// \endcond
} // namespace random
} // namespace boost
Modified: branches/release/libs/random/doc/Jamfile.v2
==============================================================================
--- branches/release/libs/random/doc/Jamfile.v2 (original)
+++ branches/release/libs/random/doc/Jamfile.v2 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -9,7 +9,7 @@
using quickbook ;
using doxygen ;
-import boostbook ;
+using boostbook ;
import regex ;
import os ;
import path ;
@@ -19,29 +19,43 @@
bernoulli_distribution
binomial_distribution
cauchy_distribution
+ chi_squared_distribution
discard_block
+ discrete_distribution
exponential_distribution
+ extreme_value_distribution
+ fisher_f_distribution
gamma_distribution
geometric_distribution
+ independent_bits
inversive_congruential
lagged_fibonacci
linear_congruential
linear_feedback_shift
lognormal_distribution
mersenne_twister
+ negative_binomial_distribution
normal_distribution
+ piecewise_constant_distribution
+ piecewise_linear_distribution
poisson_distribution
+ random_device
random_number_generator
ranlux
- shuffle_output
+ seed_seq
+ shuffle_order
+ # shuffle_output
+ student_t_distribution
subtract_with_carry
+ taus88
triangle_distribution
uniform_01
- uniform_int
+ uniform_int_distribution
uniform_on_sphere
- uniform_real
+ uniform_real_distribution
uniform_smallint
variate_generator
+ weibull_distribution
xor_combine
;
@@ -58,13 +72,14 @@
doxygen reference :
$(here)/../../../boost/random/$(doxygen_files).hpp
- $(here)/../../../boost/nondet_random.hpp
$(here)/../../../boost/random.hpp
:
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>"ALIASES= \\
xmlnote=\"@xmlonly <note><para> @endxmlonly\" \\
endxmlnote=\"@xmlonly </para></note> @endxmlonly\" \\
+ xmlwarning=\"@xmlonly <warning><para> @endxmlonly\" \\
+ endxmlwarning=\"@xmlonly </para></warning> @endxmlonly\" \\
blockquote=\"@xmlonly <blockquote><para> @endxmlonly\" \\
endblockquote=\"@xmlonly </para></blockquote> @endxmlonly\" \\
boost=\"$(BOOST_ROOT)\" \\
@@ -72,25 +87,25 @@
pseudo_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.pseudo_random_number_generator\\\">pseudo-random number generator</link> @endxmlonly\" \\
uniform_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.uniform_random_number_generator\\\">uniform random number generator</link> @endxmlonly\" \\
nondeterministic_random_number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.non_deterministic_uniform_random_number_generator\\\">non-deterministic random number generator</link> @endxmlonly\" \\
- number_generator=\"@xmlonly <link linkend=\\\"boost_random.reference.concepts.number_generator\\\">number generator</link> @endxmlonly\" \\
generators=\"@xmlonly <link linkend=\\\"boost_random.reference.generators\\\">generators</link> @endxmlonly\" \\
distributions=\"@xmlonly <link linkend=\\\"boost_random.reference.distributions\\\">distributions</link> @endxmlonly\" \\
- additive_combine=\"@xmlonly <classname alt=\\\"boost::random::additive_combine\\\">additive_combine</classname> @endxmlonly\" \\
- discard_block=\"@xmlonly <classname alt=\\\"boost::random::discard_block\\\">discard_block</classname> @endxmlonly\" \\
- lagged_fibonacci=\"@xmlonly<classname alt=\\\"boost::random::lagged_fibonacci\\\">lagged_fibonacci</classname>@endxmlonly\" \\
- linear_congruential=\"@xmlonly<classname alt=\\\"boost::random::linear_congruential\\\">linear_congruential</classname>@endxmlonly\" \\
- minstd_rand=\"@xmlonly <classname alt=\\\"boost::minstd_rand\\\">minstd_rand</classname> @endxmlonly\" \\
- minstd_rand0=\"@xmlonly <classname alt=\\\"boost::minstd_rand0\\\">minstd_rand0</classname> @endxmlonly\" \\
- rand48=\"@xmlonly <classname alt=\\\"boost::rand48\\\">rand48</classname> @endxmlonly\" \\
- mt11213b=\"@xmlonly <classname alt=\\\"boost::mt11213b\\\">mt11213b</classname> @endxmlonly\" \\
- mt19937=\"@xmlonly <classname alt=\\\"boost::mt19937\\\">mt19937</classname> @endxmlonly\" \\
- ecuyer1988=\"@xmlonly <classname alt=\\\"boost::ecuyer1988\\\">ecuyer1988</classname> @endxmlonly\" \\
- lagged_fibonacci607=\"@xmlonly <classname alt=\\\"boost::lagged_fibonacci607\\\">lagged_fibonacci607</classname> @endxmlonly\" \\
- lagged_fibonacci44497=\"@xmlonly <classname alt=\\\"boost::lagged_fibonacci44497\\\">lagged_fibonacci44497</classname> @endxmlonly\" \\
- bernoulli_distribution=\"@xmlonly <classname alt=\\\"boost::bernoulli_distribution\\\">bernoulli_distribution</classname> @endxmlonly\" \\
- cauchy_distribution=\"@xmlonly <classname alt=\\\"boost::cauchy_distribution\\\">cauchy_distribution</classname> @endxmlonly\" \\
- uniform_01=\"@xmlonly<classname alt=\\\"boost::uniform_01\\\">uniform_01</classname>@endxmlonly\" \\
- random_device=\"@xmlonly<classname alt=\\\"boost::random_device\\\">random_device</classname>@endxmlonly\""
+ additive_combine_engine=\"@xmlonly <classname alt=\\\"boost::random::additive_combine_engine\\\">additive_combine_engine</classname> @endxmlonly\" \\
+ discard_block_engine=\"@xmlonly <classname alt=\\\"boost::random::discard_block_engine\\\">discard_block_engine</classname> @endxmlonly\" \\
+ lagged_fibonacci_engine=\"@xmlonly<classname alt=\\\"boost::random::lagged_fibonacci_engine\\\">lagged_fibonacci_engine</classname>@endxmlonly\" \\
+ subtract_with_carry_01_engine=\"@xmlonly<classname alt=\\\"boost::random::subtract_with_carry_01_engine\\\">subtract_with_carry_01_engine</classname>@endxmlonly\" \\
+ linear_congruential_engine=\"@xmlonly<classname alt=\\\"boost::random::linear_congruential_engine\\\">linear_congruential_engine</classname>@endxmlonly\" \\
+ minstd_rand=\"@xmlonly <classname alt=\\\"boost::random::minstd_rand\\\">minstd_rand</classname> @endxmlonly\" \\
+ minstd_rand0=\"@xmlonly <classname alt=\\\"boost::random::minstd_rand0\\\">minstd_rand0</classname> @endxmlonly\" \\
+ rand48=\"@xmlonly <classname alt=\\\"boost::random::rand48\\\">rand48</classname> @endxmlonly\" \\
+ mt11213b=\"@xmlonly <classname alt=\\\"boost::random::mt11213b\\\">mt11213b</classname> @endxmlonly\" \\
+ mt19937=\"@xmlonly <classname alt=\\\"boost::random::mt19937\\\">mt19937</classname> @endxmlonly\" \\
+ ecuyer1988=\"@xmlonly <classname alt=\\\"boost::random::ecuyer1988\\\">ecuyer1988</classname> @endxmlonly\" \\
+ lagged_fibonacci607=\"@xmlonly <classname alt=\\\"boost::random::lagged_fibonacci607\\\">lagged_fibonacci607</classname> @endxmlonly\" \\
+ lagged_fibonacci44497=\"@xmlonly <classname alt=\\\"boost::random::lagged_fibonacci44497\\\">lagged_fibonacci44497</classname> @endxmlonly\" \\
+ bernoulli_distribution=\"@xmlonly <classname alt=\\\"boost::random::bernoulli_distribution\\\">bernoulli_distribution</classname> @endxmlonly\" \\
+ cauchy_distribution=\"@xmlonly <classname alt=\\\"boost::random::cauchy_distribution\\\">cauchy_distribution</classname> @endxmlonly\" \\
+ uniform_01=\"@xmlonly<classname alt=\\\"boost::random::uniform_01\\\">uniform_01</classname>@endxmlonly\" \\
+ random_device=\"@xmlonly<classname alt=\\\"boost::random::random_device\\\">random_device</classname>@endxmlonly\""
<doxygen:param>HIDE_UNDOC_MEMBERS=NO
<doxygen:param>QUIET=YES
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
@@ -98,15 +113,47 @@
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>SEARCH_INCLUDES=NO
+ # Expand macros and clean up a bunch of ugly names
<doxygen:param>"PREDEFINED= \\
\"BOOST_RANDOM_DOXYGEN=1\" \\
\"BOOST_PREVENT_MACRO_SUBSTITUTION=\" \\
\"BOOST_STATIC_ASSERT(x)=\" \\
\"BOOST_STATIC_CONSTANT(type,value)=static const type value\" \\
+ \"UINT64_C(value)=value ## ull\" \\
+ \"BOOST_RANDOM_DECL=\" \\
+ \"RealType(x)=x\" \\
+ \"result_type(x)=x\" \\
+ \"p_arg=p\" \\
+ \"median_arg=median\" \\
+ \"mean_arg=mean\" \\
+ \"sigma_arg=sigma\" \\
+ \"lambda_arg=lambda\" \\
+ \"alpha_arg=alpha\" \\
+ \"beta_arg=beta\" \\
+ \"a_arg=a\" \\
+ \"b_arg=b\" \\
+ \"c_arg=c\" \\
+ \"t_arg=t\" \\
+ \"m_arg=m\" \\
+ \"n_arg=n\" \\
+ \"s_arg=s\" \\
+ \"k_arg=k\" \\
+ \"min_arg=min\" \\
+ \"max_arg=max\" \\
+ \"dim_arg=dim\" \\
+ \"parm=param\" \\
+ \"aseed=seed\" \\
+ \"seed_arg=seed\" \\
+ \"BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,T,t)=template<class CharT, class Traits> friend std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,T,t)=template<class CharT, class Traits> friend std::basic_istream<CharT,Traits>& operator>>(std::basic_istream<CharT,Traits>& is, const T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T,lhs,rhs)=friend bool operator==(const T& lhs, const T& rhs)\" \\
+ \"BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T)=friend bool operator!=(const T& lhs, const T& rhs) { return !(lhs == rhs); }\" \\
\"BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self,T,t)=explicit Self(T t)\" \\
\"BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self,T,t)=template<class T> explicit Self(T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self,T,t)=template<class T> explicit Self(T& t)\" \\
\"BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self,T,t)=void seed(T t)\" \\
- \"BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self,T,t)=template<class T> void seed(T& t)\""
+ \"BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self,T,t)=template<class T> void seed(T& t)\" \\
+ \"BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self,T,t)=template<class T> void seed(T& t)\""
<reftitle>"Headers"
<doxygen:xml-imagedir>images/random
;
Modified: branches/release/libs/random/doc/concepts.qbk
==============================================================================
--- branches/release/libs/random/doc/concepts.qbk (original)
+++ branches/release/libs/random/doc/concepts.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -31,42 +31,21 @@
* pseudo-random number generator
* quasi-random number generator
-All variations have some properties in common, these concepts (in the STL
-sense) are called __NumberGenerator and __UniformRandomNumberGenerator. Each
-concept will be defined in a subsequent section.
+All variations have some properties in common, the concepts (in the STL
+sense) is called __UniformRandomNumberGenerator. This
+concept will be defined in a subsequent section.
The goals for this library are the following:
-* allow easy integration of third-party random-number generators
-* define a validation interface for the generators
+* allow easy integration of third-party random-number generators
* provide easy-to-use front-end classes which model popular distributions
* provide maximum efficiency
-* allow control on quantization effects in front-end processing (not yet done)
-
-[endsect]
-
-[section Number Generator]
-
-A number generator is a /function object/ (std:20.3 [lib.function.objects]) that
-takes zero arguments. Each call to `operator()` returns a number. In the
-following table, X denotes a number generator class returning objects of type
-T, and u is a value of X.
-
-[table NumberGenerator requirements
- [[expression] [return type] [pre/post-condition]]
- [[`X::result_type`] [`T`] [`std::numeric_limits<T>::is_specialized` is
- `true`, `T` is __LessThanComparable]]
- [[`u.operator()()`] [`T`] [-]]
-]
-
-[note The NumberGenerator requirements do not impose any restrictions on the
-characteristics of the returned numbers.]
[endsect]
[section Uniform Random Number Generator]
-A uniform random number generator is a __NumberGenerator that provides a
+A uniform random number generator provides a
sequence of random numbers uniformly distributed on a given range. The
range can be compile-time fixed or available (only) after run-time construction
of the object.
@@ -81,18 +60,9 @@
[table UniformRandomNumberGenerator requirements
[[expression] [return type] [pre/post-condition]]
- [[`X::has_fixed_range`] [`bool`] [compile-time constant; if `true`, the range
- on which the random numbers are uniformly
- distributed is known at compile-time and
- members `min_value` and `max_value` exist.
- Note: This flag may also be `false` due to
- compiler limitations]]
- [[`X::min_value`] [`T`] [compile-time constant; `min_value` is only defined if
- `has_fixed_range` is `true`. If it exists, it is
- equal to `v.min()`.]]
- [[`X::max_value`] [`T`] [compile-time constant; `max_value` is only defined if
- `has_fixed_range` is `true`. If it exists, it is
- equal to `v.max()`]]
+ [[`X::result_type`] [`T`] [`std::numeric_limits<T>::is_specialized` is
+ `true`, `T` is __LessThanComparable]]
+ [[`u.operator()()`] [`T`] [-]]
[[`v.min()`] [`T`] [tight lower bound on the set of all values returned by
`operator()`. The return value of this function shall not
change during the lifetime of the object.]]
@@ -158,8 +128,9 @@
A pseudo-random number generator is a __UniformRandomNumberGenerator which
provides a deterministic sequence of pseudo-random numbers, based on some
-algorithm and internal state. [classref boost::random::linear_congruential
-Linear congruential] and [classref boost::random::inversive_congruential
+algorithm and internal state.
+[classref boost::random::linear_congruential_engine
+Linear congruential] and [classref boost::random::inversive_congruential_engine
inversive congruential] generators are examples of such [prng pseudo-random
number generators]. Often, these generators are very sensitive to their
parameters. In order to prevent wrong implementations from being used, an
@@ -186,20 +157,13 @@
[[`X()`] [-] [creates a generator in some implementation-defined state.
Note: Several generators thusly created may possibly produce
dependent or identical sequences of random numbers.]]
- [[`explicit X(...)`] [-] [creates a generator with user-provided state; the
+ [[`X(...)`] [-] [creates a generator with user-provided state; the
implementation shall specify the constructor
argument(s)]]
[[`u.seed(...)`] [`void`] [sets the current state according to the
argument(s); at least functions with the same
signature as the non-default constructor(s)
shall be provided.]]
- [[`X::validation(x)`] [`bool`] [compares the pre-computed and hardcoded
- 10001th element in the generator's random
- number sequence with x. The generator must
- have been constructed by its default
- constructor and seed must not have been
- called for the validation to be
- meaningful.]]
]
[note The seed member function is similar to the assign member function in
@@ -219,7 +183,7 @@
pseudo-random number generator with the restored state and the original at
the just-written state shall be equivalent.
-Classes which model a pseudo-random number generator may also model the
+Classes which model a pseudo-random number generator should also model the
__CopyConstructible and __Assignable concepts. However, note that the
sequences of the original and the copy are strongly correlated (in fact,
they are identical), which may make them unsuitable for some problem domains.
@@ -247,16 +211,16 @@
`e` is an lvalue of an arbitrary type that meets the requirements of a
__UniformRandomNumberGenerator, returning values of type `U`.
-[table Random distribution requirements (in addition to NumberGenerator, CopyConstructible, and Assignable)
+[table Random distribution requirements (in addition to CopyConstructible, and Assignable)
[[expression] [return type] [pre/post-condition] [complexity]]
- [[`X::input_type`] [`U`] [-] [compile-time]]
+ [[`X::result_type`] [`T`] [-] [compile-time]]
[[`u.reset()`] [`void`] [subsequent uses of `u` do not depend on values
- produced by `e` prior to invoking `reset`.]
+ produced by any engine prior to invoking `reset`.]
[constant]]
[[`u(e)`] [`T`] [the sequence of numbers returned by successive invocations
with the same object `e` is randomly distributed with some
probability density function `p(x)`]
- [amortized constant number of invocations of `e`]]
+ [amortized constant number of invocations of `e`]]
[[`os << x`] [`std::ostream&`] [writes a textual representation for the
parameters and additional internal data of
the distribution `x` to `os`.
Modified: branches/release/libs/random/doc/distribution_performance_linux.qbk
==============================================================================
--- branches/release/libs/random/doc/distribution_performance_linux.qbk (original)
+++ branches/release/libs/random/doc/distribution_performance_linux.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,23 +1,24 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
[table Distributions (Linux)
[[\[M rn/sec\]][minstd_rand][kreutzer1986][mt19937][lagged_fibonacci607]]
- [[uniform_int][31.25][30.581][11.5607][16.0514]]
- [[geometric][5.20833][6.66223][6.68449][6.73854]]
- [[binomial][5.01505][21.7865][4.38982][10.9529]]
- [[poisson][22.8311][22.1729][20.8768][24.3902]]
- [[uniform_real][18.2815][84.0336][67.1141][72.4638]]
- [[triangle][13.2802][33.4448][33.67][36.4964]]
- [[exponential][6.19195][8.49618][8.2713][8.65052]]
- [[normal polar][5.78369][6.56599][6.49773][6.48508]]
- [[lognormal][4.13565][4.53515][4.51467][4.57875]]
- [[cauchy][6.07533][7.92393][7.77605][8.35422]]
- [[gamma][6.07533][7.92393][7.83085][8.34725]]
- [[uniform_on_sphere][1.43472][1.62075][1.5625][1.5949]]
+ [[uniform_int][16.2338][48.7805][21.5517][23.8663]]
+ [[uniform_smallint][18.9036][114.943][25.3165][74.6269]]
+ [[bernoulli][21.322][85.4701][23.2558][125]]
+ [[geometric][9.42507][11.7925][7.38007][15.528]]
+ [[binomial][13.4953][29.7619][12.7877][38.7597]]
+ [[negative_binomial][1.69549][2.29305][1.65563][2.45098]]
+ [[poisson][13.7552][34.1297][13.369][43.8596]]
+ [[uniform_real][18.2815][44.4444][19.8413][119.048]]
+ [[uniform_01][21.692][72.4638][17.1233][116.279]]
+ [[triangle][15.2207][29.3255][11.9904][51.2821]]
+ [[exponential][10.5374][17.0068][10.8814][22.2222]]
+ [[normal polar][8.82613][12.9199][9.00901][14.771]]
+ [[lognormal][6.15764][7.50188][5.68182][8.61326]]
+ [[chi squared][2.07297][2.8401][2.10926][3.07409]]
+ [[cauchy][9.18274][14.8368][7.37463][17.3913]]
+ [[fisher f][1.04646][1.47449][1.08026][1.61186]]
+ [[student t][1.60927][2.18245][1.65207][2.34192]]
+ [[gamma][2.1097][2.87439][2.13538][3.01296]]
+ [[weibull][4.73709][5.77367][4.20521][6.33312]]
+ [[extreme value][7.40192][10.101][6.23441][11.5741]]
+ [[uniform_on_sphere][2.22222][2.78552][2.28311][2.7933]]
]
Modified: branches/release/libs/random/doc/distribution_performance_windows.qbk
==============================================================================
--- branches/release/libs/random/doc/distribution_performance_windows.qbk (original)
+++ branches/release/libs/random/doc/distribution_performance_windows.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,23 +1,24 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
[table Distributions (Windows)
[[\[M rn/sec\]][minstd_rand][kreutzer1986][mt19937][lagged_fibonacci607]]
- [[uniform_int][14.7449][27.465][6.65292][28.5714]]
- [[geometric][7.10328][5.53649][3.73622][9.38438]]
- [[binomial][6.20155][5.78135][2.65118][4.65463]]
- [[poisson][15.9617][8.77886][12.5486][17.9276]]
- [[uniform_real][49.6032][27.1223][31.6857][60.35]]
- [[triangle][21.3356][11.7][14.2857][22.3015]]
- [[exponential][14.3493][6.05473][10.8472][12.982]]
- [[normal polar][4.24394][2.75748][7.04871][6.09533]]
- [[lognormal][3.30066][1.34822][5.36913][4.0024]]
- [[cauchy][11.4286][2.92372][12.0525][7.55629]]
- [[gamma][10.5263][3.72523][12.1433][5.87682]]
- [[uniform_on_sphere][0.680874][0.38004][1.18737][0.486334]]
+ [[uniform_int][27.049][79.1139][29.8151][34.8432]]
+ [[uniform_smallint][31.736][90.3342][33.9213][59.9161]]
+ [[bernoulli][25.641][56.2114][27.049][62.8141]]
+ [[geometric][12.8717][18.9645][14.6671][18.5805]]
+ [[binomial][18.2116][32.2165][19.8491][29.4118]]
+ [[negative_binomial][2.79065][3.99138][2.73358][3.72898]]
+ [[poisson][20.0321][37.7074][18.9645][36.4299]]
+ [[uniform_real][27.6319][78.1861][26.4901][71.2251]]
+ [[uniform_01][36.63][95.6938][26.3783][85.4701]]
+ [[triangle][19.4856][43.8982][19.425][36.8324]]
+ [[exponential][17.0474][32.0513][18.005][28.6205]]
+ [[normal polar][14.4051][19.7863][13.1354][20.7426]]
+ [[lognormal][10.8472][13.6968][10.3563][13.7855]]
+ [[chi squared][3.53957][4.95][3.44448][4.83442]]
+ [[cauchy][15.1906][23.5682][14.9768][23.31]]
+ [[fisher f][1.74951][2.45417][1.69854][2.38743]]
+ [[student t][2.63151][3.75291][2.53872][3.51432]]
+ [[gamma][3.50275][4.9729][3.35087][4.75195]]
+ [[weibull][8.96539][11.9161][9.09256][11.6754]]
+ [[extreme value][12.3274][18.4196][12.5945][17.5623]]
+ [[uniform_on_sphere][2.83688][3.58038][2.73898][3.60101]]
]
Modified: branches/release/libs/random/doc/distributions.qbk
==============================================================================
--- branches/release/libs/random/doc/distributions.qbk (original)
+++ branches/release/libs/random/doc/distributions.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -18,24 +18,28 @@
values of the specified distribution or otherwise do not converge
statistically to it are not acceptable.
-[table distributions
+[table Uniform Distributions
[[distribution] [explanation] [example]]
[[__uniform_smallint] [discrete uniform distribution on a small set of integers
(much smaller than the range of the underlying
generator)]
[drawing from an urn]]
- [[__uniform_int] [discrete uniform distribution on a set of integers; the
+ [[__uniform_int_distribution] [discrete uniform distribution on a set of integers; the
underlying generator may be called several times to gather
enough randomness for the output]
[drawing from an urn]]
[[__uniform_01] [continuous uniform distribution on the range [0,1);
important basis for other distributions]
[-]]
- [[__uniform_real] [continuous uniform distribution on some range [min, max) of
+ [[__uniform_real_distribution] [continuous uniform distribution on some range [min, max) of
real numbers]
[for the range [0, 2pi): randomly dropping a stick and
measuring its angle in radians (assuming the angle is
uniformly distributed)]]
+]
+
+[table Bernoulli Distributions
+ [[distribution] [explanation] [example]]
[[__bernoulli_distribution] [Bernoulli experiment: discrete boolean valued
distribution with configurable probability]
[tossing a coin (p=0.5)]]
@@ -43,20 +47,33 @@
experiments]
[tossing a coin 20 times and counting how many
front sides are shown]]
- [[__cauchy_distribution][cauchy distribution][-]]
- [[__gamma_distribution][gamma distribution][-]]
- [[__poisson_distribution][poisson distribution]
- [counting the number of alpha particles emitted
- by radioactive matter in a fixed period of time]]
[[__geometric_distribution] [measures distance between outcomes of repeated
Bernoulli experiments]
[throwing a die several times and counting the
number of tries until a "6" appears for the
first time]]
- [[__triangle_distribution] [triangle distribution] [-]]
+ [[__negative_binomial_distribution] [Counts the number of failures of repeated
+ Bernoulli experiments required to get some constant
+ number of successes.]
+ [flipping a coin and counting the number of
+ heads that show up before we get 3 tails]]
+]
+
+[table Poisson Distributions
+ [[distribution] [explanation] [example]]
+ [[__poisson_distribution][poisson distribution]
+ [counting the number of alpha particles emitted
+ by radioactive matter in a fixed period of time]]
[[__exponential_distribution] [exponential distribution]
[measuring the inter-arrival time of alpha
particles emitted by radioactive matter]]
+ [[__gamma_distribution][gamma distribution][-]]
+ [[__weibull_distribution] [weibull distribution] [-]]
+ [[__extreme_value_distribution] [extreme value distribution] [-]]
+]
+
+[table Normal Distributions
+ [[distribution] [explanation] [example]]
[[__normal_distribution] [counts outcomes of (infinitely) repeated Bernoulli
experiments]
[tossing a coin 10000 times and counting how many
@@ -65,6 +82,23 @@
simulations)]
[measuring the job completion time of an assembly
line worker]]
+ [[__chi_squared_distribution][chi-squared distribution][-]]
+ [[__cauchy_distribution][Cauchy distribution][-]]
+ [[__fisher_f_distribution][Fisher F distribution][-]]
+ [[__student_t_distribution][Student t distribution][-]]
+]
+
+[table Sampling Distributions
+ [[distribution] [explanation] [example]]
+ [[__discrete_distribution][discrete distribution with specific probabilities][rolling an unfair die]]
+ [[__piecewise_constant_distribution][-][-]]
+ [[__piecewise_linear_distribution][-][-]]
+]
+
+
+[table Miscellaneous Distributions
+ [[distribution] [explanation] [example]]
+ [[__triangle_distribution] [triangle distribution] [-]]
[[__uniform_on_sphere] [uniform distribution on a unit sphere of arbitrary
dimension]
[choosing a random point on Earth (assumed to be a
Modified: branches/release/libs/random/doc/generator_performance_linux.qbk
==============================================================================
--- branches/release/libs/random/doc/generator_performance_linux.qbk (original)
+++ branches/release/libs/random/doc/generator_performance_linux.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,42 +1,37 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
[table Basic Generators (Linux)
[[generator] [M rn/sec] [time per random number \[nsec\]] [relative speed compared to fastest \[percent\]]]
- [[rand48][312.5][3.2][100%]]
- [[lrand48 run-time][303.03][3.3][96%]]
- [[lrand48 (C library)][67.5676][14.8][21%]]
- [[minstd_rand0][96.1538][10.4][30%]]
- [[minstd_rand][93.4579][10.7][29%]]
- [[ecuyer combined][60.6061][16.5][19%]]
- [[kreutzer1986][97.0874][10.3][31%]]
- [[taus88][243.902][4.1][78%]]
- [[hellekalek1995 (inversive)][2.405][415.8][0%]]
- [[mt11213b][138.889][7.2][44%]]
- [[mt19937][138.889][7.2][44%]]
- [[lagged_fibonacci607][81.9672][12.2][26%]]
- [[lagged_fibonacci1279][81.9672][12.2][26%]]
- [[lagged_fibonacci2281][81.9672][12.2][26%]]
- [[lagged_fibonacci3217][81.3008][12.3][26%]]
- [[lagged_fibonacci4423][80.6452][12.4][25%]]
- [[lagged_fibonacci9689][80.6452][12.4][25%]]
- [[lagged_fibonacci19937][80][12.5][25%]]
- [[lagged_fibonacci23209][80.6452][12.4][25%]]
- [[lagged_fibonacci44497][79.3651][12.6][25%]]
- [[subtract_with_carry][76.9231][13][24%]]
- [[subtract_with_carry_01][45.045][22.2][14%]]
- [[ranlux3][8.78735][113.8][2%]]
- [[ranlux4][5.11771][195.4][1%]]
- [[ranlux3_01][5.29381][188.9][1%]]
- [[ranlux4_01][3.04599][328.3][0%]]
- [[ranlux64_3][8.74126][114.4][2%]]
- [[ranlux64_4][5.09684][196.2][1%]]
- [[ranlux64_3_01][5.30786][188.4][1%]]
- [[ranlux64_4_01][3.02847][330.2][0%]]
- [[mt19937ar.c][95.2381][10.5][30%]]
+ [[rand48][149.254][6.7][59%]]
+ [[lrand48 run-time][158.73][6.3][63%]]
+ [[minstd_rand0][22.9885][43.5][9%]]
+ [[minstd_rand][22.0751][45.3][8%]]
+ [[ecuyer combined][42.735][23.4][17%]]
+ [[kreutzer1986][151.515][6.6][60%]]
+ [[taus88][250][4][100%]]
+ [[knuth_b][19.6078][51][7%]]
+ [[hellekalek1995 (inversive)][4.54545][220][1%]]
+ [[mt11213b][204.082][4.9][81%]]
+ [[mt19937][204.082][4.9][81%]]
+ [[mt19937_64][60.6061][16.5][24%]]
+ [[lagged_fibonacci607][126.582][7.9][50%]]
+ [[lagged_fibonacci1279][129.87][7.7][51%]]
+ [[lagged_fibonacci2281][129.87][7.7][51%]]
+ [[lagged_fibonacci3217][131.579][7.6][52%]]
+ [[lagged_fibonacci4423][128.205][7.8][51%]]
+ [[lagged_fibonacci9689][128.205][7.8][51%]]
+ [[lagged_fibonacci19937][131.579][7.6][52%]]
+ [[lagged_fibonacci23209][131.579][7.6][52%]]
+ [[lagged_fibonacci44497][131.579][7.6][52%]]
+ [[subtract_with_carry][147.059][6.8][58%]]
+ [[subtract_with_carry_01][105.263][9.5][42%]]
+ [[ranlux3][15.748][63.5][6%]]
+ [[ranlux4][9.11577][109.7][3%]]
+ [[ranlux3_01][10.5708][94.6][4%]]
+ [[ranlux4_01][6.27353][159.4][2%]]
+ [[ranlux64_3][15.8983][62.9][6%]]
+ [[ranlux64_4][9.14913][109.3][3%]]
+ [[ranlux64_3_01][10.9409][91.4][4%]]
+ [[ranlux64_4_01][6.32911][158][2%]]
+ [[ranlux24][15.1976][65.8][6%]]
+ [[ranlux48][8.88099][112.6][3%]]
+ [[mt19937ar.c][111.111][9][44%]]
]
Modified: branches/release/libs/random/doc/generator_performance_windows.qbk
==============================================================================
--- branches/release/libs/random/doc/generator_performance_windows.qbk (original)
+++ branches/release/libs/random/doc/generator_performance_windows.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,41 +1,37 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
[table Basic Generators (Windows)
[[generator] [M rn/sec] [time per random number \[nsec\]] [relative speed compared to fastest \[percent\]]]
- [[rand48][98.5222][10.15][67%]]
- [[lrand48 run-time][17.343][57.66][11%]]
- [[minstd_rand0][46.3822][21.56][31%]]
- [[minstd_rand][38.5505][25.94][26%]]
- [[ecuyer combined][15.8028][63.28][10%]]
- [[kreutzer1986][66.6667][15][45%]]
- [[taus88][145.56][6.87][100%]]
- [[hellekalek1995 (inversive)][4.26658][234.38][2%]]
- [[mt11213b][139.082][7.19][95%]]
- [[mt19937][142.248][7.03][97%]]
- [[lagged_fibonacci607][61.5385][16.25][42%]]
- [[lagged_fibonacci1279][58.7199][17.03][40%]]
- [[lagged_fibonacci2281][64.0205][15.62][43%]]
- [[lagged_fibonacci3217][62.1118][16.1][42%]]
- [[lagged_fibonacci4423][63.3714][15.78][43%]]
- [[lagged_fibonacci9689][64.6412][15.47][44%]]
- [[lagged_fibonacci19937][63.3714][15.78][43%]]
- [[lagged_fibonacci23209][64.6412][15.47][44%]]
- [[lagged_fibonacci44497][64.0205][15.62][43%]]
- [[subtract_with_carry][92.7644][10.78][63%]]
- [[subtract_with_carry_01][78.0031][12.82][53%]]
- [[ranlux3][9.86193][101.4][6%]]
- [[ranlux4][5.80754][172.19][3%]]
- [[ranlux3_01][7.15103][139.84][4%]]
- [[ranlux4_01][3.8345][260.79][2%]]
- [[ranlux64_3][9.10415][109.84][6%]]
- [[ranlux64_4][5.05919][197.66][3%]]
- [[ranlux64_3_01][6.12445][163.28][4%]]
- [[ranlux64_4_01][3.39167][294.84][2%]]
- [[mt19937ar.c][125.471][7.97][86%]]
+ [[rand48][152.672][6.55][64%]]
+ [[lrand48 run-time][24.3724][41.03][10%]]
+ [[minstd_rand0][39.8248][25.11][16%]]
+ [[minstd_rand][39.0778][25.59][16%]]
+ [[ecuyer combined][16.7813][59.59][7%]]
+ [[kreutzer1986][89.0472][11.23][37%]]
+ [[taus88][237.53][4.21][100%]]
+ [[knuth_b][30.8166][32.45][12%]]
+ [[hellekalek1995 (inversive)][5.28457][189.23][2%]]
+ [[mt11213b][237.53][4.21][100%]]
+ [[mt19937][221.239][4.52][93%]]
+ [[mt19937_64][91.5751][10.92][38%]]
+ [[lagged_fibonacci607][142.45][7.02][59%]]
+ [[lagged_fibonacci1279][142.45][7.02][59%]]
+ [[lagged_fibonacci2281][145.56][6.87][61%]]
+ [[lagged_fibonacci3217][149.031][6.71][62%]]
+ [[lagged_fibonacci4423][142.45][7.02][59%]]
+ [[lagged_fibonacci9689][145.773][6.86][61%]]
+ [[lagged_fibonacci19937][142.45][7.02][59%]]
+ [[lagged_fibonacci23209][145.773][6.86][61%]]
+ [[lagged_fibonacci44497][142.45][7.02][59%]]
+ [[subtract_with_carry][136.24][7.34][57%]]
+ [[subtract_with_carry_01][90.3342][11.07][38%]]
+ [[ranlux3][13.1631][75.97][5%]]
+ [[ranlux4][7.60398][131.51][3%]]
+ [[ranlux3_01][8.62738][115.91][3%]]
+ [[ranlux4_01][4.99625][200.15][2%]]
+ [[ranlux64_3][13.1631][75.97][5%]]
+ [[ranlux64_4][7.5861][131.82][3%]]
+ [[ranlux64_3_01][8.63931][115.75][3%]]
+ [[ranlux64_4_01][5.01958][199.22][2%]]
+ [[ranlux24][13.1631][75.97][5%]]
+ [[ranlux48][7.5861][131.82][3%]]
+ [[mt19937ar.c][200.401][4.99][84%]]
]
Modified: branches/release/libs/random/doc/generators.qbk
==============================================================================
--- branches/release/libs/random/doc/generators.qbk (original)
+++ branches/release/libs/random/doc/generators.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,5 +1,5 @@
[/
- / Copyright (c) 2009 Steven Watanabe
+ / Copyright (c) 2009-2010 Steven Watanabe
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
@@ -47,11 +47,13 @@
[[__minstd_rand] [2[sup 31]-2] [`sizeof(int32_t)`] [[minstd_rand_speed]] [-]]
[[__rand48][2[sup 48]-1] [`sizeof(uint64_t)`] [[rand48_speed]] [-]]
[[__ecuyer1988] [approx. 2[sup 61]] [`2*sizeof(int32_t)`] [[ecuyer_combined_speed]] [-]]
+ [[__knuth_b] [?] [`257*sizeof(uint32_t)`] [[knuth_b_speed]] [-]]
[[__kreutzer1986] [?] [`1368*sizeof(uint32_t)`] [[kreutzer1986_speed]] [-]]
[[__taus88] [~2[sup 88]] [`3*sizeof(uint32_t)`] [[taus88_speed]] [-]]
[[__hellekalek1995] [2[sup 31]-1] [`sizeof(int32_t)`] [[hellekalek1995__inversive__speed]] [good uniform distribution in several dimensions]]
[[__mt11213b] [2[sup 11213]-1] [`352*sizeof(uint32_t)`] [[mt11213b_speed]] [good uniform distribution in up to 350 dimensions]]
[[__mt19937] [2[sup 19937]-1] [`625*sizeof(uint32_t)`] [[mt19937_speed]] [good uniform distribution in up to 623 dimensions]]
+ [[__mt19937_64] [2[sup 19937]-1] [`312*sizeof(uint64_t)`] [[mt19937_64_speed]] [good uniform distribution in up to 311 dimensions]]
[[__lagged_fibonacci607] [~2[sup 32000]] [`607*sizeof(double)`] [[lagged_fibonacci607_speed]] [-]]
[[__lagged_fibonacci1279] [~2[sup 67000]] [`1279*sizeof(double)`] [[lagged_fibonacci1279_speed]] [-]]
[[__lagged_fibonacci2281] [~2[sup 120000]] [`2281*sizeof(double)`] [[lagged_fibonacci2281_speed]] [-]]
@@ -69,6 +71,8 @@
[[__ranlux4_01] [~10[sup 171]] [`24*sizeof(float)`] [[ranlux4_speed]] [-]]
[[__ranlux64_3_01] [~10[sup 171]] [`24*sizeof(double)`] [[ranlux64_3_speed]] [-]]
[[__ranlux64_4_01] [~10[sup 171]] [`24*sizeof(double)`] [[ranlux64_4_speed]] [-]]
+ [[__ranlux24] [~10[sup 171]] [`24*sizeof(uint32_t)`] [[ranlux24_speed]] [-]]
+ [[__ranlux48] [~10[sup 171]] [`12*sizeof(uint64_t)`] [[ranlux48_speed]] [-]]
]
As observable from the table, there is generally a quality/performance/memory
Modified: branches/release/libs/random/doc/performance.qbk
==============================================================================
--- branches/release/libs/random/doc/performance.qbk (original)
+++ branches/release/libs/random/doc/performance.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,11 +12,9 @@
the wide variety of generators and distributions available in the boost
library.
-The performance has been evaluated on an Intel(R) Xeon(TM) MP
-CPU 3.66GHz, Gentoo Base System release 1.12.11.1, GCC 4.3.2,
-glibc 2.9 and on an Intel(R) Core(TM)2 CPU T7600
-_at_2.33 Ghz with Microsoft Windows XP Professional, Service Pack 2 Build
-2600, Microsoft Visual C++ 2008 9.0.21022.
+The performance has been evaluated on an Intel(R) Core(TM) i7
+CPU Q 840 @ 1.87GHz, 1867 Mhz with Visual C++ 2010, Microsoft
+Windows 7 Professional and with gcc 4.4.5, Ubuntu Linux 2.6.35-25-generic.
The speed is reported in million random numbers
per second (M rn/sec), generated in a tight loop.
Modified: branches/release/libs/random/doc/performance_data.qbk
==============================================================================
--- branches/release/libs/random/doc/performance_data.qbk (original)
+++ branches/release/libs/random/doc/performance_data.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,39 +1,34 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
-[template rand48_speed[] 100%]
-[template lrand48_run_time_speed[] 96%]
-[template lrand48__C_library__speed[] 21%]
-[template minstd_rand0_speed[] 30%]
-[template minstd_rand_speed[] 29%]
-[template ecuyer_combined_speed[] 19%]
-[template kreutzer1986_speed[] 31%]
-[template taus88_speed[] 78%]
-[template hellekalek1995__inversive__speed[] 0%]
-[template mt11213b_speed[] 44%]
-[template mt19937_speed[] 44%]
-[template lagged_fibonacci607_speed[] 26%]
-[template lagged_fibonacci1279_speed[] 26%]
-[template lagged_fibonacci2281_speed[] 26%]
-[template lagged_fibonacci3217_speed[] 26%]
-[template lagged_fibonacci4423_speed[] 25%]
-[template lagged_fibonacci9689_speed[] 25%]
-[template lagged_fibonacci19937_speed[] 25%]
-[template lagged_fibonacci23209_speed[] 25%]
-[template lagged_fibonacci44497_speed[] 25%]
-[template subtract_with_carry_speed[] 24%]
-[template subtract_with_carry_01_speed[] 14%]
-[template ranlux3_speed[] 2%]
-[template ranlux4_speed[] 1%]
-[template ranlux3_01_speed[] 1%]
-[template ranlux4_01_speed[] 0%]
-[template ranlux64_3_speed[] 2%]
-[template ranlux64_4_speed[] 1%]
-[template ranlux64_3_01_speed[] 1%]
-[template ranlux64_4_01_speed[] 0%]
-[template mt19937ar_c_speed[] 30%]
+[template rand48_speed[] 64%]
+[template lrand48_run_time_speed[] 10%]
+[template minstd_rand0_speed[] 16%]
+[template minstd_rand_speed[] 16%]
+[template ecuyer_combined_speed[] 7%]
+[template kreutzer1986_speed[] 37%]
+[template taus88_speed[] 100%]
+[template knuth_b_speed[] 12%]
+[template hellekalek1995__inversive__speed[] 2%]
+[template mt11213b_speed[] 100%]
+[template mt19937_speed[] 93%]
+[template mt19937_64_speed[] 38%]
+[template lagged_fibonacci607_speed[] 59%]
+[template lagged_fibonacci1279_speed[] 59%]
+[template lagged_fibonacci2281_speed[] 61%]
+[template lagged_fibonacci3217_speed[] 62%]
+[template lagged_fibonacci4423_speed[] 59%]
+[template lagged_fibonacci9689_speed[] 61%]
+[template lagged_fibonacci19937_speed[] 59%]
+[template lagged_fibonacci23209_speed[] 61%]
+[template lagged_fibonacci44497_speed[] 59%]
+[template subtract_with_carry_speed[] 57%]
+[template subtract_with_carry_01_speed[] 38%]
+[template ranlux3_speed[] 5%]
+[template ranlux4_speed[] 3%]
+[template ranlux3_01_speed[] 3%]
+[template ranlux4_01_speed[] 2%]
+[template ranlux64_3_speed[] 5%]
+[template ranlux64_4_speed[] 3%]
+[template ranlux64_3_01_speed[] 3%]
+[template ranlux64_4_01_speed[] 2%]
+[template ranlux24_speed[] 5%]
+[template ranlux48_speed[] 3%]
+[template mt19937ar_c_speed[] 84%]
Modified: branches/release/libs/random/doc/random.qbk
==============================================================================
--- branches/release/libs/random/doc/random.qbk (original)
+++ branches/release/libs/random/doc/random.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,7 +1,7 @@
[library Boost.Random
[quickbook 1.5]
[authors [Maurer, Jens]]
- [copyright 2000-2005 Jens Maurer, 2009 Steven Watanabe]
+ [copyright 2000-2005 Jens Maurer, 2009-2010 Steven Watanabe]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -26,52 +26,65 @@
[def __EqualityComparable [@boost:/doc/html/EqualityComparable.html EqualityComparable]]
[def __Streamable Streamable]
-[def __random_device [classref boost::random_device random_device]]
-[def __random_number_generator [classref boost::random_number_generator random_number_generator]]
-[def __variate_generator [classref boost::variate_generator variate_generator]]
-
-[def __minstd_rand0 [classref boost::minstd_rand0 minstd_rand0]]
-[def __minstd_rand [classref boost::minstd_rand minstd_rand]]
-[def __rand48 [classref boost::rand48 rand48]]
-[def __ecuyer1988 [classref boost::ecuyer1988 ecuyer1988]]
-[def __kreutzer1986 [classref boost::kreutzer1986 kreutzer1986]]
-[def __taus88 [classref boost::taus88 taus88]]
-[def __hellekalek1995 [classref boost::hellekalek1995 hellekalek1995]]
-[def __mt11213b [classref boost::mt11213b mt11213b]]
-[def __mt19937 [classref boost::mt19937 mt19937]]
-[def __lagged_fibonacci607 [classref boost::lagged_fibonacci607 lagged_fibonacci607]]
-[def __lagged_fibonacci1279 [classref boost::lagged_fibonacci1279 lagged_fibonacci1279]]
-[def __lagged_fibonacci2281 [classref boost::lagged_fibonacci2281 lagged_fibonacci2281]]
-[def __lagged_fibonacci3217 [classref boost::lagged_fibonacci3217 lagged_fibonacci3217]]
-[def __lagged_fibonacci4423 [classref boost::lagged_fibonacci4423 lagged_fibonacci4423]]
-[def __lagged_fibonacci9689 [classref boost::lagged_fibonacci9689 lagged_fibonacci9689]]
-[def __lagged_fibonacci19937 [classref boost::lagged_fibonacci19937 lagged_fibonacci19937]]
-[def __lagged_fibonacci23209 [classref boost::lagged_fibonacci23209 lagged_fibonacci23209]]
-[def __lagged_fibonacci44497 [classref boost::lagged_fibonacci44497 lagged_fibonacci44497]]
-[def __ranlux3 [classref boost::ranlux3 ranlux3]]
-[def __ranlux4 [classref boost::ranlux4 ranlux4]]
-[def __ranlux64_3 [classref boost::ranlux64_3 ranlux64_3]]
-[def __ranlux64_4 [classref boost::ranlux64_4 ranlux64_4]]
-[def __ranlux3_01 [classref boost::ranlux3_01 ranlux3_01]]
-[def __ranlux4_01 [classref boost::ranlux4_01 ranlux4_01]]
-[def __ranlux64_3_01 [classref boost::ranlux64_3_01 ranlux64_3_01]]
-[def __ranlux64_4_01 [classref boost::ranlux64_4_01 ranlux64_4_01]]
-
-[def __uniform_smallint [classref boost::uniform_smallint uniform_smallint]]
-[def __uniform_int [classref boost::uniform_int uniform_int]]
-[def __uniform_01 [classref boost::uniform_01 uniform_01]]
-[def __uniform_real [classref boost::uniform_real uniform_real]]
-[def __bernoulli_distribution [classref boost::bernoulli_distribution bernoulli_distribution]]
-[def __binomial_distribution [classref boost::binomial_distribution binomial_distribution]]
-[def __cauchy_distribution [classref boost::cauchy_distribution cauchy_distribution]]
-[def __gamma_distribution [classref boost::gamma_distribution gamma_distribution]]
-[def __poisson_distribution [classref boost::poisson_distribution poisson_distribution]]
-[def __geometric_distribution [classref boost::geometric_distribution geometric_distribution]]
-[def __triangle_distribution [classref boost::triangle_distribution triangle_distribution]]
-[def __exponential_distribution [classref boost::exponential_distribution exponential_distribution]]
-[def __normal_distribution [classref boost::normal_distribution normal_distribution]]
-[def __lognormal_distribution [classref boost::lognormal_distribution lognormal_distribution]]
-[def __uniform_on_sphere [classref boost::uniform_on_sphere uniform_on_sphere]]
+[def __random_device [classref boost::random::random_device random_device]]
+[def __random_number_generator [classref boost::random::random_number_generator random_number_generator]]
+[def __variate_generator [classref boost::random::variate_generator variate_generator]]
+
+[def __minstd_rand0 [classref boost::random::minstd_rand0 minstd_rand0]]
+[def __minstd_rand [classref boost::random::minstd_rand minstd_rand]]
+[def __rand48 [classref boost::random::rand48 rand48]]
+[def __ecuyer1988 [classref boost::random::ecuyer1988 ecuyer1988]]
+[def __kreutzer1986 [classref boost::random::kreutzer1986 kreutzer1986]]
+[def __knuth_b [classref boost::random::knuth_b knuth_b]]
+[def __taus88 [classref boost::random::taus88 taus88]]
+[def __hellekalek1995 [classref boost::random::hellekalek1995 hellekalek1995]]
+[def __mt11213b [classref boost::random::mt11213b mt11213b]]
+[def __mt19937 [classref boost::random::mt19937 mt19937]]
+[def __mt19937_64 [classref boost::random::mt19937_64 mt19937_64]]
+[def __lagged_fibonacci607 [classref boost::random::lagged_fibonacci607 lagged_fibonacci607]]
+[def __lagged_fibonacci1279 [classref boost::random::lagged_fibonacci1279 lagged_fibonacci1279]]
+[def __lagged_fibonacci2281 [classref boost::random::lagged_fibonacci2281 lagged_fibonacci2281]]
+[def __lagged_fibonacci3217 [classref boost::random::lagged_fibonacci3217 lagged_fibonacci3217]]
+[def __lagged_fibonacci4423 [classref boost::random::lagged_fibonacci4423 lagged_fibonacci4423]]
+[def __lagged_fibonacci9689 [classref boost::random::lagged_fibonacci9689 lagged_fibonacci9689]]
+[def __lagged_fibonacci19937 [classref boost::random::lagged_fibonacci19937 lagged_fibonacci19937]]
+[def __lagged_fibonacci23209 [classref boost::random::lagged_fibonacci23209 lagged_fibonacci23209]]
+[def __lagged_fibonacci44497 [classref boost::random::lagged_fibonacci44497 lagged_fibonacci44497]]
+[def __ranlux3 [classref boost::random::ranlux3 ranlux3]]
+[def __ranlux4 [classref boost::random::ranlux4 ranlux4]]
+[def __ranlux64_3 [classref boost::random::ranlux64_3 ranlux64_3]]
+[def __ranlux64_4 [classref boost::random::ranlux64_4 ranlux64_4]]
+[def __ranlux3_01 [classref boost::random::ranlux3_01 ranlux3_01]]
+[def __ranlux4_01 [classref boost::random::ranlux4_01 ranlux4_01]]
+[def __ranlux64_3_01 [classref boost::random::ranlux64_3_01 ranlux64_3_01]]
+[def __ranlux64_4_01 [classref boost::random::ranlux64_4_01 ranlux64_4_01]]
+[def __ranlux24 [classref boost::random::ranlux24 ranlux24]]
+[def __ranlux48 [classref boost::random::ranlux48 ranlux48]]
+
+[def __uniform_smallint [classref boost::random::uniform_smallint uniform_smallint]]
+[def __uniform_int_distribution [classref boost::random::uniform_int_distribution uniform_int_distribution]]
+[def __uniform_01 [classref boost::random::uniform_01 uniform_01]]
+[def __uniform_real_distribution [classref boost::random::uniform_real_distribution uniform_real_distribution]]
+[def __bernoulli_distribution [classref boost::random::bernoulli_distribution bernoulli_distribution]]
+[def __binomial_distribution [classref boost::random::binomial_distribution binomial_distribution]]
+[def __cauchy_distribution [classref boost::random::cauchy_distribution cauchy_distribution]]
+[def __discrete_distribution [classref boost::random::discrete_distribution discrete_distribution]]
+[def __gamma_distribution [classref boost::random::gamma_distribution gamma_distribution]]
+[def __poisson_distribution [classref boost::random::poisson_distribution poisson_distribution]]
+[def __geometric_distribution [classref boost::random::geometric_distribution geometric_distribution]]
+[def __triangle_distribution [classref boost::random::triangle_distribution triangle_distribution]]
+[def __exponential_distribution [classref boost::random::exponential_distribution exponential_distribution]]
+[def __normal_distribution [classref boost::random::normal_distribution normal_distribution]]
+[def __lognormal_distribution [classref boost::random::lognormal_distribution lognormal_distribution]]
+[def __uniform_on_sphere [classref boost::random::uniform_on_sphere uniform_on_sphere]]
+[def __weibull_distribution [classref boost::random::weibull_distribution weibull_distribution]]
+[def __extreme_value_distribution [classref boost::random::extreme_value_distribution extreme_value_distribution]]
+[def __negative_binomial_distribution [classref boost::random::negative_binomial_distribution negative_binomial_distribution]]
+[def __student_t_distribution [classref boost::random::student_t_distribution student_t_distribution]]
+[def __fisher_f_distribution [classref boost::random::fisher_f_distribution fisher_f_distribution]]
+[def __chi_squared_distribution [classref boost::random::chi_squared_distribution chi_squared_distribution]]
+[def __piecewise_constant_distribution [classref boost::random::piecewise_constant_distribution piecewise_constant_distribution]]
+[def __piecewise_linear_distribution [classref boost::random::piecewise_linear_distribution piecewise_linear_distribution]]
[include performance_data.qbk]
@@ -88,13 +101,12 @@
For a very quick start, here's an example:
- ``[classref boost::mt19937]`` rng; // produces randomness out of thin air
+ ``[classref boost::random::mt19937]`` rng; // produces randomness out of thin air
// see pseudo-random number generators
- ``[classref boost::uniform_int]<>`` six(1,6); // distribution that maps to 1..6
+ ``[classref boost::random::uniform_int_distribution]<>`` six(1,6);
+ // distribution that maps to 1..6
// see random number distributions
- ``[classref boost::variate_generator]``<``[classref boost::mt19937]``&, ``[classref boost::uniform_int]``<> >
- die(rng, six); // glues randomness with mapping
- int x = die(); // simulate rolling a die
+ int x = six(rng); // simulate rolling a die
[endsect]
@@ -124,17 +136,6 @@
[include performance.qbk]
[endsect]
-[section Rationale]
-
-The methods for generating and evaluating deterministic and non-deterministic
-random numbers differ radically. Furthermore, due to the inherent
-deterministic design of present-day computers, it is often difficult to
-implement non-deterministic random number generation facilities. Thus, the
-random number library is split into separate header files, mirroring the two
-different application domains.
-
-[endsect]
-
[section History and Acknowledgements]
In November 1999, Jeet Sukumaran proposed a framework based on virtual
Deleted: branches/release/libs/random/doc/random_number_generator.qbk
==============================================================================
--- branches/release/libs/random/doc/random_number_generator.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
+++ (empty file)
@@ -1,61 +0,0 @@
-[/
- / Copyright (c) 2009 Steven Watanabe
- /
- / Distributed under the Boost Software License, Version 1.0. (See
- / accompanying file LICENSE_1_0.txt or copy at
- / http://www.boost.org/LICENSE_1_0.txt)
-]
-
-[section Synopsis of miscellaneous decorators in header <boost/random.hpp>]
-
- namespace boost {
- template<class UniformRandomNumberGenerator, class IntType = long>
- class random_number_generator;
- } // namespace boost
-
-[endsect]
-
-[section Class template random_number_generator]
-
-[section Synopsis]
-
- template<class UniformRandomNumberGenerator, class IntType = long>
- class random_number_generator
- {
- public:
- typedef UniformRandomNumberGenerator base_type;
- typedef IntType argument_type;
- typedef IntType result_type;
- random_number_generator(base_type & rng);
- result_type operator()(argument_type n);
- };
-
-[endsect]
-
-[section Description]
-
-Instantiations of class template random_number_generator model a
-RandomNumberGenerator (std:25.2.11 [lib.alg.random.shuffle]). On each
-invocation, it returns a uniformly distributed integer in the range [0..n).
-
-The template parameter IntType shall denote some integer-like value type.
-
-[note I consider it unfortunate that the C++ Standard uses the name
-RandomNumberGenerator for something rather specific.]
-
-[endsect]
-
-[section Members]
-
- random_number_generator(base_type & rng)
-
-Effects: Constructs a random_number_generator functor with the given uniform
-random number generator as the underlying source of random numbers.
-
- result_type operator()(argument_type n)
-
-Returns: The value of uniform_int<base_type>(rng, 0, n-1)().
-
-[endsect]
-
-[endsect]
Modified: branches/release/libs/random/doc/tutorial.qbk
==============================================================================
--- branches/release/libs/random/doc/tutorial.qbk (original)
+++ branches/release/libs/random/doc/tutorial.qbk 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -19,3 +19,10 @@
[weighted_die]
[endsect]
+
+[section Generating a random password]
+
+[import ../example/password.cpp]
+[password]
+
+[endsect]
Modified: branches/release/libs/random/example/Jamfile.v2
==============================================================================
--- branches/release/libs/random/example/Jamfile.v2 (original)
+++ branches/release/libs/random/example/Jamfile.v2 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -9,3 +9,4 @@
run die.cpp ;
run weighted_die.cpp ;
+run password.cpp /boost//random ;
Modified: branches/release/libs/random/example/die.cpp
==============================================================================
--- branches/release/libs/random/example/die.cpp (original)
+++ branches/release/libs/random/example/die.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,11 +12,10 @@
For the source of this example see
[@boost://libs/random/example/die.cpp die.cpp].
First we include the headers we need for __mt19937
- and __uniform_int.
+ and __uniform_int_distribution.
*/
#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/variate_generator.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
/*`
We use __mt19937 with the default seed as a source of
@@ -25,7 +24,7 @@
change this is to seed with the current time (`std::time(0)`
defined in ctime).
*/
-boost::mt19937 gen;
+boost::random::mt19937 gen;
/*`
[note We are using a /global/ generator object here. This
is important because we don't want to create a new [prng
@@ -38,24 +37,17 @@
int roll_die() {
/*<< __mt19937 produces integers in the range [0, 2[sup 32]-1].
However, we want numbers in the range [1, 6]. The distribution
- __uniform_int performs this transformation.
- [warning Contrary to common C++ usage __uniform_int
+ __uniform_int_distribution performs this transformation.
+ [warning Contrary to common C++ usage __uniform_int_distribution
does not take a /half-open range/. Instead it takes a /closed range/.
- Given the parameters 1 and 6, __uniform_int can
+ Given the parameters 1 and 6, __uniform_int_distribution can
can produce any of the values 1, 2, 3, 4, 5, or 6.]
>>*/
- boost::uniform_int<> dist(1, 6);
- /*<< __variate_generator combines a generator with a distribution.
- [important We pass [classref boost::mt19937 boost::mt19937&] to
- __variate_generator instead of just [classref boost::mt19937]
- (note the reference). Without the reference, __variate_generator
- would make a copy of the generator and would leave the global
- `gen` unchanged. Consequently, `roll_die` would produce *the same value*
- every time it was called.]
+ boost::random::uniform_int_distribution<> dist(1, 6);
+ /*<< A distribution is a function object. We generate a random
+ number by calling `dist` with the generator.
>>*/
- boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(gen, dist);
- /*<< A __variate_generator is a function object. >>*/
- return die();
+ return dist(gen);
}
//]
Copied: branches/release/libs/random/example/password.cpp (from r62629, /trunk/libs/random/example/password.cpp)
==============================================================================
--- /trunk/libs/random/example/password.cpp (original)
+++ branches/release/libs/random/example/password.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,9 +17,8 @@
*/
-#include <boost/nondet_random.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <boost/random/uniform_int.hpp>
+#include <boost/random/random_device.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
int main() {
/*<< We first define the characters that we're going
@@ -35,14 +34,13 @@
/*<< We use __random_device as a source of entropy, since we want
passwords that are not predictable.
>>*/
- boost::random_device rng;
+ boost::random::random_device rng;
/*<< Finally we select 8 random characters from the
string and print them to cout.
>>*/
- boost::variate_generator<boost::random_device&, boost::uniform_int<> >
- gen(rng, boost::uniform_int<>(0, chars.size()));
+ boost::random::uniform_int_distribution<> index_dist(0, chars.size() - 1);
for(int i = 0; i < 8; ++i) {
- std::cout << chars[gen()];
+ std::cout << chars[index_dist(rng)];
}
std::cout << std::endl;
}
Modified: branches/release/libs/random/example/random_demo.cpp
==============================================================================
--- branches/release/libs/random/example/random_demo.cpp (original)
+++ branches/release/libs/random/example/random_demo.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -18,17 +18,7 @@
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
-
-// Sun CC doesn't handle boost::iterator_adaptor yet
-#if !defined(__SUNPRO_CC) || (__SUNPRO_CC > 0x530)
#include <boost/generator_iterator.hpp>
-#endif
-
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std {
- using ::time;
-}
-#endif
// This is a typedef for a random number generator.
// Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand
@@ -43,23 +33,18 @@
typedef boost::variate_generator<base_generator_type&, distribution_type> gen_type;
gen_type die_gen(generator, distribution_type(1, 6));
-#if !defined(__SUNPRO_CC) || (__SUNPRO_CC > 0x530)
// If you want to use an STL iterator interface, use iterator_adaptors.hpp.
- // Unfortunately, this doesn't work on SunCC yet.
boost::generator_iterator<gen_type> die(&die_gen);
for(int i = 0; i < 10; i++)
std::cout << *die++ << " ";
std::cout << '\n';
-#endif
}
int main()
{
// Define a random number generator and initialize it with a reproducible
// seed.
- // (The seed is unsigned, otherwise the wrong overload may be selected
- // when using mt19937 as the base_generator_type.)
- base_generator_type generator(42u);
+ base_generator_type generator(42);
std::cout << "10 samples of a uniform distribution in [0..1):\n";
@@ -114,15 +99,12 @@
boost::variate_generator<base_generator_type&, boost::uniform_int<> > deg(generator, degen_dist);
std::cout << deg() << " " << deg() << " " << deg() << std::endl;
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
{
// You can save the generator state for future use. You can read the
// state back in at any later time using operator>>.
std::ofstream file("rng.saved", std::ofstream::trunc);
file << generator;
}
-#endif
- // Some compilers don't pay attention to std:3.6.1/5 and issue a
- // warning here if "return 0;" is omitted.
+
return 0;
}
Modified: branches/release/libs/random/example/weighted_die.cpp
==============================================================================
--- branches/release/libs/random/example/weighted_die.cpp (original)
+++ branches/release/libs/random/example/weighted_die.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,11 +13,7 @@
[@boost://libs/random/example/weighted_die.cpp weighted_die.cpp].
*/
#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <vector>
-#include <algorithm>
-#include <numeric>
+#include <boost/random/discrete_distribution.hpp>
boost::mt19937 gen;
@@ -25,27 +21,27 @@
This time, instead of a fair die, the probability of
rolling a 1 is 50% (!). The other five faces are all
equally likely.
+
+ __discrete_distribution works nicely here by allowing
+ us to assign weights to each of the possible outcomes.
+
+ [tip If your compiler supports `std::initializer_list`,
+ you can initialize __discrete_distribution directly with
+ the weights.]
*/
-static const double probabilities[] = {
+double probabilities[] = {
0.5, 0.1, 0.1, 0.1, 0.1, 0.1
};
+boost::random::discrete_distribution<> dist(probabilities);
/*`
Now define a function that simulates rolling this die.
- Note that the C++0x library contains a `discrete_distribution`
- class which would be a better way to do this.
*/
int roll_weighted_die() {
- std::vector<double> cumulative;
- std::partial_sum(&probabilities[0], &probabilities[0] + 6,
- std::back_inserter(cumulative));
- boost::uniform_real<> dist(0, cumulative.back());
- boost::variate_generator<boost::mt19937&, boost::uniform_real<> > die(gen, dist);
- /*<< Find the position within the sequence and add 1
- (to make sure that the result is in the range [1,6]
- instead of [0,5])
+ /*<< Add 1 to make sure that the result is in the range [1,6]
+ instead of [0,5].
>>*/
- return (std::lower_bound(cumulative.begin(), cumulative.end(), die()) - cumulative.begin()) + 1;
+ return dist(gen) + 1;
}
//]
Copied: branches/release/libs/random/performance/Jamfile.v2 (from r68872, /trunk/libs/random/performance/Jamfile.v2)
==============================================================================
--- /trunk/libs/random/performance/Jamfile.v2 (original)
+++ branches/release/libs/random/performance/Jamfile.v2 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,4 +1,15 @@
-exe random_speed.exe : random_speed.cpp mt19937ar.c : release ;
+mt19937ar-files = [ glob mt19937ar.c ] ;
+
+if $(mt19937ar-files)
+{
+ alias mt19937ar : $(mt19937ar-files) : : <define>HAVE_MT19937AR_C ;
+}
+else
+{
+ alias mt19937ar ;
+}
+
+exe random_speed.exe : random_speed.cpp mt19937ar : release ;
exe generate_table.exe : generate_table.cpp /boost//regex : <link>static ;
exe nondet_random_speed.exe : nondet_random_speed.cpp /boost//random : release <link>static ;
Modified: branches/release/libs/random/performance/generate_table.cpp
==============================================================================
--- branches/release/libs/random/performance/generate_table.cpp (original)
+++ branches/release/libs/random/performance/generate_table.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -43,7 +43,19 @@
>
> unique_list;
-int main() {
+int main(int argc, char** argv) {
+
+ std::string suffix;
+ std::string id;
+
+ if(argc >= 2 && std::strcmp(argv[1], "-linux") == 0) {
+ suffix = "linux";
+ id = "Linux";
+ } else {
+ suffix = "windows";
+ id = "Windows";
+ }
+
std::vector<std::pair<std::string, double> > generator_info;
std::string line;
while(std::getline(std::cin, line)) {
@@ -63,8 +75,8 @@
double min = std::min_element(generator_info.begin(), generator_info.end(), compare_second())->second;
std::ofstream generator_defs("performance_data.qbk");
- std::ofstream generator_performance("generator_performance.qbk");
- generator_performance << "[table Basic Generators\n";
+ std::ofstream generator_performance(("generator_performance_" + suffix + ".qbk").c_str());
+ generator_performance << "[table Basic Generators (" << id << ")\n";
generator_performance << " [[generator] [M rn/sec] [time per random number \\[nsec\\]] "
"[relative speed compared to fastest \\[percent\\]]]\n";
@@ -96,9 +108,9 @@
}
} while(std::getline(std::cin, line));
- std::ofstream distribution_performance("distribution_performance.qbk");
+ std::ofstream distribution_performance(("distribution_performance_" + suffix + ".qbk").c_str());
- distribution_performance << "[table Distributions\n";
+ distribution_performance << "[table Distributions (" << id << ")\n";
distribution_performance << " [[\\[M rn/sec\\]]";
BOOST_FOREACH(const std::string& generator, generator_names) {
distribution_performance << boost::format("[%s]") % generator;
Modified: branches/release/libs/random/performance/nondet_random_speed.cpp
==============================================================================
--- branches/release/libs/random/performance/nondet_random_speed.cpp (original)
+++ branches/release/libs/random/performance/nondet_random_speed.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,10 +12,10 @@
#include <iostream>
#include <string>
#include <boost/timer.hpp>
-#include <boost/nondet_random.hpp>
+#include <boost/random/random_device.hpp>
-// set to your CPU frequency in MHz
-static const double cpu_frequency = 200 * 1e6;
+// set to your CPU frequency
+static const double cpu_frequency = 1.87 * 1e9;
static void show_elapsed(double end, int iter, const std::string & name)
{
@@ -53,12 +53,8 @@
int iter = std::atoi(argv[1]);
-#ifdef __linux__
- boost::random_device dev;
+ boost::random::random_device dev;
timing<unsigned int>(dev, iter, "random_device");
-#else
-#error The non-deterministic random device is currently available on Linux only.
-#endif
return 0;
}
Modified: branches/release/libs/random/performance/random_speed.cpp
==============================================================================
--- branches/release/libs/random/performance/random_speed.cpp (original)
+++ branches/release/libs/random/performance/random_speed.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -21,16 +21,16 @@
*/
// define if your C library supports the non-standard drand48 family
-#define HAVE_DRAND48
+//#define HAVE_DRAND48
// define if you have the original mt19937int.c (with commented out main())
#undef HAVE_MT19937INT_C
// define if you have the original mt19937ar.c (with commented out main())
-#define HAVE_MT19937AR_C
+// #define HAVE_MT19937AR_C
-// set to your CPU frequency in MHz
-static const double cpu_frequency = 3.66 * 1e9;
+// set to your CPU frequency
+static const double cpu_frequency = 1.87 * 1e9;
/*
* End of Configuration Section
@@ -244,98 +244,71 @@
{
Gen gen;
- timing(make_gen(gen, boost::uniform_int<>(-2, 4)),
+ timing(make_gen(gen, boost::random::uniform_int_distribution<>(-2, 4)),
iter, name + " uniform_int");
- timing(make_gen(gen, boost::geometric_distribution<>(0.5)),
+ timing(make_gen(gen, boost::random::uniform_smallint<>(-2, 4)),
+ iter, name + " uniform_smallint");
+
+ timing(make_gen(gen, boost::random::bernoulli_distribution<>(0.5)),
+ iter, name + " bernoulli");
+
+ timing(make_gen(gen, boost::random::geometric_distribution<>(0.5)),
iter, name + " geometric");
- timing(make_gen(gen, boost::binomial_distribution<int>(4, 0.8)),
+ timing(make_gen(gen, boost::random::binomial_distribution<int>(4, 0.8)),
iter, name + " binomial");
- timing(make_gen(gen, boost::poisson_distribution<>(1)),
+ timing(make_gen(gen, boost::random::negative_binomial_distribution<int>(4, 0.8)),
+ iter, name + " negative_binomial");
+
+ timing(make_gen(gen, boost::random::poisson_distribution<>(1)),
iter, name + " poisson");
- timing(make_gen(gen, boost::uniform_real<>(-5.3, 4.8)),
+ timing(make_gen(gen, boost::random::uniform_real_distribution<>(-5.3, 4.8)),
iter, name + " uniform_real");
- timing(make_gen(gen, boost::triangle_distribution<>(1, 2, 7)),
+ timing(make_gen(gen, boost::random::uniform_01<>()),
+ iter, name + " uniform_01");
+
+ timing(make_gen(gen, boost::random::triangle_distribution<>(1, 2, 7)),
iter, name + " triangle");
- timing(make_gen(gen, boost::exponential_distribution<>(3)),
+ timing(make_gen(gen, boost::random::exponential_distribution<>(3)),
iter, name + " exponential");
- timing(make_gen(gen, boost::normal_distribution<>()),
+ timing(make_gen(gen, boost::random::normal_distribution<>()),
iter, name + " normal polar");
- timing(make_gen(gen, boost::lognormal_distribution<>()),
+ timing(make_gen(gen, boost::random::lognormal_distribution<>()),
iter, name + " lognormal");
- timing(make_gen(gen, boost::cauchy_distribution<>()),
- iter, name + " cauchy");
-
- timing(make_gen(gen, boost::cauchy_distribution<>()),
- iter, name + " gamma");
-
- timing_sphere(make_gen(gen, boost::uniform_on_sphere<>(3)),
- iter/10, name + " uniform_on_sphere");
-}
-
-
-template<class URNG, class Dist>
-inline boost::shared_ptr<DynamicRandomGenerator<URNG, Dist> >
-make_dynamic(URNG & rng, const Dist& d)
-{
- typedef DynamicRandomGenerator<URNG, Dist> type;
- return boost::shared_ptr<type>(new type(rng, d));
-}
-
-template<class Gen>
-void distrib_runtime(int iter, const std::string & n, const Gen &)
-{
- std::string name = n + " virtual function ";
- Gen gen;
-
- GenericRandomGenerator<int> g_int;
-
- g_int.set(make_dynamic(gen, boost::uniform_int<>(-2,4)));
- timing(g_int, iter, name + "uniform_int");
-
- g_int.set(make_dynamic(gen, boost::geometric_distribution<>(0.5)));
- timing(g_int, iter, name + "geometric");
-
- g_int.set(make_dynamic(gen, boost::binomial_distribution<>(4, 0.8)));
- timing(g_int, iter, name + "binomial");
-
- g_int.set(make_dynamic(gen, boost::poisson_distribution<>(1)));
- timing(g_int, iter, name + "poisson");
+ timing(make_gen(gen, boost::random::chi_squared_distribution<>(4)),
+ iter, name + " chi squared");
- GenericRandomGenerator<double> g;
-
- g.set(make_dynamic(gen, boost::uniform_real<>(-5.3, 4.8)));
- timing(g, iter, name + "uniform_real");
+ timing(make_gen(gen, boost::random::cauchy_distribution<>()),
+ iter, name + " cauchy");
- g.set(make_dynamic(gen, boost::triangle_distribution<>(1, 2, 7)));
- timing(g, iter, name + "triangle");
+ timing(make_gen(gen, boost::random::fisher_f_distribution<>(4, 5)),
+ iter, name + " fisher f");
- g.set(make_dynamic(gen, boost::exponential_distribution<>(3)));
- timing(g, iter, name + "exponential");
+ timing(make_gen(gen, boost::random::student_t_distribution<>(7)),
+ iter, name + " student t");
- g.set(make_dynamic(gen, boost::normal_distribution<>()));
- timing(g, iter, name + "normal polar");
+ timing(make_gen(gen, boost::random::gamma_distribution<>(2.8)),
+ iter, name + " gamma");
- g.set(make_dynamic(gen, boost::lognormal_distribution<>()));
- timing(g, iter, name + "lognormal");
+ timing(make_gen(gen, boost::random::weibull_distribution<>(3)),
+ iter, name + " weibull");
- g.set(make_dynamic(gen, boost::cauchy_distribution<>()));
- timing(g, iter, name + "cauchy");
+ timing(make_gen(gen, boost::random::extreme_value_distribution<>()),
+ iter, name + " extreme value");
- g.set(make_dynamic(gen, boost::gamma_distribution<>(0.4)));
- timing(g, iter, name + "gamma");
+ timing_sphere(make_gen(gen, boost::random::uniform_on_sphere<>(3)),
+ iter/10, name + " uniform_on_sphere");
}
-
int main(int argc, char*argv[])
{
if(argc != 2) {
@@ -370,11 +343,15 @@
run(iter, "ecuyer combined", boost::ecuyer1988());
run(iter, "kreutzer1986", boost::kreutzer1986());
run(iter, "taus88", boost::taus88());
+ run(iter, "knuth_b", boost::random::knuth_b());
run(iter, "hellekalek1995 (inversive)", boost::hellekalek1995());
run(iter, "mt11213b", boost::mt11213b());
run(iter, "mt19937", boost::mt19937());
+#if !defined(BOOST_NO_INT64_T)
+ run(iter, "mt19937_64", boost::mt19937_64());
+#endif
run(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
run(iter, "lagged_fibonacci1279", boost::lagged_fibonacci1279());
@@ -396,6 +373,8 @@
run(iter, "ranlux64_4", boost::ranlux4());
run(iter, "ranlux64_3_01", boost::ranlux3_01());
run(iter, "ranlux64_4_01", boost::ranlux4_01());
+ run(iter, "ranlux24", boost::ranlux3());
+ run(iter, "ranlux48", boost::ranlux4());
run(iter, "counting", counting());
@@ -409,7 +388,6 @@
#endif
distrib(iter, "counting", counting());
- distrib_runtime(iter, "counting", counting());
distrib(iter, "minstd_rand", boost::minstd_rand());
@@ -418,6 +396,4 @@
distrib(iter, "mt19937", boost::mt19937());
distrib(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
-
- distrib_runtime(iter, "mt19937", boost::mt19937());
}
Modified: branches/release/libs/random/src/random_device.cpp
==============================================================================
--- branches/release/libs/random/src/random_device.cpp (original)
+++ branches/release/libs/random/src/random_device.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,7 +1,7 @@
/* boost random_device.cpp implementation
*
* Copyright Jens Maurer 2000
- * Copyright Steven Watanabe 2010
+ * Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -12,16 +12,15 @@
#define BOOST_RANDOM_SOURCE
-#include <boost/nondet_random.hpp>
+#include <boost/random/random_device.hpp>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/detail/workaround.hpp>
#include <string>
-#include <cassert>
-
-#if defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
// A definition is required even for integral static constants
-const bool boost::random_device::has_fixed_range;
-const boost::random_device::result_type boost::random_device::min_value;
-const boost::random_device::result_type boost::random_device::max_value;
+const bool boost::random::random_device::has_fixed_range;
#endif
@@ -56,9 +55,13 @@
#endif
-BOOST_RANDOM_DECL const char * const boost::random_device::default_token = MS_DEF_PROV_A;
+namespace {
+
+const char * const default_token = MS_DEF_PROV_A;
+
+}
-class boost::random_device::impl
+class boost::random::random_device::impl
{
public:
impl(const std::string & token) : provider(token) {
@@ -120,9 +123,11 @@
#else
+namespace {
// the default is the unlimited capacity device, using some secure hash
// try "/dev/random" for blocking when the entropy pool has drained
-const char * const boost::random_device::default_token = "/dev/urandom";
+const char * const default_token = "/dev/urandom";
+}
/*
* This uses the POSIX interface for unbuffered reading.
@@ -153,7 +158,7 @@
#include <stdexcept> // std::invalid_argument
-class boost::random_device::impl
+class boost::random::random_device::impl
{
public:
impl(const std::string & token) : path(token) {
@@ -188,16 +193,16 @@
#endif // BOOST_WINDOWS
-BOOST_RANDOM_DECL boost::random_device::random_device(const std::string& token)
+BOOST_RANDOM_DECL boost::random::random_device::random_device()
+ : pimpl(new impl(default_token))
+{}
+
+BOOST_RANDOM_DECL boost::random::random_device::random_device(const std::string& token)
: pimpl(new impl(token))
-{
- assert((std::numeric_limits<result_type>::max)() == max_value);
-}
+{}
BOOST_RANDOM_DECL boost::random_device::~random_device()
{
- // the complete class impl is now visible, so we're safe
- // (see comment in random.hpp)
delete pimpl;
}
Modified: branches/release/libs/random/test/Jamfile.v2
==============================================================================
--- branches/release/libs/random/test/Jamfile.v2 (original)
+++ branches/release/libs/random/test/Jamfile.v2 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,5 +1,5 @@
# Copyright 2003 Jens Maurer
-# Copyright 2009-2010 Steven Watanabe
+# 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)
@@ -8,38 +8,111 @@
# bring in rules for testing
import testing ;
-project /boost/random/test ;
+project /boost/random/test : requirements <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS ;
-run random_test.cpp ;
+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 validate.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 ;
-local all-urngs =
- rand48
- minstd_rand0
- minstd_rand
- ecuyer1988
- kreutzer1986
- hellekalek1995
- mt11213b
- mt19937
- lagged_fibonacci
- lagged_fibonacci607
- ranlux3
- ranlux4
- ranlux3_01
- ranlux4_01
- ranlux64_3_01
- ranlux64_4_01
- taus88
-;
-
-for urng in $(all-urngs)
-{
- run instantiate.cpp : : : <define>BOOST_RANDOM_URNG_TEST=$(urng) : test_$(urng) ;
-}
+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 ;
@@ -47,7 +120,7 @@
# run statistic_tests.cpp ;
exe statistic_tests.exe : statistic_tests.cpp ;
-explicit statistics_tests ;
+explicit statistic_tests.exe ;
install statistic_tests : statistic_tests.exe : <install-type>EXE <location>. ;
explicit statistic_tests ;
Copied: branches/release/libs/random/test/chi_squared_test.hpp (from r63088, /trunk/libs/random/test/chi_squared_test.hpp)
==============================================================================
--- /trunk/libs/random/test/chi_squared_test.hpp (original)
+++ branches/release/libs/random/test/chi_squared_test.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -38,7 +38,7 @@
current_actual += actual;
current_expected += expected;
- if(expected >= cutoff) {
+ if(current_expected >= cutoff) {
if(prev_expected != 0) {
update(prev_actual, prev_expected);
}
Copied: branches/release/libs/random/test/concepts.hpp (from r67761, /trunk/libs/random/test/concepts.hpp)
==============================================================================
--- /trunk/libs/random/test/concepts.hpp (original)
+++ branches/release/libs/random/test/concepts.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -9,18 +9,38 @@
*
*/
+#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/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>
-#ifndef BOOST_RANDOM_TEST_CONCEPTS_HPP
-#define BOOST_RANDOM_TEST_CONCEPTS_HPP
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4510)
+#pragma warning(disable:4610)
+#endif
namespace boost {
namespace random {
@@ -34,7 +54,16 @@
((Mutable_RandomAccessIterator<Iter>))
((UnsignedInteger<typename Mutable_RandomAccessIterator<Iter>::value_type>)),
(void))
- generate(Iter, Iter);
+ 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>
@@ -71,6 +100,10 @@
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>,
@@ -79,7 +112,7 @@
EqualityComparable<E>,
Streamable<E>
{
- public:
+public:
typedef typename E::result_type result_type;
// relaxed from the standard
@@ -94,12 +127,14 @@
BOOST_CONCEPT_USAGE(RandomNumberEngine)
{
same_type(e(), result_type());
- same_type(E::min(), result_type());
- same_type(E::max(), result_type());
+ same_type((E::min)(), result_type());
+ same_type((E::max)(), result_type());
- E();
- E(s);
- E(q);
+ check_extra(boost::is_integral<result_type>());
+
+ (void)E();
+ (void)E(s);
+ (void)E(q);
e.seed();
e.seed(s);
@@ -108,27 +143,79 @@
e.discard(z);
// extension
- E(sb, se);
+ (void)E(sb, se);
e.seed(sb, se);
}
- private:
+private:
E e;
E v;
const E x;
seed_seq_archetype<> q;
- result_type s;
+ typename detail::seed_type<result_type>::type s;
unsigned long long z;
+
+ void check_extra(boost::mpl::true_ /*is_integral*/) {}
+
+ void check_extra(boost::mpl::false_ /*is_integral*/)
+ {
+ // This is an undocumented extension, but we still need
+ // to check for it.
+ same_type(E::precision(), std::size_t(0));
+ }
input_iterator_archetype<boost::uint32_t> sb, se;
+};
- // Type deduction will fail unless the arguments have the same type.
- template <typename T>
- void same_type(T const&, T const&);
+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
Deleted: branches/release/libs/random/test/instantiate.cpp
==============================================================================
--- branches/release/libs/random/test/instantiate.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
+++ (empty file)
@@ -1,441 +0,0 @@
-/* boost validate.cpp
- *
- * 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$
- */
-
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-#pragma warning( disable : 4786 )
-#endif
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <cmath>
-#include <iterator>
-#include <vector>
-#include <boost/random.hpp>
-#include <boost/config.hpp>
-#include <boost/preprocessor/stringize.hpp>
-
-#include <boost/test/test_tools.hpp>
-#include <boost/test/included/test_exec_monitor.hpp>
-
-#ifdef BOOST_NO_STDC_NAMESPACE
- namespace std { using ::abs; using ::fabs; using ::pow; }
-#endif
-
-
-/*
- * General portability note:
- * MSVC mis-compiles explicit function template instantiations.
- * For example, f<A>() and f<B>() are both compiled to call f<A>().
- * BCC is unable to implicitly convert a "const char *" to a std::string
- * when using explicit function template instantiations.
- *
- * Therefore, avoid explicit function template instantiations.
- */
-
-/*
- * Check function signatures
- */
-
-#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x570) )
-#pragma warn -par
-#endif
-template<class URNG, class Dist>
-void instantiate_dist(URNG& urng, const char * name, const Dist& dist)
-{
- std::cout << "Testing " << name << std::endl;
- // this makes a copy of urng
- boost::variate_generator<URNG, Dist> gen(urng, dist);
-
- // this keeps a reference to urng
- boost::variate_generator<URNG&, Dist> genref(urng, dist);
-
- BOOST_CHECK(gen.engine() == genref.engine());
-
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- // and here is a pointer to (a copy of) the urng
- URNG copy = urng;
- boost::variate_generator<URNG*, Dist> genptr(©, dist);
-#endif
-
- for(int i = 0; i < 1000; ++i) {
- (void) gen();
- (void) genref();
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- (void) genptr();
-#endif
- }
- // If the values are not exactly equal, we cannot
- // rely on them being close...
- typename Dist::result_type g = gen();
- BOOST_CHECK_EQUAL(g, genref());
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- BOOST_CHECK_EQUAL(g, genptr());
-#endif
-
- (void) gen.engine();
- gen.distribution().reset();
-
- Dist d = dist; // copy ctor
- d = dist; // copy assignment
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- {
- std::ostringstream file;
- file << urng << std::endl;
- file << d;
- std::istringstream input(file.str());
- // std::cout << file.str() << std::endl;
- URNG restored_engine;
- input >> restored_engine;
- input >> std::ws;
- Dist restored_dist;
- input >> restored_dist;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- boost::variate_generator<URNG, Dist> old(urng, d);
- boost::variate_generator<URNG, Dist> restored(restored_engine, restored_dist);
- // advance some more so that state is exercised
- for(int i = 0; i < 1000; ++i) {
- (void) old();
- (void) restored();
- }
- BOOST_CHECK_MESSAGE((std::abs(old()-restored()) < 0.0001),
- (std::string(name) + " old == restored_dist"));
-#endif // BOOST_MSVC
- }
-#endif // BOOST_RANDOM_NO_STREAM_OPERATORS
-}
-
-template<class URNG, class RealType>
-void instantiate_real_dist(URNG& urng, RealType /* ignored */)
-{
- std::cout << "Testing real distributions with " << typeid(RealType).name() << std::endl;
- instantiate_dist(urng, "uniform_01",
- boost::uniform_01<RealType>());
- instantiate_dist(urng, "uniform_real",
- boost::uniform_real<RealType>(0, 2.1));
- instantiate_dist(urng, "triangle_distribution",
- boost::triangle_distribution<RealType>(1, 1.5, 7));
- instantiate_dist(urng, "exponential_distribution",
- boost::exponential_distribution<RealType>(5));
- instantiate_dist(urng, "normal_distribution",
- boost::normal_distribution<RealType>());
- instantiate_dist(urng, "lognormal_distribution",
- boost::lognormal_distribution<RealType>(1, 1));
- instantiate_dist(urng, "cauchy_distribution",
- boost::cauchy_distribution<RealType>(1));
- instantiate_dist(urng, "gamma_distribution",
- boost::gamma_distribution<RealType>(1));
-}
-
-template<class URNG, class T, class Converted>
-void test_seed_conversion(URNG & urng, const T & t, const Converted &) {
- 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());
- }
-}
-
-// rand48 uses non-standard seeding
-template<class T, class Converted>
-void test_seed_conversion(boost::rand48 & urng, const T & t, const Converted &) {
- boost::rand48 urng2(t);
- urng2.seed(t);
-}
-
-template<class URNG, class ResultType>
-void test_seed(const URNG &, const ResultType & value) {
- URNG urng(value);
-
- // integral types
- test_seed_conversion(urng, value, static_cast<char>(0));
- test_seed_conversion(urng, value, static_cast<signed char>(0));
- test_seed_conversion(urng, value, static_cast<unsigned char>(0));
- test_seed_conversion(urng, value, static_cast<short>(0));
- test_seed_conversion(urng, value, static_cast<unsigned short>(0));
- test_seed_conversion(urng, value, static_cast<int>(0));
- test_seed_conversion(urng, value, static_cast<unsigned int>(0));
- test_seed_conversion(urng, value, static_cast<long>(0));
- test_seed_conversion(urng, value, static_cast<unsigned long>(0));
-#if !defined(BOOST_NO_INT64_T)
- test_seed_conversion(urng, value, static_cast<boost::int64_t>(0));
- test_seed_conversion(urng, value, static_cast<boost::uint64_t>(0));
-#endif
-
- // floating point types
- test_seed_conversion(urng, value, static_cast<float>(0));
- test_seed_conversion(urng, value, static_cast<double>(0));
- test_seed_conversion(urng, value, static_cast<long double>(0));
-}
-
-template<class URNG, class ResultType>
-void instantiate_seed(const URNG & urng, const ResultType &) {
- {
- URNG urng;
- URNG urng2;
- urng2.seed();
- BOOST_CHECK(urng == urng2);
- }
- test_seed(urng, static_cast<ResultType>(0));
- test_seed(urng, static_cast<ResultType>(127));
- test_seed(urng, static_cast<ResultType>(539157235));
- test_seed(urng, static_cast<ResultType>(~0u));
-}
-
-// ranlux uses int32_t for seeding instead of result_type
-template<class ResultType>
-void instantiate_seed(const boost::ranlux3 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux3, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux4 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux4, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux3_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux3_01, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux4_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux4_01, boost::uint32_t>(urng, ResultType());
-}
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_3 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_4 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3, boost::uint32_t>(urng, ResultType());
-}
-#endif
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_3_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3_01, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_4_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_4_01, boost::uint32_t>(urng, ResultType());
-}
-
-
-template<class URNG, class ResultType>
-void instantiate_urng(const std::string & s, const URNG & u, const ResultType & r)
-{
- std::cout << "Basic tests for " << s << std::endl;
- URNG urng;
- instantiate_seed(u, r); // seed() member function
- int a[URNG::has_fixed_range ? 5 : 10]; // compile-time constant
- (void) a; // avoid "unused" warning
- typename URNG::result_type x1 = urng();
- ResultType x2 = x1;
- (void) &x2; // avoid "unused" warning
-
- URNG urng2 = urng; // copy constructor
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- BOOST_CHECK(urng == urng2); // operator==
- BOOST_CHECK(!(urng != urng2)); // operator!=
- urng();
- urng2 = urng; // copy assignment
- BOOST_CHECK(urng == urng2);
- urng2 = URNG(urng2); // copy constructor, not templated constructor
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
-
- const std::vector<int> v(9999u, 0x41);
- std::vector<int>::const_iterator it = v.begin();
- std::vector<int>::const_iterator it_end = v.end();
- URNG urng3(it, it_end);
- BOOST_CHECK(it != v.begin());
- std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
- std::cout << "; seeding uses " << n_words << " words" << std::endl;
-
- it = v.end();
- BOOST_CHECK_THROW(urng3.seed(it, it_end), std::invalid_argument);
-
- if(n_words > 1) {
- it = v.end();
- --it;
- BOOST_CHECK_THROW(urng3.seed(it, it_end), std::invalid_argument);
- }
-
- // check for min/max members
- ResultType min = (urng3.min)();
- (void) &min;
- ResultType max = (urng3.max)();
- (void) &max;
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- // Streamable concept not supported for broken compilers
-
- std::cout << "Testing stream operators" << std::endl;
-
- // advance a little so that state is relatively arbitrary
- for(int i = 0; i < 9307; ++i)
- urng();
- urng2 = urng;
-
- {
- // narrow stream first
- std::ostringstream file;
- file << urng;
- // move forward
- urng();
- // restore old state
- std::istringstream input(file.str());
- input >> urng;
- // std::cout << file.str() << std::endl;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- // advance some more so that state is exercised
- for(int i = 0; i < 10000; ++i) {
- urng();
- urng2();
- }
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
- }
-
- urng2 = urng;
-#if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
- {
- // then wide stream
- std::wostringstream file;
- file << urng;
- // move forward
- urng();
- std::wistringstream input(file.str());
- input >> urng;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- // advance some more so that state is exercised
- for(int i = 0; i < 10000; ++i) {
- urng();
- urng2();
- }
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
- }
-#endif // BOOST_NO_STD_WSTREAMBUF, BOOST_NO_STD_WSTRING
-#endif // BOOST_RANDOM_NO_STREAM_OPERATORS
-
- // instantiate various distributions with this URNG
- instantiate_dist(urng, "uniform_smallint", boost::uniform_smallint<>(0, 11));
- instantiate_dist(urng, "uniform_int", boost::uniform_int<>(-200, 20000));
- instantiate_dist(urng, "bernoulli_distribution",
- boost::bernoulli_distribution<>(0.2));
- instantiate_dist(urng, "binomial_distribution",
- boost::binomial_distribution<>(4, 0.2));
- instantiate_dist(urng, "geometric_distribution",
- boost::geometric_distribution<>(0.8));
- instantiate_dist(urng, "poisson_distribution",
- boost::poisson_distribution<>(1));
-
- instantiate_real_dist(urng, 1.0f);
- instantiate_real_dist(urng, 1.0);
- instantiate_real_dist(urng, 1.0l);
-
-#if 0
- // We cannot compare the outcomes before/after save with std::abs(x-y)
- instantiate_dist("uniform_on_sphere",
- boost::uniform_on_sphere<URNG>(urng, 2));
-#endif
-}
-
-template<class T>
-void extra_tests(T*)
-{
-}
-
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-void extra_tests(boost::rand48*)
-{
- using namespace boost;
- rand48 rnd(boost::int32_t(5));
- rand48 rnd2(boost::uint64_t(0x80000000) * 42);
- rnd.seed(boost::int32_t(17));
- rnd2.seed(boost::uint64_t(0x80000000) * 49);
-}
-#endif
-
-void extra_tests(boost::minstd_rand*)
-{
- using namespace boost;
- minstd_rand mstd(42);
- mstd.seed(17);
-}
-
-void extra_tests(boost::mt19937*)
-{
- using namespace boost;
- minstd_rand mstd(42);
- mstd.seed(17);
-
- mt19937 mt(boost::uint32_t(17)); // needs to be an exact type match for MSVC
- int i = 42;
- mt.seed(boost::uint32_t(i));
- mt19937 mt2(mstd);
- mt2.seed(mstd);
-
- random_number_generator<mt19937> std_rng(mt2);
- (void) std_rng(10);
-}
-
-void instantiate_all()
-{
- using namespace boost;
-
- typedef boost::random::lagged_fibonacci<boost::uint32_t, 24, 607, 273> lagged_fibonacci;
-
- typedef BOOST_RANDOM_URNG_TEST::result_type result_type;
- instantiate_urng(BOOST_PP_STRINGIZE(BOOST_RANDOM_URNG_TEST), BOOST_RANDOM_URNG_TEST(), static_cast<result_type>(0));
- BOOST_RANDOM_URNG_TEST* type_ptr = 0;
- extra_tests(type_ptr);
-
-}
-
-
-#if defined(BOOST_MSVC) && _MSC_VER < 1300
-
-// These explicit instantiations are necessary, otherwise MSVC does
-// not find the <boost/operators.hpp> inline friends.
-// We ease the typing with a suitable preprocessor macro.
-#define INSTANT(x) \
-template class boost::uniform_smallint<x>; \
-template class boost::uniform_int<x>; \
-template class boost::uniform_real<x>; \
-template class boost::bernoulli_distribution<x>; \
-template class boost::geometric_distribution<x>; \
-template class boost::triangle_distribution<x>; \
-template class boost::exponential_distribution<x>; \
-template class boost::normal_distribution<x>; \
-template class boost::uniform_on_sphere<x>; \
-template class boost::lognormal_distribution<x>;
-
-INSTANT(boost::minstd_rand0)
-INSTANT(boost::minstd_rand)
-INSTANT(boost::ecuyer1988)
-INSTANT(boost::kreutzer1986)
-INSTANT(boost::hellekalek1995)
-INSTANT(boost::mt19937)
-INSTANT(boost::mt11213b)
-
-#undef INSTANT
-#endif
-
-
-int test_main(int, char*[])
-{
- instantiate_all();
- return 0;
-}
Deleted: branches/release/libs/random/test/random_test.cpp
==============================================================================
--- branches/release/libs/random/test/random_test.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
+++ (empty file)
@@ -1,291 +0,0 @@
-/* boost random_test.cpp various tests
- *
- * 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$
- */
-
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-#pragma warning( disable : 4786 )
-#endif
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <cmath>
-#include <iterator>
-#include <vector>
-#include <boost/random.hpp>
-#include <boost/config.hpp>
-
-#include <boost/test/test_tools.hpp>
-#include <boost/test/included/test_exec_monitor.hpp>
-
-#ifdef BOOST_NO_STDC_NAMESPACE
- namespace std { using ::abs; using ::fabs; using ::pow; }
-#endif
-
-
-/*
- * General portability note:
- * MSVC mis-compiles explicit function template instantiations.
- * For example, f<A>() and f<B>() are both compiled to call f<A>().
- * BCC is unable to implicitly convert a "const char *" to a std::string
- * when using explicit function template instantiations.
- *
- * Therefore, avoid explicit function template instantiations.
- */
-
-/*
- * A few equidistribution tests
- */
-
-// yet to come...
-
-template<class Generator>
-void check_uniform_int(Generator & gen, int iter)
-{
- std::cout << "testing uniform_int(" << (gen.min)() << "," << (gen.max)()
- << ")" << std::endl;
- int range = (gen.max)()-(gen.min)()+1;
- std::vector<int> bucket(range);
- for(int j = 0; j < iter; j++) {
- int result = gen();
- if(result < (gen.min)() || result > (gen.max)())
- std::cerr << " ... delivers " << result << std::endl;
- else
- bucket[result-(gen.min)()]++;
- }
- int sum = 0;
- // use a different variable name "k", because MSVC has broken "for" scoping
- for(int k = 0; k < range; k++)
- sum += bucket[k];
- double avg = static_cast<double>(sum)/range;
- double p = 1 / static_cast<double>(range);
- double threshold = 2*std::sqrt(static_cast<double>(iter)*p*(1-p));
- for(int i = 0; i < range; i++) {
- if(std::fabs(bucket[i] - avg) > threshold) {
- // 95% confidence interval
- std::cout << " ... has bucket[" << i << "] = " << bucket[i]
- << " (distance " << (bucket[i] - avg) << ")"
- << std::endl;
- }
- }
-}
-
-template<class Generator>
-void test_uniform_int(Generator & gen)
-{
- typedef boost::uniform_int<int> int_gen;
-
- // large range => small range (modulo case)
- typedef boost::variate_generator<Generator&, 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::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::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::uniform_int<boost::uint8_t> int8_gen;
- typedef boost::variate_generator<Generator&, 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::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::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_MSVC) && _MSC_VER < 1300
-
-// These explicit instantiations are necessary, otherwise MSVC does
-// not find the <boost/operators.hpp> inline friends.
-// We ease the typing with a suitable preprocessor macro.
-#define INSTANT(x) \
-template class boost::uniform_smallint<x>; \
-template class boost::uniform_int<x>; \
-template class boost::uniform_real<x>; \
-template class boost::bernoulli_distribution<x>; \
-template class boost::geometric_distribution<x>; \
-template class boost::triangle_distribution<x>; \
-template class boost::exponential_distribution<x>; \
-template class boost::normal_distribution<x>; \
-template class boost::uniform_on_sphere<x>; \
-template class boost::lognormal_distribution<x>;
-
-INSTANT(boost::minstd_rand0)
-INSTANT(boost::minstd_rand)
-INSTANT(boost::ecuyer1988)
-INSTANT(boost::kreutzer1986)
-INSTANT(boost::hellekalek1995)
-INSTANT(boost::mt19937)
-INSTANT(boost::mt11213b)
-
-#undef INSTANT
-#endif
-
-#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;
-};
-
-void test_overflow_range()
-{
- ruetti_gen gen;
- boost::variate_generator<ruetti_gen, boost::uniform_int<> >
- rng(gen, boost::uniform_int<>(0, 10));
- for (int i=0;i<10;i++)
- (void) rng();
-}
-#else
-void test_overflow_range()
-{ }
-#endif
-
-template <typename EngineT>
-struct rand_for_random_shuffle
-{
- explicit rand_for_random_shuffle(EngineT &engine)
- : m_engine(engine)
- { }
-
- template <typename IntT>
- IntT operator()(IntT upperBound)
- {
- assert(upperBound > 0);
-
- if (upperBound == 1)
- {
- return 0;
- }
-
- typedef boost::uniform_int<IntT> distribution_type;
- typedef boost::variate_generator<EngineT &, distribution_type> generator_type;
-
- return generator_type(m_engine, distribution_type(0, upperBound - 1))();
- }
-
- EngineT &m_engine;
-
-};
-
-// Test that uniform_int<> can be used with std::random_shuffle
-// Author: Jos Hickson
-void 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);
-
- rand_for_random_shuffle<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);
-
- typedef std::vector<int>::iterator iter_type;
- iter_type theEnd(referenceVec.end());
-
- for (iter_type referenceIter(referenceVec.begin()), testIter(testVec.begin());
- referenceIter != theEnd;
- ++referenceIter, ++testIter)
- {
- BOOST_CHECK_EQUAL(*referenceIter, *testIter);
- }
-}
-
-
-int test_main(int, char*[])
-{
-
-#if !defined(__INTEL_COMPILER) || !defined(_MSC_VER) || __INTEL_COMPILER > 700
- boost::mt19937 mt;
- test_uniform_int(mt);
-
- // bug report from Ken Mahler: This used to lead to an endless loop.
- typedef boost::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::uniform_int<> > x(mr, boost::uniform_int<>(0, 8361));
- (void) x();
-
- // bug report from Alan Stokes and others: this throws an assertion
- boost::variate_generator<boost::minstd_rand, boost::uniform_int<> > y(mr, boost::uniform_int<>(1,1));
- std::cout << "uniform_int(1,1) " << y() << ", " << y() << ", " << y()
- << std::endl;
-
- test_overflow_range();
- test_random_shuffle();
-
- return 0;
-#else
- std::cout << "Intel 7.00 on Win32 loops, so the test is disabled\n";
- return 1;
-#endif
-}
Modified: branches/release/libs/random/test/statistic_tests.hpp
==============================================================================
--- branches/release/libs/random/test/statistic_tests.hpp (original)
+++ branches/release/libs/random/test/statistic_tests.hpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -19,9 +19,10 @@
#include <algorithm>
#include <cmath>
-#include <boost/random.hpp>
#include <boost/config.hpp>
#include <boost/bind.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/variate_generator.hpp>
#include "integrate.hpp"
@@ -93,7 +94,7 @@
for(int i = 0; i < n; ++i)
count(f());
}
- double probability(int i) const { return 1.0/classes(); }
+ double probability(int /*i*/) const { return 1.0/classes(); }
};
// two-dimensional equidistribution experiment
@@ -344,10 +345,12 @@
double probability(unsigned int r) const
{
if(r == classes()-1)
- return 1-fac<double>(d)/std::pow(d, static_cast<double>(d+classes()-2))*
+ 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(d, static_cast<double>(d+r)) *
+ return fac<double>(d)/
+ std::pow(static_cast<double>(d), static_cast<double>(d+r)) *
stirling2<double>(d+r-1, d-1);
}
private:
Copied: branches/release/libs/random/test/test_bernoulli.cpp (from r68375, /trunk/libs/random/test/test_bernoulli.cpp)
==============================================================================
--- /trunk/libs/random/test/test_bernoulli.cpp (original)
+++ branches/release/libs/random/test/test_bernoulli.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -25,7 +25,7 @@
bool do_test(double p, long long max) {
std::cout << "running bernoulli(" << p << ")" << " " << max << " times: " << std::flush;
- boost::math::binomial expected(max, p);
+ boost::math::binomial expected(static_cast<double>(max), p);
boost::random::bernoulli_distribution<> dist(p);
boost::mt19937 gen;
Copied: branches/release/libs/random/test/test_binomial.cpp (from r63088, /trunk/libs/random/test/test_binomial.cpp)
==============================================================================
--- /trunk/libs/random/test/test_binomial.cpp (original)
+++ branches/release/libs/random/test/test_binomial.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,105 +12,19 @@
#include <boost/random/binomial_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 <vector>
-#include <iostream>
-#include <numeric>
-#include "chi_squared_test.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
-bool do_test(int n, double p, long long max) {
- std::cout << "running binomial(" << n << ", " << p << ")" << " " << max << " times: " << std::flush;
-
- std::vector<double> expected(n+1);
- {
- boost::math::binomial dist(n, p);
- for(int i = 0; i <= n; ++i) {
- expected[i] = pdf(dist, i);
- }
- }
-
- boost::random::binomial_distribution<int, double> dist(n, p);
- boost::mt19937 gen;
- std::vector<long long> results(n + 1);
- 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(0, max_n);
- boost::uniform_01<> rdist;
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(idist(gen), rdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_binomial_distribution -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;
- }
-
- if(do_tests(repeat, max_n, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_binomial_distribution.cpp (from r63088, /trunk/libs/random/test/test_binomial_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_binomial_distribution.cpp (original)
+++ branches/release/libs/random/test/test_binomial_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,124 +10,28 @@
*/
#include <boost/random/binomial_distribution.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <sstream>
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.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
-BOOST_AUTO_TEST_CASE(test_constructors) {
- boost::random::binomial_distribution<> dist;
- BOOST_CHECK_EQUAL(dist.t(), 1);
- BOOST_CHECK_EQUAL(dist.p(), 0.5);
- boost::random::binomial_distribution<> dist_one(10);
- BOOST_CHECK_EQUAL(dist_one.t(), 10);
- BOOST_CHECK_EQUAL(dist_one.p(), 0.5);
- boost::random::binomial_distribution<> dist_two(10, 0.25);
- BOOST_CHECK_EQUAL(dist_two.t(), 10);
- BOOST_CHECK_EQUAL(dist_two.p(), 0.25);
- boost::random::binomial_distribution<> copy(dist);
- BOOST_CHECK_EQUAL(dist, copy);
- boost::random::binomial_distribution<> copy_one(dist_one);
- BOOST_CHECK_EQUAL(dist_one, copy_one);
- boost::random::binomial_distribution<> copy_two(dist_two);
- BOOST_CHECK_EQUAL(dist_two, copy_two);
-}
-
-BOOST_AUTO_TEST_CASE(test_copy_constructor) {
- boost::random::binomial_distribution<> dist(10, 0.25);
-}
-
-BOOST_AUTO_TEST_CASE(test_param) {
- boost::random::binomial_distribution<> dist(10, 0.25);
- boost::random::binomial_distribution<>::param_type param = dist.param();
- BOOST_CHECK_EQUAL(param.t(), 10);
- BOOST_CHECK_EQUAL(param.p(), 0.25);
- boost::random::binomial_distribution<> copy1(param);
- BOOST_CHECK_EQUAL(dist, copy1);
- boost::random::binomial_distribution<> copy2;
- copy2.param(param);
- BOOST_CHECK_EQUAL(dist, copy2);
-
- boost::random::binomial_distribution<>::param_type param_copy = param;
- BOOST_CHECK_EQUAL(param, param_copy);
- BOOST_CHECK(param == param_copy);
- BOOST_CHECK(!(param != param_copy));
- boost::random::binomial_distribution<>::param_type param_default;
- BOOST_CHECK_EQUAL(param_default.t(), 1);
- BOOST_CHECK_EQUAL(param_default.p(), 0.5);
- BOOST_CHECK(param != param_default);
- BOOST_CHECK(!(param == param_default));
- boost::random::binomial_distribution<>::param_type param_one(10);
- BOOST_CHECK_EQUAL(param_one.t(), 10);
- BOOST_CHECK_EQUAL(param_one.p(), 0.5);
- BOOST_CHECK(param != param_one);
- BOOST_CHECK(!(param == param_one));
- BOOST_CHECK(param_default != param_one);
- BOOST_CHECK(!(param_default == param_one));
- boost::random::binomial_distribution<>::param_type param_two(10, 0.25);
- BOOST_CHECK_EQUAL(param_two.t(), 10);
- BOOST_CHECK_EQUAL(param_two.p(), 0.25);
-}
-
-BOOST_AUTO_TEST_CASE(test_min_max) {
- boost::random::binomial_distribution<> dist;
- BOOST_CHECK_EQUAL((dist.min)(), 0);
- BOOST_CHECK_EQUAL((dist.max)(), 1);
- boost::random::binomial_distribution<> dist_one(10);
- BOOST_CHECK_EQUAL((dist_one.min)(), 0);
- BOOST_CHECK_EQUAL((dist_one.max)(), 10);
- boost::random::binomial_distribution<> dist_two(10, 0.25);
- BOOST_CHECK_EQUAL((dist_two.min)(), 0);
- BOOST_CHECK_EQUAL((dist_two.max)(), 10);
-}
-
-BOOST_AUTO_TEST_CASE(test_comparison) {
- boost::random::binomial_distribution<> dist;
- boost::random::binomial_distribution<> dist_copy(dist);
- boost::random::binomial_distribution<> dist_one(10);
- boost::random::binomial_distribution<> dist_one_copy(dist_one);
- boost::random::binomial_distribution<> dist_two(10, 0.25);
- boost::random::binomial_distribution<> dist_two_copy(dist_two);
- BOOST_CHECK(dist == dist_copy);
- BOOST_CHECK(!(dist != dist_copy));
- BOOST_CHECK(dist_one == dist_one_copy);
- BOOST_CHECK(!(dist_one != dist_one_copy));
- BOOST_CHECK(dist_two == dist_two_copy);
- BOOST_CHECK(!(dist_two != dist_two_copy));
- BOOST_CHECK(dist != dist_one);
- BOOST_CHECK(!(dist == dist_one));
- BOOST_CHECK(dist != dist_two);
- BOOST_CHECK(!(dist == dist_two));
- BOOST_CHECK(dist_one != dist_two);
- BOOST_CHECK(!(dist_one == dist_two));
-}
-
-BOOST_AUTO_TEST_CASE(test_streaming) {
- boost::random::binomial_distribution<> dist(10, 0.25);
- std::stringstream stream;
- stream << dist;
- boost::random::binomial_distribution<> restored_dist;
- stream >> restored_dist;
- BOOST_CHECK_EQUAL(dist, restored_dist);
-}
-
-BOOST_AUTO_TEST_CASE(test_generation) {
- boost::minstd_rand0 gen;
- boost::random::binomial_distribution<> dist;
- boost::random::binomial_distribution<> dist_two(10, 0.25);
- for(int i = 0; i < 10; ++i) {
- int value = dist(gen);
- BOOST_CHECK_GE(value, (dist.min)());
- BOOST_CHECK_LE(value, (dist.max)());
- int value_two = dist_two(gen);
- BOOST_CHECK_GE(value_two, (dist_two.min)());
- BOOST_CHECK_LE(value_two, (dist_two.max)());
- int value_param = dist_two(gen, dist.param());
- BOOST_CHECK_GE(value_param, (dist.min)());
- BOOST_CHECK_LE(value_param, (dist.max)());
- int value_two_param = dist(gen, dist_two.param());
- BOOST_CHECK_GE(value_two_param, (dist_two.min)());
- BOOST_CHECK_LE(value_two_param, (dist_two.max)());
- }
-}
+#include "test_distribution.ipp"
Copied: branches/release/libs/random/test/test_chi_squared.cpp (from r67669, /trunk/libs/random/test/test_chi_squared.cpp)
==============================================================================
--- /trunk/libs/random/test/test_chi_squared.cpp (original)
+++ branches/release/libs/random/test/test_chi_squared.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,99 +10,15 @@
*/
#include <boost/random/chi_squared_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/chi_squared.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double n, int max) {
- std::cout << "running chi_squared(" << n << ")" << " " << max << " times: " << std::flush;
-
- boost::math::chi_squared expected(n);
-
- boost::random::chi_squared_distribution<> dist(n);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::chi_squared_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_n, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> ndist(0.00001, max_n);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(ndist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_chi_squared -r <repeat> -n <max n> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_n = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, '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;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_const_mod.cpp (from r68747, /trunk/libs/random/test/test_const_mod.cpp)
==============================================================================
--- /trunk/libs/random/test/test_const_mod.cpp (original)
+++ branches/release/libs/random/test/test_const_mod.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -11,6 +11,7 @@
#include <boost/random/detail/const_mod.hpp>
+#include <boost/cstdint.hpp>
#include <boost/mpl/vector.hpp>
#define BOOST_TEST_MAIN
@@ -97,37 +98,37 @@
> int32_types;
BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult32, IntType, int32_types) {
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 2147483562)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 2147483562)), 1);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, 1234657890)), 813106682);
+ 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)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(0, 2147483562)), 2147483562);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 0)), 2147483562);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 2147483562)), 2147483561);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(1234567890, 1234657890)), 321742217);
+ 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)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 2147483562, 827364)), 827364);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 0, 827364)), 827364);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 2147483562, 2147483562)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(1234567890, 1234657890, 1726384759)), 392007878);
+ 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)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 0, 0)), 0);
+ 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)), 1);
+ 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)), 1);
+ BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, inverse)), IntType(1));
}
#if !defined(BOOST_NO_INT64_T)
@@ -138,41 +139,45 @@
> int64_types;
BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult64, IntType, int64_types) {
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(0, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(0, 2147483562)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(2147483562, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(2147483562, 2147483562)), 316718521754730848);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(1234567890, 1234657890)), 1524268986129152100);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(1234567890726352938, 1234657890736453927)), 88656187017794672);
+ 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) {
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(0, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(0, 2147483562)), 2147483562);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(2147483562, 0)), 2147483562);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(2147483562, 2147483562)), 4294967124);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(1234567890, 1234657890)), 2469225780);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(1234567890726352938, 1234657890736453927)), 321742217810068367);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::add(2147483563652738490, 8)), 0);
+ 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) {
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(0, 0, 0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(0, 2147483562, 827364)), 827364);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(2147483562, 0, 827364)), 827364);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(2147483562, 2147483562, 2147483562)), 316718523902214410);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(1234567890, 1234657890, 1726384759)), 1524268987855536859);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(1234567890726352938, 1234657890736453927, 1726384759726488649)), 1815040946744283321);
+ 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) {
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::invert(0)), 0);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult_add(0, 0, 0)), 0);
+ 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 = boost::random::const_mod<IntType, 2147483563652738498>::invert(7362947769);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(7362947769, inverse)), 1);
- inverse = boost::random::const_mod<IntType, 2147483563652738498>::invert(1263142436887493875);
- BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563652738498>::mult(1263142436887493875, inverse)), 1);
+ 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
Copied: branches/release/libs/random/test/test_discrete_distribution.cpp (from r63180, /trunk/libs/random/test/test_discrete_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_discrete_distribution.cpp (original)
+++ branches/release/libs/random/test/test_discrete_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,10 +14,15 @@
#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;
Copied: branches/release/libs/random/test/test_distribution.ipp (from r65093, /trunk/libs/random/test/test_distribution.ipp)
==============================================================================
--- /trunk/libs/random/test/test_distribution.ipp (original)
+++ branches/release/libs/random/test/test_distribution.ipp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,26 +10,46 @@
*/
#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);
@@ -39,10 +59,16 @@
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) {
-#ifdef BOOST_RANDOM_ARG2
+#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);
@@ -52,6 +78,9 @@
#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;
@@ -67,6 +96,9 @@
#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);
@@ -74,6 +106,9 @@
#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));
@@ -84,6 +119,15 @@
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
}
@@ -99,6 +143,11 @@
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) {
@@ -110,6 +159,10 @@
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);
@@ -124,10 +177,22 @@
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) {
-#ifdef BOOST_RANDOM_ARG2
+#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);
@@ -139,13 +204,57 @@
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;
+ 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
@@ -153,6 +262,7 @@
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
@@ -160,6 +270,7 @@
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
@@ -167,6 +278,7 @@
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
@@ -175,3 +287,4 @@
#endif
}
}
+
Copied: branches/release/libs/random/test/test_ecuyer1988.cpp (from r68727, /trunk/libs/random/test/test_ecuyer1988.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ecuyer1988.cpp (original)
+++ branches/release/libs/random/test/test_ecuyer1988.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,4 +13,12 @@
#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 1416886025U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 776923198U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x7AE0C087U, 0x948A8A31U, 0xBE5CCBA9U, 0x1316692CU }
+
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_extreme_value.cpp (from r63330, /trunk/libs/random/test/test_extreme_value.cpp)
==============================================================================
--- /trunk/libs/random/test/test_extreme_value.cpp (original)
+++ branches/release/libs/random/test/test_extreme_value.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,102 +10,19 @@
*/
#include <boost/random/extreme_value_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/extreme_value.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double a, double b, int max) {
- std::cout << "running extreme_value(" << a << ", " << b << ")" << " " << max << " times: " << std::flush;
-
- boost::math::extreme_value_distribution<> expected(a, b);
-
- boost::random::extreme_value_distribution<> dist(a, b);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::extreme_value_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_a, double max_b, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> adist(0.00001, max_a);
- boost::uniform_real<> bdist(0.00001, max_b);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(adist(gen), bdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_extreme_value -r <repeat> -a <max a> -b <max b> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_a = 1000.0;
- double max_b = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, 'a', max_a)
- && !handle_option(argc, argv, 'b', max_b)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_a, max_b, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_extreme_value_distribution.cpp (from r63330, /trunk/libs/random/test/test_extreme_value_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_extreme_value_distribution.cpp (original)
+++ branches/release/libs/random/test/test_extreme_value_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,119 +10,27 @@
*/
#include <boost/random/extreme_value_distribution.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <sstream>
+#include <limits>
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
+#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)()
-BOOST_AUTO_TEST_CASE(test_constructors) {
- boost::random::extreme_value_distribution<> dist;
- BOOST_CHECK_EQUAL(dist.a(), 1.0);
- BOOST_CHECK_EQUAL(dist.b(), 1.0);
- boost::random::extreme_value_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL(dist_one.a(), 7.5);
- BOOST_CHECK_EQUAL(dist_one.b(), 1.0);
- boost::random::extreme_value_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(dist_two.a(), 7.5);
- BOOST_CHECK_EQUAL(dist_two.b(), 0.25);
- boost::random::extreme_value_distribution<> copy(dist);
- BOOST_CHECK_EQUAL(dist, copy);
- boost::random::extreme_value_distribution<> copy_one(dist_one);
- BOOST_CHECK_EQUAL(dist_one, copy_one);
- boost::random::extreme_value_distribution<> copy_two(dist_two);
- BOOST_CHECK_EQUAL(dist_two, copy_two);
-}
-
-BOOST_AUTO_TEST_CASE(test_param) {
- boost::random::extreme_value_distribution<> dist(7.5, 0.25);
- boost::random::extreme_value_distribution<>::param_type param = dist.param();
- BOOST_CHECK_EQUAL(param.a(), 7.5);
- BOOST_CHECK_EQUAL(param.b(), 0.25);
- boost::random::extreme_value_distribution<> copy1(param);
- BOOST_CHECK_EQUAL(dist, copy1);
- boost::random::extreme_value_distribution<> copy2;
- copy2.param(param);
- BOOST_CHECK_EQUAL(dist, copy2);
-
- boost::random::extreme_value_distribution<>::param_type param_copy = param;
- BOOST_CHECK_EQUAL(param, param_copy);
- BOOST_CHECK(param == param_copy);
- BOOST_CHECK(!(param != param_copy));
- boost::random::extreme_value_distribution<>::param_type param_default;
- BOOST_CHECK_EQUAL(param_default.a(), 1.0);
- BOOST_CHECK_EQUAL(param_default.b(), 1.0);
- BOOST_CHECK(param != param_default);
- BOOST_CHECK(!(param == param_default));
- boost::random::extreme_value_distribution<>::param_type param_one(7.5);
- BOOST_CHECK_EQUAL(param_one.a(), 7.5);
- BOOST_CHECK_EQUAL(param_one.b(), 1.0);
- BOOST_CHECK(param != param_one);
- BOOST_CHECK(!(param == param_one));
- BOOST_CHECK(param_default != param_one);
- BOOST_CHECK(!(param_default == param_one));
- boost::random::extreme_value_distribution<>::param_type param_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(param_two.a(), 7.5);
- BOOST_CHECK_EQUAL(param_two.b(), 0.25);
-}
-
-BOOST_AUTO_TEST_CASE(test_min_max) {
- boost::random::extreme_value_distribution<> dist;
- BOOST_CHECK_EQUAL((dist.min)(), -(std::numeric_limits<double>::infinity)());
- BOOST_CHECK_EQUAL((dist.max)(), (std::numeric_limits<double>::infinity)());
- boost::random::extreme_value_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL((dist_one.min)(), -(std::numeric_limits<double>::infinity)());
- BOOST_CHECK_EQUAL((dist_one.max)(), (std::numeric_limits<double>::infinity)());
- boost::random::extreme_value_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL((dist_two.min)(), -(std::numeric_limits<double>::infinity)());
- BOOST_CHECK_EQUAL((dist_two.max)(), (std::numeric_limits<double>::infinity)());
-}
-
-BOOST_AUTO_TEST_CASE(test_comparison) {
- boost::random::extreme_value_distribution<> dist;
- boost::random::extreme_value_distribution<> dist_copy(dist);
- boost::random::extreme_value_distribution<> dist_one(7.5);
- boost::random::extreme_value_distribution<> dist_one_copy(dist_one);
- boost::random::extreme_value_distribution<> dist_two(7.5, 0.25);
- boost::random::extreme_value_distribution<> dist_two_copy(dist_two);
- BOOST_CHECK(dist == dist_copy);
- BOOST_CHECK(!(dist != dist_copy));
- BOOST_CHECK(dist_one == dist_one_copy);
- BOOST_CHECK(!(dist_one != dist_one_copy));
- BOOST_CHECK(dist_two == dist_two_copy);
- BOOST_CHECK(!(dist_two != dist_two_copy));
- BOOST_CHECK(dist != dist_one);
- BOOST_CHECK(!(dist == dist_one));
- BOOST_CHECK(dist != dist_two);
- BOOST_CHECK(!(dist == dist_two));
- BOOST_CHECK(dist_one != dist_two);
- BOOST_CHECK(!(dist_one == dist_two));
-}
-
-BOOST_AUTO_TEST_CASE(test_streaming) {
- boost::random::extreme_value_distribution<> dist(7.5, 0.25);
- std::stringstream stream;
- stream << dist;
- boost::random::extreme_value_distribution<> restored_dist;
- stream >> restored_dist;
- BOOST_CHECK_EQUAL(dist, restored_dist);
-}
-
-BOOST_AUTO_TEST_CASE(test_generation) {
- boost::minstd_rand0 gen;
- boost::random::extreme_value_distribution<> dist(-100.0);
- boost::random::extreme_value_distribution<> dist_two(100.0);
- for(int i = 0; i < 10; ++i) {
- // This test is not guaranteed to work, since
- // a extreme value distribution with a large location
- // parameter can produce small values and vice versa
- double value = dist(gen);
- BOOST_CHECK_LE(value, 0.0);
- double value_two = dist_two(gen);
- BOOST_CHECK_GE(value_two, 0.0);
- double value_param = dist_two(gen, dist.param());
- BOOST_CHECK_LE(value_param, 0.0);
- double value_two_param = dist(gen, dist_two.param());
- BOOST_CHECK_GE(value_two_param, 0.0);
- }
-}
+#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"
Copied: branches/release/libs/random/test/test_fisher_f.cpp (from r67694, /trunk/libs/random/test/test_fisher_f.cpp)
==============================================================================
--- /trunk/libs/random/test/test_fisher_f.cpp (original)
+++ branches/release/libs/random/test/test_fisher_f.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -11,100 +11,18 @@
#include <boost/random/fisher_f_distribution.hpp>
#include <boost/random/uniform_real.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions/fisher_f.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double m, double n, int max) {
- std::cout << "running fisher_f(" << m << ", " << n << ")" << " " << max << " times: " << std::flush;
-
- boost::math::fisher_f expected(m, n);
-
- boost::random::fisher_f_distribution<> dist(m, n);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::fisher_f_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_m, double max_n, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> mdist(0.00001, max_m);
- boost::uniform_real<> ndist(0.00001, max_n);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(mdist(gen), ndist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_fisher_f -r <repeat> -m <max m> -n <max n> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_m = 1000.0;
- double max_n = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, 'm', max_m)
- && !handle_option(argc, argv, 'n', max_n)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_m, max_n, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_gamma.cpp (from r63247, /trunk/libs/random/test/test_gamma.cpp)
==============================================================================
--- /trunk/libs/random/test/test_gamma.cpp (original)
+++ branches/release/libs/random/test/test_gamma.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,102 +10,19 @@
*/
#include <boost/random/gamma_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/gamma.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.hpp"
+#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)
-bool do_test(double alpha, double beta, int max) {
- std::cout << "running gamma(" << alpha << ", " << beta << ")" << " " << max << " times: " << std::flush;
-
- boost::math::gamma_distribution<> expected(alpha, beta);
-
- boost::random::gamma_distribution<> dist(alpha, beta);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::gamma_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_alpha, double max_beta, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> adist(0.00001, max_alpha);
- boost::uniform_real<> bdist(0.00001, max_beta);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(adist(gen), bdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_gamma -r <repeat> -n <max n> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_alpha = 1000.0;
- double max_beta = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, 'a', max_alpha)
- && !handle_option(argc, argv, 'b', max_beta)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_alpha, max_beta, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_gamma_distribution.cpp (from r63247, /trunk/libs/random/test/test_gamma_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_gamma_distribution.cpp (original)
+++ branches/release/libs/random/test/test_gamma_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,123 +10,28 @@
*/
#include <boost/random/gamma_distribution.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <sstream>
+#include <limits>
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
+#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
-BOOST_AUTO_TEST_CASE(test_constructors) {
- boost::random::gamma_distribution<> dist;
- BOOST_CHECK_EQUAL(dist.alpha(), 1.0);
- BOOST_CHECK_EQUAL(dist.beta(), 1.0);
- boost::random::gamma_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL(dist_one.alpha(), 7.5);
- BOOST_CHECK_EQUAL(dist_one.beta(), 1.0);
- boost::random::gamma_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(dist_two.alpha(), 7.5);
- BOOST_CHECK_EQUAL(dist_two.beta(), 0.25);
- boost::random::gamma_distribution<> copy(dist);
- BOOST_CHECK_EQUAL(dist, copy);
- boost::random::gamma_distribution<> copy_one(dist_one);
- BOOST_CHECK_EQUAL(dist_one, copy_one);
- boost::random::gamma_distribution<> copy_two(dist_two);
- BOOST_CHECK_EQUAL(dist_two, copy_two);
-}
-
-BOOST_AUTO_TEST_CASE(test_param) {
- boost::random::gamma_distribution<> dist(7.5, 0.25);
- boost::random::gamma_distribution<>::param_type param = dist.param();
- BOOST_CHECK_EQUAL(param.alpha(), 7.5);
- BOOST_CHECK_EQUAL(param.beta(), 0.25);
- boost::random::gamma_distribution<> copy1(param);
- BOOST_CHECK_EQUAL(dist, copy1);
- boost::random::gamma_distribution<> copy2;
- copy2.param(param);
- BOOST_CHECK_EQUAL(dist, copy2);
-
- boost::random::gamma_distribution<>::param_type param_copy = param;
- BOOST_CHECK_EQUAL(param, param_copy);
- BOOST_CHECK(param == param_copy);
- BOOST_CHECK(!(param != param_copy));
- boost::random::gamma_distribution<>::param_type param_default;
- BOOST_CHECK_EQUAL(param_default.alpha(), 1.0);
- BOOST_CHECK_EQUAL(param_default.beta(), 1.0);
- BOOST_CHECK(param != param_default);
- BOOST_CHECK(!(param == param_default));
- boost::random::gamma_distribution<>::param_type param_one(7.5);
- BOOST_CHECK_EQUAL(param_one.alpha(), 7.5);
- BOOST_CHECK_EQUAL(param_one.beta(), 1.0);
- BOOST_CHECK(param != param_one);
- BOOST_CHECK(!(param == param_one));
- BOOST_CHECK(param_default != param_one);
- BOOST_CHECK(!(param_default == param_one));
- boost::random::gamma_distribution<>::param_type param_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(param_two.alpha(), 7.5);
- BOOST_CHECK_EQUAL(param_two.beta(), 0.25);
-}
-
-BOOST_AUTO_TEST_CASE(test_min_max) {
- boost::random::gamma_distribution<> dist;
- BOOST_CHECK_EQUAL((dist.min)(), 0);
- BOOST_CHECK_EQUAL((dist.max)(), (std::numeric_limits<double>::max)());
- boost::random::gamma_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL((dist_one.min)(), 0);
- BOOST_CHECK_EQUAL((dist_one.max)(), (std::numeric_limits<double>::max)());
- boost::random::gamma_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL((dist_two.min)(), 0);
- BOOST_CHECK_EQUAL((dist_two.max)(), (std::numeric_limits<double>::max)());
-}
-
-BOOST_AUTO_TEST_CASE(test_comparison) {
- boost::random::gamma_distribution<> dist;
- boost::random::gamma_distribution<> dist_copy(dist);
- boost::random::gamma_distribution<> dist_one(7.5);
- boost::random::gamma_distribution<> dist_one_copy(dist_one);
- boost::random::gamma_distribution<> dist_two(7.5, 0.25);
- boost::random::gamma_distribution<> dist_two_copy(dist_two);
- BOOST_CHECK(dist == dist_copy);
- BOOST_CHECK(!(dist != dist_copy));
- BOOST_CHECK(dist_one == dist_one_copy);
- BOOST_CHECK(!(dist_one != dist_one_copy));
- BOOST_CHECK(dist_two == dist_two_copy);
- BOOST_CHECK(!(dist_two != dist_two_copy));
- BOOST_CHECK(dist != dist_one);
- BOOST_CHECK(!(dist == dist_one));
- BOOST_CHECK(dist != dist_two);
- BOOST_CHECK(!(dist == dist_two));
- BOOST_CHECK(dist_one != dist_two);
- BOOST_CHECK(!(dist_one == dist_two));
-}
-
-BOOST_AUTO_TEST_CASE(test_streaming) {
- boost::random::gamma_distribution<> dist(7.5, 0.25);
- std::stringstream stream;
- stream << dist;
- boost::random::gamma_distribution<> restored_dist;
- stream >> restored_dist;
- BOOST_CHECK_EQUAL(dist, restored_dist);
-}
-
-BOOST_AUTO_TEST_CASE(test_generation) {
- boost::minstd_rand0 gen;
- boost::random::gamma_distribution<> dist;
- boost::random::gamma_distribution<> dist_two(1.0, 1000000.0);
- for(int i = 0; i < 10; ++i) {
- // This test is not guaranteed to work, since
- // a gamma distribution with a large scale parameter
- // can produce small values and a distribution with
- // a small scale can produce large values, but the
- // chances of failure are small.
- double value = dist(gen);
- BOOST_CHECK_GE(value, 0.0);
- BOOST_CHECK_LE(value, 100.0);
- double value_two = dist_two(gen);
- BOOST_CHECK_GE(value_two, 100.0);
- double value_param = dist_two(gen, dist.param());
- BOOST_CHECK_GE(value_param, 0);
- BOOST_CHECK_LE(value_param, 100.0);
- double value_two_param = dist(gen, dist_two.param());
- BOOST_CHECK_GE(value_two_param, 100.0);
- }
-}
+#define BOOST_RANDOM_TEST2_PARAMS (1.0, 1000000.0)
+#define BOOST_RANDOM_TEST2_MIN 100.0
+
+#include "test_distribution.ipp"
Copied: branches/release/libs/random/test/test_generate_canonical.cpp (from r68813, /trunk/libs/random/test/test_generate_canonical.cpp)
==============================================================================
--- /trunk/libs/random/test/test_generate_canonical.cpp (original)
+++ branches/release/libs/random/test/test_generate_canonical.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -91,7 +91,7 @@
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(); }
+ result_type operator()() { return (max)(); }
};
BOOST_AUTO_TEST_CASE(test_max)
Copied: branches/release/libs/random/test/test_generator.ipp (from r67761, /trunk/libs/random/test/test_generator.ipp)
==============================================================================
--- /trunk/libs/random/test/test_generator.ipp (original)
+++ branches/release/libs/random/test/test_generator.ipp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -19,6 +19,12 @@
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)
@@ -34,7 +40,11 @@
}
}
-void test_seed(result_type value)
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+void test_seed(seed_type value)
{
BOOST_RANDOM_URNG urng(value);
@@ -71,23 +81,24 @@
BOOST_AUTO_TEST_CASE(test_arithmetic_seed)
{
- test_seed(static_cast<result_type>(0));
- test_seed(static_cast<result_type>(127));
- test_seed(static_cast<result_type>(539157235));
- test_seed(static_cast<result_type>(~0u));
+ 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(9999u, 0x41);
+ 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();
+ 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());
@@ -101,7 +112,7 @@
if(n_words > 1) {
it = v.end();
--it;
- BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
+ 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);
@@ -110,7 +121,7 @@
BOOST_AUTO_TEST_CASE(test_seed_seq_seed)
{
- boost::random::seed_seq q;
+ boost::random::seed_seq q;
BOOST_RANDOM_URNG urng(q);
BOOST_RANDOM_URNG urng2;
BOOST_CHECK_NE(urng, urng2);
@@ -192,3 +203,44 @@
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);
+}
Copied: branches/release/libs/random/test/test_geometric.cpp (from r68410, /trunk/libs/random/test/test_geometric.cpp)
==============================================================================
--- /trunk/libs/random/test/test_geometric.cpp (original)
+++ branches/release/libs/random/test/test_geometric.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,7 @@
#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
@@ -20,6 +21,6 @@
#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 (-5 / std::log(1-p))
+#define BOOST_RANDOM_DISTRIBUTION_MAX boost::numeric_cast<int>(-5 / std::log(1-p))
#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_hellekalek1995.cpp (from r68748, /trunk/libs/random/test/test_hellekalek1995.cpp)
==============================================================================
--- /trunk/libs/random/test/test_hellekalek1995.cpp (original)
+++ branches/release/libs/random/test/test_hellekalek1995.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,4 +13,12 @@
#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 1081665111U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 618743552U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5642A47BU, 0x1F6987E8U, 0xD35860E7U, 0xC8C661ABU }
+
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_independent_bits31.cpp (from r68804, /trunk/libs/random/test/test_independent_bits31.cpp)
==============================================================================
--- /trunk/libs/random/test/test_independent_bits31.cpp (original)
+++ branches/release/libs/random/test/test_independent_bits31.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,6 +14,13 @@
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_VALIDATION_VALUE 26292962
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+#define BOOST_RANDOM_VALIDATION_VALUE 26292962U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1147343739U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1399154219U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC1A63AF0U, 0xD66C0614U, 0xADE076B1U, 0xC1DAE13FU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_independent_bits32.cpp (from r68804, /trunk/libs/random/test/test_independent_bits32.cpp)
==============================================================================
--- /trunk/libs/random/test/test_independent_bits32.cpp (original)
+++ branches/release/libs/random/test/test_independent_bits32.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,6 +14,13 @@
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 3107690757U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3408548740U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xD091BB5CU, 0x22AE9EF6U, 0xE7E1FAEEU, 0xD5C31F79U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_knuth_b.cpp (from r68784, /trunk/libs/random/test/test_knuth_b.cpp)
==============================================================================
--- /trunk/libs/random/test/test_knuth_b.cpp (original)
+++ branches/release/libs/random/test/test_knuth_b.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 1112339016
+#define BOOST_RANDOM_VALIDATION_VALUE 1112339016U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 160100893U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1692601883U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5D189C63U, 0xD0544F0EU, 0x15B0E78FU, 0xD814D654U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_kreutzer1986.cpp (from r68783, /trunk/libs/random/test/test_kreutzer1986.cpp)
==============================================================================
--- /trunk/libs/random/test/test_kreutzer1986.cpp (original)
+++ branches/release/libs/random/test/test_kreutzer1986.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 139726
+#define BOOST_RANDOM_VALIDATION_VALUE 139726U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 227233U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 163138U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x3EADAB08U, 0x85E481CEU, 0xCF84AEA5U, 0x39D4395BU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci.cpp (from r68754, /trunk/libs/random/test/test_lagged_fibonacci.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,4 +14,12 @@
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 7852929U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 4372778U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xF61A5094U, 0xFC4BA046U, 0xF1C41E92U, 0x3D82FE61U }
+
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci1279.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci1279.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci1279.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci1279.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci1279
-#define BOOST_RANDOM_VALIDATION_VALUE 0.56576990947654049
+
+#define BOOST_RANDOM_SEED_WORDS 1279*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.39647253381274083
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.37536953918742455
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.56042480761195179
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4D102C47U, 0xC4E610D7U, 0xF29333BEU, 0x6E45EBE7U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci19937.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci19937.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci19937.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci19937.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci19937
-#define BOOST_RANDOM_VALIDATION_VALUE 0.21779661133680173
+
+#define BOOST_RANDOM_SEED_WORDS 19937*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.24396310480293693
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.48319870930434661
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0029754638678802792
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x5CE9850CU, 0xAA20067BU, 0x4E48643BU, 0xA4A59F4BU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci2281.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci2281.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci2281.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci2281.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci2281
-#define BOOST_RANDOM_VALIDATION_VALUE 0.85870032418398168
+
+#define BOOST_RANDOM_SEED_WORDS 2281*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.91955231927349246
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.58796187519502041
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.087280273457821522
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x7EB0882AU, 0xCE09BE60U, 0xD53046CFU, 0x93257E41U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci23209.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci23209.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci23209.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci23209.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci23209
-#define BOOST_RANDOM_VALIDATION_VALUE 0.98718042717052668
+
+#define BOOST_RANDOM_SEED_WORDS 23209*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.086299988971202168
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.59787206924233871
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0019836425785868528
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4301DE0AU, 0xAD2584E3U, 0x7C28463CU, 0x74848542U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci3217.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci3217.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci3217.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci3217.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci3217
-#define BOOST_RANDOM_VALIDATION_VALUE 0.29923216793615537
+
+#define BOOST_RANDOM_SEED_WORDS 3217*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.54223093970093927
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.51719299526538975
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.1805114746514036
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x4938F127U, 0x86C65CFEU, 0x65356579U, 0xA6CDC325U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci4423.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci4423.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci4423.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci4423.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci4423
-#define BOOST_RANDOM_VALIDATION_VALUE 0.39798595467394815
+
+#define BOOST_RANDOM_SEED_WORDS 4423*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.23188533286820601
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.51262293730517783
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.012893676760814543
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x6D4DBAFU, 0x8039C1A9U, 0x3DA53D58U, 0x95155BE5U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci44497.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci44497.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci44497.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci44497.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci44497
-#define BOOST_RANDOM_VALIDATION_VALUE 0.86191789886161496
+
+#define BOOST_RANDOM_SEED_WORDS 44497*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.12519369894159738
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.63574754742431594
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0019836425785868528
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x6A2DCEA9U, 0x4668EFB4U, 0x711E352FU, 0xA963C43BU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci607.cpp (from r68754, /trunk/libs/random/test/test_lagged_fibonacci607.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci607.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci607.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,4 +13,12 @@
#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.73011070026216984
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.72330291632639643
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x78EB0905U, 0x61766547U, 0xCB507F64U, 0x94FA3EC0U }
+
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_lagged_fibonacci9689.cpp (from r68784, /trunk/libs/random/test/test_lagged_fibonacci9689.cpp)
==============================================================================
--- /trunk/libs/random/test/test_lagged_fibonacci9689.cpp (original)
+++ branches/release/libs/random/test/test_lagged_fibonacci9689.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#include <boost/random/lagged_fibonacci.hpp>
#define BOOST_RANDOM_URNG boost::random::lagged_fibonacci9689
-#define BOOST_RANDOM_VALIDATION_VALUE 0.22728966337376244
+
+#define BOOST_RANDOM_SEED_WORDS 9689*2
+
+#define BOOST_RANDOM_VALIDATION_VALUE 0.059230573043926427
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 0.84199156986666068
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 0.0039672851571737056
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x32EF18BEU, 0x79277C11U, 0xA383438U, 0x32155952U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_linear_feedback_shift.cpp (from r68759, /trunk/libs/random/test/test_linear_feedback_shift.cpp)
==============================================================================
--- /trunk/libs/random/test/test_linear_feedback_shift.cpp (original)
+++ branches/release/libs/random/test/test_linear_feedback_shift.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,6 +13,13 @@
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_VALIDATION_VALUE 981440277
+
+#define BOOST_RANDOM_SEED_WORDS 1
+
+#define BOOST_RANDOM_VALIDATION_VALUE 981440277U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 554836316U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3112279337U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x154005U, 0x54005502U, 0x5502BD4U, 0x2BD4005U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_minstd_rand.cpp (from r68783, /trunk/libs/random/test/test_minstd_rand.cpp)
==============================================================================
--- /trunk/libs/random/test/test_minstd_rand.cpp (original)
+++ branches/release/libs/random/test/test_minstd_rand.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 399268537
+#define BOOST_RANDOM_VALIDATION_VALUE 399268537U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 2096435890U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 182651141U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x8400BC8EU, 0xF45B895FU, 0x145F0F91U, 0xE5F8F088U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_minstd_rand0.cpp (from r68783, /trunk/libs/random/test/test_minstd_rand0.cpp)
==============================================================================
--- /trunk/libs/random/test/test_minstd_rand0.cpp (original)
+++ branches/release/libs/random/test/test_minstd_rand0.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 1043618065
+#define BOOST_RANDOM_VALIDATION_VALUE 1043618065U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 849515105U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 1263181168U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC00041A6U, 0xCD8358EBU, 0x430A4B7AU, 0x31B781ADU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_mt11213b.cpp (from r68783, /trunk/libs/random/test/test_mt11213b.cpp)
==============================================================================
--- /trunk/libs/random/test/test_mt11213b.cpp (original)
+++ branches/release/libs/random/test/test_mt11213b.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#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 770080327U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 2434563197U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xEF3F3F3FU, 0x70082175U, 0xDAF6EAF5U, 0x2A16A63EU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_mt19937.cpp (from r67761, /trunk/libs/random/test/test_mt19937.cpp)
==============================================================================
--- /trunk/libs/random/test/test_mt19937.cpp (original)
+++ branches/release/libs/random/test/test_mt19937.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,4 +13,13 @@
#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 3107690757U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3408548740U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xD091BB5CU, 0x22AE9EF6U, 0xE7E1FAEEU, 0xD5C31F79U }
+
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_mt19937_64.cpp (from r68783, /trunk/libs/random/test/test_mt19937_64.cpp)
==============================================================================
--- /trunk/libs/random/test/test_mt19937_64.cpp (original)
+++ branches/release/libs/random/test/test_mt19937_64.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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(10059787671936601387)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(13543700832025962283)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xF6F6AEA6U, 0xC96D191CU, 0x8BC80F1CU, 0x401F7AC7U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_negative_binomial.cpp (from r65157, /trunk/libs/random/test/test_negative_binomial.cpp)
==============================================================================
--- /trunk/libs/random/test/test_negative_binomial.cpp (original)
+++ branches/release/libs/random/test/test_negative_binomial.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,113 +12,19 @@
#include <boost/random/negative_binomial_distribution.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions/negative_binomial.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "chi_squared_test.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
-bool do_test(int n, double p, long long max) {
- std::cout << "running negative_binomial(" << n << ", " << p << ")" << " " << max << " times: " << std::flush;
-
- int max_value = static_cast<int>(4*n*std::ceil((1-p)/p));
- std::vector<double> expected(max_value+1);
- {
- boost::math::negative_binomial dist(n, p);
- for(int i = 0; i <= max_value; ++i) {
- expected[i] = pdf(dist, i);
- }
- expected.back() += 1-cdf(dist,max_value);
- }
-
- boost::random::negative_binomial_distribution<int, double> dist(n, p);
- boost::mt19937 gen;
- 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 = 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(0, max_n);
- boost::uniform_01<> rdist;
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(idist(gen), rdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_negative_binomial_distribution -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;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_normal.cpp (from r67710, /trunk/libs/random/test/test_normal.cpp)
==============================================================================
--- /trunk/libs/random/test/test_normal.cpp (original)
+++ branches/release/libs/random/test/test_normal.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,102 +10,19 @@
*/
#include <boost/random/normal_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/normal.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double m, double s, int max) {
- std::cout << "running normal(" << m << ", " << s << ")" << " " << max << " times: " << std::flush;
-
- boost::math::normal expected(m, s);
-
- boost::random::normal_distribution<> dist(m, s);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::normal_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_m, double max_s, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> mdist(-max_m, max_m);
- boost::uniform_real<> sdist(0.00001, max_s);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(mdist(gen), sdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_normal -r <repeat> -m <max mean> -s <max sigma> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_m = 1000.0;
- double max_s = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, 'm', max_m)
- && !handle_option(argc, argv, 's', max_s)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_m, max_s, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_old_uniform_int_distribution.cpp (from r68647, /trunk/libs/random/test/test_old_uniform_int_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_old_uniform_int_distribution.cpp (original)
+++ branches/release/libs/random/test/test_old_uniform_int_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -36,3 +36,41 @@
#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());
+}
Copied: branches/release/libs/random/test/test_old_uniform_real.cpp (from r68647, /trunk/libs/random/test/test_old_uniform_real.cpp)
==============================================================================
--- /trunk/libs/random/test/test_old_uniform_real.cpp (original)
+++ branches/release/libs/random/test/test_old_uniform_real.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,7 +10,6 @@
*/
#include <boost/random/uniform_real.hpp>
-#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/uniform.hpp>
#define BOOST_RANDOM_DISTRIBUTION boost::uniform_real<>
Copied: branches/release/libs/random/test/test_piecewise_constant.cpp (from r67740, /trunk/libs/random/test/test_piecewise_constant.cpp)
==============================================================================
--- /trunk/libs/random/test/test_piecewise_constant.cpp (original)
+++ branches/release/libs/random/test/test_piecewise_constant.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,55 +14,86 @@
#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 <numeric>
+#include <iomanip>
-#include "chi_squared_test.hpp"
+#include "statistic_tests.hpp"
-bool do_test(int n, long long max) {
+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> expected;
+ std::vector<double> weights;
{
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;
+ 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, expected);
+ boost::random::piecewise_constant_distribution<> dist(intervals, weights);
boost::mt19937 gen;
- std::vector<long long> results(expected.size());
- for(long long i = 0; i < max; ++i) {
- ++results[static_cast<std::size_t>(dist(gen))];
- }
+ kolmogorov_experiment test(max);
+ boost::variate_generator<boost::mt19937&, boost::random::piecewise_constant_distribution<> > vgen(gen, dist);
- 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);
+ double prob = test.probability(test.run(vgen, expected));
- bool result = chsqr < 0.99;
+ bool result = prob < 0.99;
const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << chsqr << err << std::endl;
+ std::cout << std::setprecision(17) << prob << err << std::endl;
std::cout << std::setprecision(6);
return result;
}
-bool do_tests(int repeat, int max_n, long long trials) {
+bool do_tests(int repeat, int max_n, int trials) {
boost::mt19937 gen;
boost::uniform_int<> idist(1, max_n);
int errors = 0;
@@ -96,8 +127,8 @@
int main(int argc, char** argv) {
int repeat = 10;
- int max_n = 100000;
- long long trials = 1000000ll;
+ int max_n = 10;
+ int trials = 1000000;
if(argc > 0) {
--argc;
Copied: branches/release/libs/random/test/test_piecewise_constant_distribution.cpp (from r67740, /trunk/libs/random/test/test_piecewise_constant_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_piecewise_constant_distribution.cpp (original)
+++ branches/release/libs/random/test/test_piecewise_constant_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,10 +14,15 @@
#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;
@@ -52,22 +57,46 @@
};
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);
@@ -86,6 +115,8 @@
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();
@@ -113,14 +144,26 @@
{ 99, 103, 107, 111, 115 },
gen()
};
- CHECK_SEQUENCE(param_il.intervals(), list_of(99)(103)(107)(111)(115));
- CHECK_SEQUENCE(param_il.densities(), list_of(.03125)(.0625)(.03125)(.125));
+ 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());
@@ -128,9 +171,19 @@
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) {
Copied: branches/release/libs/random/test/test_piecewise_linear.cpp (from r68028, /trunk/libs/random/test/test_piecewise_linear.cpp)
==============================================================================
--- /trunk/libs/random/test/test_piecewise_linear.cpp (original)
+++ branches/release/libs/random/test/test_piecewise_linear.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,63 +12,107 @@
#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 <numeric>
+#include <iomanip>
-#include "chi_squared_test.hpp"
+#include "statistic_tests.hpp"
-bool do_test(int n, long long max) {
+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;
- std::vector<double> expected;
{
boost::mt19937 egen;
for(int i = 0; i < n; ++i) {
weights.push_back(egen());
}
- for(int i = 0; i < n - 1; ++i) {
- expected.push_back((weights[i] + weights[i + 1]) / 2);
- }
- 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;
- }
}
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;
- std::vector<long long> results(expected.size());
- for(long long i = 0; i < max; ++i) {
- ++results[static_cast<std::size_t>(dist(gen))];
- }
+ kolmogorov_experiment test(max);
+ boost::variate_generator<boost::mt19937&, boost::random::piecewise_linear_distribution<> > vgen(gen, dist);
- 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);
+ double prob = test.probability(test.run(vgen, expected));
- bool result = chsqr < 0.99;
+ bool result = prob < 0.99;
const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << chsqr << err << std::endl;
+ std::cout << std::setprecision(17) << prob << err << std::endl;
std::cout << std::setprecision(6);
return result;
}
-bool do_tests(int repeat, int max_n, long long trials) {
+bool do_tests(int repeat, int max_n, int trials) {
boost::mt19937 gen;
- boost::uniform_int<> idist(1, max_n);
+ boost::uniform_int<> idist(2, max_n);
int errors = 0;
for(int i = 0; i < repeat; ++i) {
if(!do_test(idist(gen), trials)) {
@@ -100,8 +144,8 @@
int main(int argc, char** argv) {
int repeat = 10;
- int max_n = 100000;
- long long trials = 1000000ll;
+ int max_n = 10;
+ int trials = 1000000;
if(argc > 0) {
--argc;
Copied: branches/release/libs/random/test/test_piecewise_linear_distribution.cpp (from r68028, /trunk/libs/random/test/test_piecewise_linear_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_piecewise_linear_distribution.cpp (original)
+++ branches/release/libs/random/test/test_piecewise_linear_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -14,10 +14,15 @@
#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;
Copied: branches/release/libs/random/test/test_poisson.cpp (from r63126, /trunk/libs/random/test/test_poisson.cpp)
==============================================================================
--- /trunk/libs/random/test/test_poisson.cpp (original)
+++ branches/release/libs/random/test/test_poisson.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -11,112 +11,15 @@
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/uniform_real.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions/poisson.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "chi_squared_test.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)
-bool do_test(double mean, long long max) {
- std::cout << "running poisson(" << mean << ")" << " " << max << " times: " << std::flush;
-
- int max_value = static_cast<int>(mean * 4);
- std::vector<double> expected(max_value+1);
- {
- boost::math::poisson dist(mean);
- for(int i = 0; i <= max_value; ++i) {
- expected[i] = pdf(dist, i);
- }
- expected.back() += 1 - cdf(dist, max_value);
- }
-
- boost::random::poisson_distribution<int, double> dist(mean);
- boost::mt19937 gen;
- 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 = 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, double max_mean, long long trials) {
- boost::mt19937 gen;
- boost::uniform_real<> rdist(1e-15, max_mean);
- 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_poisson -r <repeat> -m <max mean> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_mean = 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, 'm', max_mean)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_mean, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_poisson_distribution.cpp (from r63126, /trunk/libs/random/test/test_poisson_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_poisson_distribution.cpp (original)
+++ branches/release/libs/random/test/test_poisson_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,95 +10,24 @@
*/
#include <boost/random/poisson_distribution.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <sstream>
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
+#include <limits>
-BOOST_AUTO_TEST_CASE(test_constructors) {
- boost::random::poisson_distribution<> dist;
- BOOST_CHECK_EQUAL(dist.mean(), 1.0);
- boost::random::poisson_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL(dist_one.mean(), 7.5);
- boost::random::poisson_distribution<> copy(dist);
- BOOST_CHECK_EQUAL(dist, copy);
- boost::random::poisson_distribution<> copy_one(dist_one);
- BOOST_CHECK_EQUAL(dist_one, copy_one);
-}
-
-BOOST_AUTO_TEST_CASE(test_param) {
- boost::random::poisson_distribution<> dist(7.5);
- boost::random::poisson_distribution<>::param_type param = dist.param();
- BOOST_CHECK_EQUAL(param.mean(), 7.5);
- boost::random::poisson_distribution<> copy1(param);
- BOOST_CHECK_EQUAL(dist, copy1);
- boost::random::poisson_distribution<> copy2;
- copy2.param(param);
- BOOST_CHECK_EQUAL(dist, copy2);
-
- boost::random::poisson_distribution<>::param_type param_copy = param;
- BOOST_CHECK_EQUAL(param, param_copy);
- BOOST_CHECK(param == param_copy);
- BOOST_CHECK(!(param != param_copy));
- boost::random::poisson_distribution<>::param_type param_default;
- BOOST_CHECK_EQUAL(param_default.mean(), 1.0);
- BOOST_CHECK(param != param_default);
- BOOST_CHECK(!(param == param_default));
- boost::random::poisson_distribution<>::param_type param_one(7.5);
- BOOST_CHECK_EQUAL(param_one.mean(), 7.5);
- BOOST_CHECK(param_default != param_one);
- BOOST_CHECK(!(param_default == param_one));
-}
-
-BOOST_AUTO_TEST_CASE(test_min_max) {
- boost::random::poisson_distribution<> dist;
- BOOST_CHECK_EQUAL((dist.min)(), 0);
- BOOST_CHECK_EQUAL((dist.max)(), (std::numeric_limits<int>::max)());
- boost::random::poisson_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL((dist_one.min)(), 0);
- BOOST_CHECK_EQUAL((dist_one.max)(), (std::numeric_limits<int>::max)());
-}
-
-BOOST_AUTO_TEST_CASE(test_comparison) {
- boost::random::poisson_distribution<> dist;
- boost::random::poisson_distribution<> dist_copy(dist);
- boost::random::poisson_distribution<> dist_one(7.5);
- boost::random::poisson_distribution<> dist_one_copy(dist_one);
- 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));
-}
-
-BOOST_AUTO_TEST_CASE(test_streaming) {
- boost::random::poisson_distribution<> dist(7.5);
- std::stringstream stream;
- stream << dist;
- boost::random::poisson_distribution<> restored_dist;
- stream >> restored_dist;
- BOOST_CHECK_EQUAL(dist, restored_dist);
-}
-
-BOOST_AUTO_TEST_CASE(test_generation) {
- boost::minstd_rand0 gen;
- boost::random::poisson_distribution<> dist;
- boost::random::poisson_distribution<> dist_1000(1000);
- for(int i = 0; i < 10; ++i) {
- // Basic sanity checks. Technically these tests are incorrect,
- // since the range of a poisson_distribution is [0, inf), but
- // the probability that there's an error is very small.
- int value = dist(gen);
- BOOST_CHECK_GE(value, 0);
- BOOST_CHECK_LE(value, 10);
- int value_two = dist_1000(gen);
- BOOST_CHECK_GE(value_two, 10);
- int value_param = dist_1000(gen, dist.param());
- BOOST_CHECK_GE(value_param, 0);
- BOOST_CHECK_LE(value_param, 10);
- int value_two_param = dist(gen, dist_1000.param());
- BOOST_CHECK_GE(value_two_param, 10);
- }
-}
+#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"
Copied: branches/release/libs/random/test/test_rand48.cpp (from r68783, /trunk/libs/random/test/test_rand48.cpp)
==============================================================================
--- /trunk/libs/random/test/test_rand48.cpp (original)
+++ branches/release/libs/random/test/test_rand48.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,14 +13,14 @@
#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 1993516219
+#define BOOST_RANDOM_VALIDATION_VALUE 1993516219U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1127873718U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 839037874U
-// rand48 uses non-standard seeding
-template<class Converted, class T>
-void test_seed_conversion(boost::rand48 & urng, const T & t) {
- boost::rand48 urng2(t);
- urng2.seed(t);
-}
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55424A4U, 0x3A2CCEF5U, 0x6ADB4A65U, 0x2B019719U }
#include "test_generator.ipp"
Modified: branches/release/libs/random/test/test_random_device.cpp
==============================================================================
--- branches/release/libs/random/test/test_random_device.cpp (original)
+++ branches/release/libs/random/test/test_random_device.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -8,19 +8,22 @@
* $Id$
*/
-#include <boost/nondet_random.hpp>
+#include <boost/random/random_device.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
-int test_main(int argc, char** argv) {
- 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)());
- }
- return 0;
+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;
}
Copied: branches/release/libs/random/test/test_ranlux24.cpp (from r68783, /trunk/libs/random/test/test_ranlux24.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux24.cpp (original)
+++ branches/release/libs/random/test/test_ranlux24.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 9901578
+#define BOOST_RANDOM_VALIDATION_VALUE 9901578U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 4870344U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3888733U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux24_base.cpp (from r68784, /trunk/libs/random/test/test_ranlux24_base.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux24_base.cpp (original)
+++ branches/release/libs/random/test/test_ranlux24_base.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,7 +12,14 @@
#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 7937952
+#define BOOST_RANDOM_VALIDATION_VALUE 7937952U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 836370U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 7739608U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux3.cpp (from r68783, /trunk/libs/random/test/test_ranlux3.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux3.cpp (original)
+++ branches/release/libs/random/test/test_ranlux3.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,7 +12,14 @@
#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 5957620
+#define BOOST_RANDOM_VALIDATION_VALUE 5957620U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 1848500U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 11620328U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux3_01.cpp (from r68783, /trunk/libs/random/test/test_ranlux3_01.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux3_01.cpp (original)
+++ branches/release/libs/random/test/test_ranlux3_01.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 1848500/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"
Copied: branches/release/libs/random/test/test_ranlux4.cpp (from r68783, /trunk/libs/random/test/test_ranlux4.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux4.cpp (original)
+++ branches/release/libs/random/test/test_ranlux4.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,7 +12,14 @@
#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 8587295
+#define BOOST_RANDOM_VALIDATION_VALUE 8587295U
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE 6375782U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 4515722U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x55E57B2CU, 0xF2DEF915U, 0x6D1A0CD9U, 0xCA0109F9U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux48.cpp (from r68783, /trunk/libs/random/test/test_ranlux48.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux48.cpp (original)
+++ branches/release/libs/random/test/test_ranlux48.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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(93216637457044)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(154356577406237)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xFCE57B2CU, 0xF2DF1555U, 0x1A0C0CD9U, 0x490109FAU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux48_base.cpp (from r68784, /trunk/libs/random/test/test_ranlux48_base.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux48_base.cpp (original)
+++ branches/release/libs/random/test/test_ranlux48_base.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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(107228250000854)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(172853405006548)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xFCE57B2CU, 0xF2DF1555U, 0x1A0C0CD9U, 0x490109FAU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux4_01.cpp (from r68783, /trunk/libs/random/test/test_ranlux4_01.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux4_01.cpp (original)
+++ branches/release/libs/random/test/test_ranlux4_01.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 6375782/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"
Copied: branches/release/libs/random/test/test_ranlux64_3.cpp (from r68783, /trunk/libs/random/test/test_ranlux64_3.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux64_3.cpp (original)
+++ branches/release/libs/random/test/test_ranlux64_3.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,10 +10,18 @@
*/
#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 141789170949364
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(141789170949364)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(97179253367494)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(101724473226966)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux64_3_01.cpp (from r68783, /trunk/libs/random/test/test_ranlux64_3_01.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux64_3_01.cpp (original)
+++ branches/release/libs/random/test/test_ranlux64_3_01.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 0.83841253976454766
+#define BOOST_RANDOM_VALIDATION_VALUE INT64_C(141789170949364)/std::pow(2.0, 48)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(97179253367494)/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"
Copied: branches/release/libs/random/test/test_ranlux64_4.cpp (from r68783, /trunk/libs/random/test/test_ranlux64_4.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux64_4.cpp (original)
+++ branches/release/libs/random/test/test_ranlux64_4.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,10 +10,18 @@
*/
#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 199461971133682
+#define BOOST_RANDOM_VALIDATION_VALUE UINT64_C(199461971133682)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(63570328604787)
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE UINT64_C(40074210927900)
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0xC35F616BU, 0xDC3C4DF1U, 0xF3F90D0AU, 0x206F9C9EU }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_ranlux64_4_01.cpp (from r68783, /trunk/libs/random/test/test_ranlux64_4_01.cpp)
==============================================================================
--- /trunk/libs/random/test/test_ranlux64_4_01.cpp (original)
+++ branches/release/libs/random/test/test_ranlux64_4_01.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -13,7 +13,14 @@
#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 0.59838973302498744
+#define BOOST_RANDOM_VALIDATION_VALUE INT64_C(199461971133682)/std::pow(2.0, 48)
+#define BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE UINT64_C(63570328604787)/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"
Copied: branches/release/libs/random/test/test_real_distribution.ipp (from r68372, /trunk/libs/random/test/test_real_distribution.ipp)
==============================================================================
--- /trunk/libs/random/test/test_real_distribution.ipp (original)
+++ branches/release/libs/random/test/test_real_distribution.ipp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -17,19 +17,35 @@
#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
- int max) {
+ 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
@@ -39,18 +55,42 @@
BOOST_MATH_DISTRIBUTION expected BOOST_MATH_DISTRIBUTION_INIT;
- BOOST_RANDOM_DISTRIBUTION dist(BOOST_RANDOM_ARG1_NAME
-#ifdef BOOST_RANDOM_ARG2_NAME
- , BOOST_RANDOM_ARG2_NAME
-#endif
- );
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
+ 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));
- bool result = prob < 0.99;
+#endif
+
+ bool result = prob < BOOST_RANDOM_P_CUTOFF;
const char* err = result? "" : "*";
std::cout << std::setprecision(17) << prob << err << std::endl;
@@ -68,7 +108,7 @@
#ifdef BOOST_RANDOM_ARG2_NAME
Dist2 d2,
#endif
- int trials) {
+ long long trials) {
boost::mt19937 gen;
int errors = 0;
for(int i = 0; i < repeat; ++i) {
@@ -76,7 +116,7 @@
#ifdef BOOST_RANDOM_ARG2_NAME
d2(gen),
#endif
- trials)) {
+ trials, gen)) {
++errors;
}
}
@@ -112,12 +152,12 @@
}
int main(int argc, char** argv) {
- int repeat = 10;
+ 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
- int trials = 1000000;
+ long long trials = 100000;
if(argc > 0) {
--argc;
Copied: branches/release/libs/random/test/test_student_t.cpp (from r67710, /trunk/libs/random/test/test_student_t.cpp)
==============================================================================
--- /trunk/libs/random/test/test_student_t.cpp (original)
+++ branches/release/libs/random/test/test_student_t.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,99 +10,15 @@
*/
#include <boost/random/student_t_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions/students_t.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double n, int max) {
- std::cout << "running student_t(" << n << ")" << " " << max << " times: " << std::flush;
-
- boost::math::students_t expected(n);
-
- boost::random::student_t_distribution<> dist(n);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::student_t_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_n, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> ndist(0.00001, max_n);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(ndist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_student_t -r <repeat> -n <max n> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_n = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, '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;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_taus88.cpp (from r68767, /trunk/libs/random/test/test_taus88.cpp)
==============================================================================
--- /trunk/libs/random/test/test_taus88.cpp (original)
+++ branches/release/libs/random/test/test_taus88.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -12,6 +12,13 @@
#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 2005586065U
+#define BOOST_RANDOM_ITERATOR_VALIDATION_VALUE 3762466828U
+
+#define BOOST_RANDOM_GENERATE_VALUES { 0x2B55504U, 0x5403F102U, 0xED45297EU, 0x6B84007U }
#include "test_generator.ipp"
Copied: branches/release/libs/random/test/test_uniform_int.cpp (from r68440, /trunk/libs/random/test/test_uniform_int.cpp)
==============================================================================
--- /trunk/libs/random/test/test_uniform_int.cpp (original)
+++ branches/release/libs/random/test/test_uniform_int.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -10,7 +10,7 @@
*/
#include <boost/random/uniform_int_distribution.hpp>
-#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_int.hpp>
#include <boost/math/distributions/uniform.hpp>
#define BOOST_RANDOM_DISTRIBUTION boost::random::uniform_int_distribution<>
Copied: branches/release/libs/random/test/test_uniform_int_distribution.cpp (from r68440, /trunk/libs/random/test/test_uniform_int_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_uniform_int_distribution.cpp (original)
+++ branches/release/libs/random/test/test_uniform_int_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -36,3 +36,7 @@
#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"
Copied: branches/release/libs/random/test/test_weibull.cpp (from r63328, /trunk/libs/random/test/test_weibull.cpp)
==============================================================================
--- /trunk/libs/random/test/test_weibull.cpp (original)
+++ branches/release/libs/random/test/test_weibull.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,4 +1,4 @@
-/* test_gamma.cpp
+/* test_weibull.cpp
*
* Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
@@ -10,102 +10,19 @@
*/
#include <boost/random/weibull_distribution.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_01.hpp>
-#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
#include <boost/math/distributions/weibull.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/exception/diagnostic_information.hpp>
-#include <vector>
-#include <iostream>
-#include <numeric>
-#include "statistic_tests.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)
-bool do_test(double alpha, double beta, int max) {
- std::cout << "running gamma(" << alpha << ", " << beta << ")" << " " << max << " times: " << std::flush;
-
- boost::math::weibull_distribution<> expected(alpha, beta);
-
- boost::random::weibull_distribution<> dist(alpha, beta);
- boost::mt19937 gen;
- kolmogorov_experiment test(max);
- boost::variate_generator<boost::mt19937&, boost::random::weibull_distribution<> > vgen(gen, dist);
-
- double prob = test.probability(test.run(vgen, expected));
-
- bool result = prob < 0.99;
- const char* err = result? "" : "*";
- std::cout << std::setprecision(17) << prob << err << std::endl;
-
- std::cout << std::setprecision(6);
-
- return result;
-}
-
-bool do_tests(int repeat, double max_a, double max_b, int trials) {
- boost::mt19937 gen;
- boost::uniform_real<> adist(0.00001, max_a);
- boost::uniform_real<> bdist(0.00001, max_b);
- int errors = 0;
- for(int i = 0; i < repeat; ++i) {
- if(!do_test(adist(gen), bdist(gen), trials)) {
- ++errors;
- }
- }
- if(errors != 0) {
- std::cout << "*** " << errors << " errors detected ***" << std::endl;
- }
- return errors == 0;
-}
-
-int usage() {
- std::cerr << "Usage: test_weibull -r <repeat> -a <max a> -b <max b> -t <trials>" << std::endl;
- return 2;
-}
-
-template<class T>
-bool handle_option(int& argc, char**& argv, char opt, T& value) {
- if(argv[0][1] == opt && argc > 1) {
- --argc;
- ++argv;
- value = boost::lexical_cast<T>(argv[0]);
- return true;
- } else {
- return false;
- }
-}
-
-int main(int argc, char** argv) {
- int repeat = 10;
- double max_a = 1000.0;
- double max_b = 1000.0;
- int trials = 1000000;
-
- if(argc > 0) {
- --argc;
- ++argv;
- }
- while(argc > 0) {
- if(argv[0][0] != '-') return usage();
- else if(!handle_option(argc, argv, 'r', repeat)
- && !handle_option(argc, argv, 'a', max_a)
- && !handle_option(argc, argv, 'b', max_b)
- && !handle_option(argc, argv, 't', trials)) {
- return usage();
- }
- --argc;
- ++argv;
- }
-
- try {
- if(do_tests(repeat, max_a, max_b, trials)) {
- return 0;
- } else {
- return EXIT_FAILURE;
- }
- } catch(...) {
- std::cerr << boost::current_exception_diagnostic_information() << std::endl;
- return EXIT_FAILURE;
- }
-}
+#include "test_real_distribution.ipp"
Copied: branches/release/libs/random/test/test_weibull_distribution.cpp (from r63328, /trunk/libs/random/test/test_weibull_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_weibull_distribution.cpp (original)
+++ branches/release/libs/random/test/test_weibull_distribution.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
@@ -1,4 +1,4 @@
-/* test_gamma_distribution.cpp
+/* test_weibull_distribution.cpp
*
* Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
@@ -8,125 +8,29 @@
* $Id$
*
*/
-
#include <boost/random/weibull_distribution.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <sstream>
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-
-BOOST_AUTO_TEST_CASE(test_constructors) {
- boost::random::weibull_distribution<> dist;
- BOOST_CHECK_EQUAL(dist.a(), 1.0);
- BOOST_CHECK_EQUAL(dist.b(), 1.0);
- boost::random::weibull_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL(dist_one.a(), 7.5);
- BOOST_CHECK_EQUAL(dist_one.b(), 1.0);
- boost::random::weibull_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(dist_two.a(), 7.5);
- BOOST_CHECK_EQUAL(dist_two.b(), 0.25);
- boost::random::weibull_distribution<> copy(dist);
- BOOST_CHECK_EQUAL(dist, copy);
- boost::random::weibull_distribution<> copy_one(dist_one);
- BOOST_CHECK_EQUAL(dist_one, copy_one);
- boost::random::weibull_distribution<> copy_two(dist_two);
- BOOST_CHECK_EQUAL(dist_two, copy_two);
-}
-
-BOOST_AUTO_TEST_CASE(test_param) {
- boost::random::weibull_distribution<> dist(7.5, 0.25);
- boost::random::weibull_distribution<>::param_type param = dist.param();
- BOOST_CHECK_EQUAL(param.a(), 7.5);
- BOOST_CHECK_EQUAL(param.b(), 0.25);
- boost::random::weibull_distribution<> copy1(param);
- BOOST_CHECK_EQUAL(dist, copy1);
- boost::random::weibull_distribution<> copy2;
- copy2.param(param);
- BOOST_CHECK_EQUAL(dist, copy2);
-
- boost::random::weibull_distribution<>::param_type param_copy = param;
- BOOST_CHECK_EQUAL(param, param_copy);
- BOOST_CHECK(param == param_copy);
- BOOST_CHECK(!(param != param_copy));
- boost::random::weibull_distribution<>::param_type param_default;
- BOOST_CHECK_EQUAL(param_default.a(), 1.0);
- BOOST_CHECK_EQUAL(param_default.b(), 1.0);
- BOOST_CHECK(param != param_default);
- BOOST_CHECK(!(param == param_default));
- boost::random::weibull_distribution<>::param_type param_one(7.5);
- BOOST_CHECK_EQUAL(param_one.a(), 7.5);
- BOOST_CHECK_EQUAL(param_one.b(), 1.0);
- BOOST_CHECK(param != param_one);
- BOOST_CHECK(!(param == param_one));
- BOOST_CHECK(param_default != param_one);
- BOOST_CHECK(!(param_default == param_one));
- boost::random::weibull_distribution<>::param_type param_two(7.5, 0.25);
- BOOST_CHECK_EQUAL(param_two.a(), 7.5);
- BOOST_CHECK_EQUAL(param_two.b(), 0.25);
-}
-
-BOOST_AUTO_TEST_CASE(test_min_max) {
- boost::random::weibull_distribution<> dist;
- BOOST_CHECK_EQUAL((dist.min)(), 0);
- BOOST_CHECK_EQUAL((dist.max)(), (std::numeric_limits<double>::infinity)());
- boost::random::weibull_distribution<> dist_one(7.5);
- BOOST_CHECK_EQUAL((dist_one.min)(), 0);
- BOOST_CHECK_EQUAL((dist_one.max)(), (std::numeric_limits<double>::infinity)());
- boost::random::weibull_distribution<> dist_two(7.5, 0.25);
- BOOST_CHECK_EQUAL((dist_two.min)(), 0);
- BOOST_CHECK_EQUAL((dist_two.max)(), (std::numeric_limits<double>::infinity)());
-}
+#include <limits>
-BOOST_AUTO_TEST_CASE(test_comparison) {
- boost::random::weibull_distribution<> dist;
- boost::random::weibull_distribution<> dist_copy(dist);
- boost::random::weibull_distribution<> dist_one(7.5);
- boost::random::weibull_distribution<> dist_one_copy(dist_one);
- boost::random::weibull_distribution<> dist_two(7.5, 0.25);
- boost::random::weibull_distribution<> dist_two_copy(dist_two);
- BOOST_CHECK(dist == dist_copy);
- BOOST_CHECK(!(dist != dist_copy));
- BOOST_CHECK(dist_one == dist_one_copy);
- BOOST_CHECK(!(dist_one != dist_one_copy));
- BOOST_CHECK(dist_two == dist_two_copy);
- BOOST_CHECK(!(dist_two != dist_two_copy));
- BOOST_CHECK(dist != dist_one);
- BOOST_CHECK(!(dist == dist_one));
- BOOST_CHECK(dist != dist_two);
- BOOST_CHECK(!(dist == dist_two));
- BOOST_CHECK(dist_one != dist_two);
- BOOST_CHECK(!(dist_one == dist_two));
-}
+#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
-BOOST_AUTO_TEST_CASE(test_streaming) {
- boost::random::weibull_distribution<> dist(7.5, 0.25);
- std::stringstream stream;
- stream << dist;
- boost::random::weibull_distribution<> restored_dist;
- stream >> restored_dist;
- BOOST_CHECK_EQUAL(dist, restored_dist);
-}
+#define BOOST_RANDOM_TEST2_PARAMS (1.0, 1000000.0)
+#define BOOST_RANDOM_TEST2_MIN 100.0
-BOOST_AUTO_TEST_CASE(test_generation) {
- boost::minstd_rand0 gen;
- boost::random::weibull_distribution<> dist;
- boost::random::weibull_distribution<> dist_two(1.0, 1000000.0);
- for(int i = 0; i < 10; ++i) {
- // This test is not guaranteed to work, since
- // a weibull distribution with a large scale parameter
- // can produce small values and a distribution with
- // a small scale can produce large values, but the
- // chances of failure are small.
- double value = dist(gen);
- BOOST_CHECK_GE(value, 0.0);
- BOOST_CHECK_LE(value, 100.0);
- double value_two = dist_two(gen);
- BOOST_CHECK_GE(value_two, 100.0);
- double value_param = dist_two(gen, dist.param());
- BOOST_CHECK_GE(value_param, 0);
- BOOST_CHECK_LE(value_param, 100.0);
- double value_two_param = dist(gen, dist_two.param());
- BOOST_CHECK_GE(value_two_param, 100.0);
- }
-}
+#include "test_distribution.ipp"
Deleted: branches/release/libs/random/test/validate.cpp
==============================================================================
--- branches/release/libs/random/test/validate.cpp 2011-04-05 17:27:52 EDT (Tue, 05 Apr 2011)
+++ (empty file)
@@ -1,131 +0,0 @@
-/* boost validate.cpp
- *
- * 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$
- */
-
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-#pragma warning( disable : 4786 )
-#endif
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <cmath>
-#include <iterator>
-#include <vector>
-#include <boost/random.hpp>
-#include <boost/config.hpp>
-
-#include <boost/test/test_tools.hpp>
-#include <boost/test/included/test_exec_monitor.hpp>
-
-#ifdef BOOST_NO_STDC_NAMESPACE
- namespace std { using ::abs; using ::fabs; using ::pow; }
-#endif
-
-
-/*
- * General portability note:
- * MSVC mis-compiles explicit function template instantiations.
- * For example, f<A>() and f<B>() are both compiled to call f<A>().
- * BCC is unable to implicitly convert a "const char *" to a std::string
- * when using explicit function template instantiations.
- *
- * Therefore, avoid explicit function template instantiations.
- */
-
-/*
- * Validate correct implementation
- */
-
-// own run
-bool check_(unsigned long x, const boost::mt11213b&) { return x == 3809585648U; }
-
-// validation by experiment from mt19937.c
-bool check_(unsigned long x, const boost::mt19937&) { return x == 4123659995U; }
-
-// validation values from the publications
-bool check_(int x, const boost::minstd_rand0&) { return x == 1043618065; }
-
-// validation values from the publications
-bool check_(int x, const boost::minstd_rand&) { return x == 399268537; }
-
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-// by experiment from lrand48()
-bool check_(unsigned long x, const boost::rand48&) { return x == 1993516219; }
-#endif
-
-// ????
-bool check_(unsigned long x, const boost::taus88&) { return x == 3535848941U; }
-
-// ????
-bool check_(int x, const boost::ecuyer1988&) { return x == 2060321752; }
-
-// validation by experiment from Harry Erwin's generator.h (private e-mail)
-bool check_(unsigned int x, const boost::kreutzer1986&) { return x == 139726; }
-
-bool check_(double x, const boost::lagged_fibonacci607&) { return std::abs(x-0.401269) < 1e-5; }
-
-// principal operation validated with CLHEP, values by experiment
-bool check_(unsigned long x, const boost::ranlux3&) { return x == 5957620; }
-bool check_(unsigned long x, const boost::ranlux4&) { return x == 8587295; }
-
-bool check_(float x, const boost::ranlux3_01&)
-{ return std::abs(x-5957620/std::pow(2.0f,24)) < 1e-6; }
-bool check_(float x, const boost::ranlux4_01&)
-{ return std::abs(x-8587295/std::pow(2.0f,24)) < 1e-6; }
-
-bool check_(double x, const boost::ranlux64_3_01&)
-{ return std::abs(x-0.838413) < 1e-6; }
-bool check_(double x, const boost::ranlux64_4_01&)
-{ return std::abs(x-0.59839) < 1e-6; }
-
-template<class PRNG>
-void validate(const std::string & name, const PRNG &)
-{
- std::cout << "validating " << name << ": ";
- PRNG rng; // default ctor
- for(int i = 0; i < 9999; i++)
- rng();
- typename PRNG::result_type val = rng();
- // make sure the validation function is a static member
- bool result = check_(val, rng);
-
- // allow for a simple eyeball check for MSVC instantiation brokenness
- // (if the numbers for all generators are the same, it's obviously broken)
- std::cout << val << std::endl;
- BOOST_CHECK(result);
-}
-
-void validate_all()
-{
- using namespace boost;
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
- validate("rand48", rand48());
-#endif
- validate("minstd_rand", minstd_rand());
- validate("minstd_rand0", minstd_rand0());
- validate("ecuyer combined", ecuyer1988());
- validate("mt11213b", mt11213b());
- validate("mt19937", mt19937());
- validate("kreutzer1986", kreutzer1986());
- validate("ranlux3", ranlux3());
- validate("ranlux4", ranlux4());
- validate("ranlux3_01", ranlux3_01());
- validate("ranlux4_01", ranlux4_01());
- validate("ranlux64_3_01", ranlux64_3_01());
- validate("ranlux64_4_01", ranlux64_4_01());
- validate("taus88", taus88());
- validate("lagged_fibonacci607", lagged_fibonacci607());
-}
-
-int test_main(int, char*[])
-{
- validate_all();
- return 0;
-}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk