• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* multiprecision_int_test.cpp
3 *
4 * Copyright John Maddock 2015
5 * Distributed under the Boost Software License, Version 1.0. (See
6 * accompanying file LICENSE_1_0.txt or copy at
7 * http://www.boost.org/LICENSE_1_0.txt)
8 *
9 * $Id$
10 *
11 * Tests all integer related generators and distributions with multiprecision types:
12 * discard_block, independent_bits_engine, random_number_generator,
13 * xor_combine_engine, uniform_int_distribution, uniform_smallint.
14 *
15 * Not supported, but could be with more work (but probably not worth while):
16 * shuffle_order_engine, binomial_distribution, discrete_distribution, negative_binomial_distribution,
17 * poisson_distribution
18 */
19 
20 #define BOOST_TEST_MAIN
21 #include <boost/test/unit_test.hpp>
22 
23 #include <boost/core/ignore_unused.hpp>
24 #include <boost/multiprecision/debug_adaptor.hpp>
25 #include <boost/multiprecision/cpp_bin_float.hpp>
26 #include <boost/multiprecision/cpp_int.hpp>
27 #include <boost/random/independent_bits.hpp>
28 #include <boost/random/discard_block.hpp>
29 #include <boost/random/xor_combine.hpp>
30 #include <boost/random/mersenne_twister.hpp>
31 #include <boost/random/random_number_generator.hpp>
32 #include <boost/random/uniform_int.hpp>
33 #include <boost/random/uniform_smallint.hpp>
34 #include <boost/random/discrete_distribution.hpp>
35 #include <sstream>
36 
37 typedef boost::mpl::list <
38    boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::uint1024_t >,
39    boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::int1024_t >,
40    boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_uint1024_t >,
41    boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_int1024_t >,
42    boost::random::independent_bits_engine<boost::random::mt19937, 30000, boost::multiprecision::cpp_int >,
43    boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::uint1024_t >, 20, 10>,
44    boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::int1024_t >, 20, 10>,
45    boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_uint1024_t >, 20, 10>,
46    boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_int1024_t >, 20, 10>,
47    boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 600, boost::multiprecision::cpp_int >, 20, 10>
48 > engines;
49 
BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test,engine_type,engines)50 BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test, engine_type, engines)
51 {
52    typedef typename engine_type::result_type test_type;
53 
54    engine_type gen;
55    gen.seed();
56    test_type a = gen.min();
57    test_type b = gen.max();
58    BOOST_CHECK(a < b);
59    a = gen();
60    //
61    // This extracts 32-bit values for use in seeding other sequences,
62    // not really applicable here, and not functional for signed types anyway.
63    //gen.generate(&b, &b + 1);
64    gen.discard(20);
65 
66    typename engine_type::base_type base(gen.base());
67    boost::ignore_unused(base);
68 
69    std::stringstream ss;
70    ss << gen;
71    engine_type gen2;
72    ss >> gen2;
73    BOOST_CHECK(gen == gen2);
74    gen2();
75    BOOST_CHECK(gen != gen2);
76    //
77    // construction and seeding:
78    //
79    engine_type gen3(0);
80    gen3.seed(2);
81 }
82 
BOOST_AUTO_TEST_CASE(xor_combine_test)83 BOOST_AUTO_TEST_CASE(xor_combine_test)
84 {
85    //
86    // As above but with a few things missing which don't work - for example we have no
87    // way to drill down and get the seed-type of the underlying generator.
88    //
89    typedef boost::random::xor_combine_engine<boost::random::independent_bits_engine<boost::random::mt19937, 512, boost::multiprecision::uint1024_t >, 512, boost::random::independent_bits_engine<boost::random::mt19937, 512, boost::multiprecision::uint1024_t >, 10> engine_type;
90    typedef engine_type::result_type test_type;
91 
92    engine_type gen;
93    gen.seed();
94    test_type a = gen.min();
95    test_type b = gen.max();
96    BOOST_CHECK(a < b);
97    a = gen();
98 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
99    gen.generate(&b, &b + 1);
100 #endif
101    gen.discard(20);
102 
103    //typename engine_type::base_type base(gen.base());
104 
105    std::stringstream ss;
106    ss << gen;
107    engine_type gen2;
108    ss >> gen2;
109    BOOST_CHECK(gen == gen2);
110    gen2();
111    BOOST_CHECK(gen != gen2);
112    //
113    // construction and seeding:
114    //
115    //engine_type gen3(0);
116    //gen3.seed(2);
117 }
118 
119 typedef boost::mpl::list <
120    boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::cpp_int>,
121    boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::uint1024_t>,
122    boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::checked_uint1024_t>
123 > generators;
124 
125 
BOOST_AUTO_TEST_CASE_TEMPLATE(random_number_generator,generator_type,generators)126 BOOST_AUTO_TEST_CASE_TEMPLATE(random_number_generator, generator_type, generators)
127 {
128    typedef typename generator_type::result_type result_type;
129    typedef typename generator_type::base_type base_type;
130 
131    result_type lim = 1;
132    lim <<= 500;
133 
134    base_type base;
135    generator_type gen(base);
136 
137    for(unsigned i = 0; i < 100; ++i)
138       BOOST_CHECK(gen(lim) < lim);
139 }
140 
141 typedef boost::mpl::list <
142    boost::random::uniform_int_distribution<boost::multiprecision::cpp_int>,
143    boost::random::uniform_int_distribution<boost::multiprecision::uint1024_t>,
144    boost::random::uniform_int_distribution<boost::multiprecision::checked_uint1024_t>,
145    boost::random::uniform_smallint<boost::multiprecision::cpp_int>,
146    boost::random::uniform_smallint<boost::multiprecision::uint1024_t>,
147    boost::random::uniform_smallint<boost::multiprecision::checked_uint1024_t>
148 > uniform_distributions;
149 
150 
BOOST_AUTO_TEST_CASE_TEMPLATE(distributions,distribution_type,uniform_distributions)151 BOOST_AUTO_TEST_CASE_TEMPLATE(distributions, distribution_type, uniform_distributions)
152 {
153    typedef typename distribution_type::result_type  result_type;
154 
155    result_type a = 20;
156    result_type b = 1;
157    b <<= 1000;
158 
159    distribution_type d(a, b);
160    boost::random::mt19937 gen;
161 
162    BOOST_CHECK_EQUAL(d.a(), a);
163    BOOST_CHECK_EQUAL(d.b(), b);
164    BOOST_CHECK_EQUAL((d.min)(), a);
165    BOOST_CHECK_EQUAL((d.max)(), b);
166 
167    for(unsigned i = 0; i < 200; ++i)
168    {
169       result_type r = d(gen);
170       BOOST_CHECK(r <= b);
171       BOOST_CHECK(r >= a);
172    }
173 
174    std::stringstream ss;
175    ss << d;
176    distribution_type d2;
177    ss >> d2;
178    BOOST_CHECK(d == d2);
179 
180    boost::random::independent_bits_engine<boost::random::mt19937, std::numeric_limits<boost::multiprecision::uint1024_t>::digits, boost::multiprecision::uint1024_t > big_random;
181    for(unsigned i = 0; i < 200; ++i)
182    {
183       result_type r = d(big_random);
184       BOOST_CHECK(r <= b);
185       BOOST_CHECK(r >= a);
186    }
187 }
188 
189 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
190 
191 typedef boost::mpl::list <
192    boost::random::discrete_distribution < boost::multiprecision::cpp_int, double>,
193    boost::random::discrete_distribution <unsigned int, boost::multiprecision::cpp_bin_float_100>
194 > other_distributions;
195 
196 
BOOST_AUTO_TEST_CASE_TEMPLATE(discrete_distributions,distribution_type,other_distributions)197 BOOST_AUTO_TEST_CASE_TEMPLATE(discrete_distributions, distribution_type, other_distributions)
198 {
199    typedef typename distribution_type::result_type  result_type;
200    typedef typename distribution_type::input_type   input_type;
201 
202    input_type a[] = { 20, 30, 40, 50 };
203 
204    distribution_type d(a, a + 4);
205    boost::random::mt19937 gen;
206 
207    for(unsigned i = 0; i < 200; ++i)
208    {
209       result_type r = d(gen);
210    }
211 
212    std::stringstream ss;
213    ss << std::setprecision(std::numeric_limits<input_type>::digits10 + 3) << d;
214    distribution_type d2;
215    ss >> d2;
216    BOOST_CHECK(d == d2);
217 
218    boost::random::independent_bits_engine<boost::random::mt19937, std::numeric_limits<boost::multiprecision::uint1024_t>::digits, boost::multiprecision::uint1024_t > big_random;
219    for(unsigned i = 0; i < 200; ++i)
220    {
221       result_type r = d(big_random);
222    }
223 }
224 
225 #endif
226