diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/random/test/test_uniform_int.ipp | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/random/test/test_uniform_int.ipp')
-rw-r--r-- | src/boost/libs/random/test/test_uniform_int.ipp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/boost/libs/random/test/test_uniform_int.ipp b/src/boost/libs/random/test/test_uniform_int.ipp new file mode 100644 index 000000000..fe35c39a2 --- /dev/null +++ b/src/boost/libs/random/test/test_uniform_int.ipp @@ -0,0 +1,149 @@ +/* boost test_uniform_int.ipp + * + * Copyright Jens Maurer 2000 + * Copyright Steven Watanabe 2011 + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * $Id$ + */ + +#include <numeric> +#include <sstream> +#include <vector> +#include <boost/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/limits.hpp> +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/linear_congruential.hpp> +#include <boost/random/lagged_fibonacci.hpp> +#include <boost/random/variate_generator.hpp> +#include "chi_squared_test.hpp" + +#define BOOST_TEST_MAIN +#include <boost/test/unit_test.hpp> + +template<class Generator> +void check_uniform_int(Generator & gen, int iter) +{ + int range = (gen.max)()-(gen.min)()+1; + std::vector<int> bucket(range); + for(int j = 0; j < iter; j++) { + int result = gen(); + BOOST_CHECK_GE(result, (gen.min)()); + BOOST_CHECK_LE(result, (gen.max)()); + if(result >= (gen.min)() && result <= (gen.max)()) { + bucket[result-(gen.min)()]++; + } + } + int sum = std::accumulate(bucket.begin(), bucket.end(), 0); + std::vector<double> expected(range, 1.0 / range); + BOOST_CHECK_LT(chi_squared_test(bucket, expected, sum), 0.99); +} + +BOOST_AUTO_TEST_CASE(test_uniform_int) +{ + boost::random::mt19937 gen; + typedef BOOST_RANDOM_UNIFORM_INT<int> int_gen; + + // large range => small range (modulo case) + typedef boost::random::variate_generator<boost::random::mt19937&, int_gen> level_one; + + level_one uint12(gen, int_gen(1,2)); + BOOST_CHECK((uint12.distribution().min)() == 1); + BOOST_CHECK((uint12.distribution().max)() == 2); + check_uniform_int(uint12, 100000); + level_one uint16(gen, int_gen(1,6)); + check_uniform_int(uint16, 100000); + + // test chaining to get all cases in operator() + + // identity map + typedef boost::random::variate_generator<level_one&, int_gen> level_two; + level_two uint01(uint12, int_gen(0, 1)); + check_uniform_int(uint01, 100000); + + // small range => larger range + level_two uint05(uint12, int_gen(-3, 2)); + check_uniform_int(uint05, 100000); + + // small range => larger range + level_two uint099(uint12, int_gen(0, 99)); + check_uniform_int(uint099, 100000); + + // larger => small range, rejection case + typedef boost::random::variate_generator<level_two&, int_gen> level_three; + level_three uint1_4(uint05, int_gen(1, 4)); + check_uniform_int(uint1_4, 100000); + + typedef BOOST_RANDOM_UNIFORM_INT<boost::uint8_t> int8_gen; + typedef boost::random::variate_generator<boost::random::mt19937&, int8_gen> gen8_t; + + gen8_t gen8_03(gen, int8_gen(0, 3)); + + // use the full range of the type, where the destination + // range is a power of the source range + typedef boost::random::variate_generator<gen8_t, int8_gen> uniform_uint8; + uniform_uint8 uint8_0255(gen8_03, int8_gen(0, 255)); + check_uniform_int(uint8_0255, 100000); + + // use the full range, but a generator whose range is not + // a root of the destination range. + gen8_t gen8_02(gen, int8_gen(0, 2)); + uniform_uint8 uint8_0255_2(gen8_02, int8_gen(0, 255)); + check_uniform_int(uint8_0255_2, 100000); + + // expand the range to a larger type. + typedef boost::random::variate_generator<gen8_t, int_gen> uniform_uint_from8; + uniform_uint_from8 uint0300(gen8_03, int_gen(0, 300)); + check_uniform_int(uint0300, 100000); +} + +#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T) + +// testcase by Mario Rutti +class ruetti_gen +{ +public: + ruetti_gen() : state((max)() - 1) {} + typedef boost::uint64_t result_type; + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<result_type>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); } + result_type operator()() { return state--; } +private: + result_type state; +}; + +BOOST_AUTO_TEST_CASE(test_overflow_range) +{ + ruetti_gen gen; + BOOST_RANDOM_DISTRIBUTION dist(0, 10); + for (int i=0;i<10;i++) { + dist(gen); + } +} + +#endif + +BOOST_AUTO_TEST_CASE(test_misc) +{ + // bug report from Ken Mahler: This used to lead to an endless loop. + typedef BOOST_RANDOM_UNIFORM_INT<unsigned int> uint_dist; + boost::minstd_rand mr; + boost::variate_generator<boost::minstd_rand, uint_dist> r2(mr, + uint_dist(0, 0xffffffff)); + r2(); + r2(); + + // bug report from Fernando Cacciola: This used to lead to an endless loop. + // also from Douglas Gregor + boost::variate_generator<boost::minstd_rand, BOOST_RANDOM_DISTRIBUTION > x(mr, BOOST_RANDOM_DISTRIBUTION(0, 8361)); + x(); + + // bug report from Alan Stokes and others: this throws an assertion + boost::variate_generator<boost::minstd_rand, BOOST_RANDOM_DISTRIBUTION > y(mr, BOOST_RANDOM_DISTRIBUTION(1,1)); + y(); + y(); + y(); +} |