1
2 /* multiprecision_float_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 floating point related generators and distributions with multiprecision types.
12 */
13
14 #define BOOST_TEST_MAIN
15 #include <boost/test/unit_test.hpp>
16
17 #include <boost/core/ignore_unused.hpp>
18 #include <boost/multiprecision/cpp_bin_float.hpp>
19 #include <boost/multiprecision/cpp_int.hpp>
20 #include <boost/multiprecision/debug_adaptor.hpp>
21 #include <boost/scoped_ptr.hpp>
22 #include <boost/random.hpp>
23 #include <sstream>
24
25
26 typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float_100::backend_type, boost::multiprecision::et_on > big_float;
27 typedef boost::random::subtract_with_carry_01_engine<big_float, 48, 10, 24 > ranlux_big_base_01;
28 typedef boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::uint1024_t> large_int_generator;
29
30 typedef boost::mpl::list <
31 boost::random::lagged_fibonacci_01_engine<big_float, 48, 44497, 21034 >,
32 boost::random::discard_block_engine< ranlux_big_base_01, 389, 24 >
33 > engines;
34
BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test,engine_type,engines)35 BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test, engine_type, engines)
36 {
37 typedef typename engine_type::result_type test_type;
38
39 boost::scoped_ptr<engine_type> gen(new engine_type());
40 unsigned seeds[] = { 1, 2, 3, 4 };
41 unsigned *p1 = seeds, *p2 = seeds + 4;
42 BOOST_CHECK_THROW(gen->seed(p1, p2), std::invalid_argument);
43 gen->seed();
44 gen->seed(2);
45 test_type a = gen->min();
46 test_type b = gen->max();
47 BOOST_CHECK(a < b);
48 for(unsigned i = 0; i < 200; ++i)
49 {
50 test_type r = (*gen)();
51 BOOST_CHECK((boost::math::isfinite)(r));
52 BOOST_CHECK(a <= r);
53 BOOST_CHECK(b >= r);
54 }
55 gen->discard(20);
56
57 std::stringstream ss;
58 ss << std::setprecision(std::numeric_limits<test_type>::digits10 + 3) << *gen;
59 boost::scoped_ptr<engine_type> gen2(new engine_type());
60 ss >> *gen2;
61 BOOST_CHECK(*gen == *gen2);
62 (*gen2)();
63 BOOST_CHECK(*gen != *gen2);
64 }
65
66 typedef boost::mpl::list <
67 boost::random::bernoulli_distribution<big_float>,
68 boost::random::beta_distribution<big_float>,
69 boost::random::cauchy_distribution<big_float>,
70 boost::random::chi_squared_distribution<big_float>,
71 boost::random::exponential_distribution<big_float>,
72 boost::random::extreme_value_distribution<big_float>,
73 boost::random::fisher_f_distribution<big_float>,
74 boost::random::gamma_distribution<big_float>,
75 boost::random::laplace_distribution<big_float>,
76 boost::random::lognormal_distribution<big_float>,
77 boost::random::normal_distribution<big_float>,
78 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
79 boost::random::piecewise_constant_distribution<big_float>,
80 boost::random::piecewise_linear_distribution<big_float>,
81 #endif
82 boost::random::student_t_distribution<big_float>,
83 boost::random::triangle_distribution<big_float>,
84 //boost::random::uniform_01<big_float>, // doesn't respect the concept! But gets used internally anyway.
85 boost::random::uniform_real_distribution<big_float>,
86 boost::random::uniform_on_sphere<big_float>,
87 boost::random::weibull_distribution<big_float>
88 > distributions;
89
90
BOOST_AUTO_TEST_CASE_TEMPLATE(distributions_test,dist_type,distributions)91 BOOST_AUTO_TEST_CASE_TEMPLATE(distributions_test, dist_type, distributions)
92 {
93 typedef typename dist_type::result_type result_type;
94 dist_type d;
95 result_type a = (d.min)();
96 result_type b = (d.max)();
97 typename dist_type::param_type p = d.param();
98 boost::ignore_unused(p);
99 d.reset();
100
101 std::stringstream ss;
102 ss << std::setprecision(std::numeric_limits<result_type>::digits10 + 3) << d;
103 dist_type d2;
104 ss >> d2;
105 BOOST_CHECK(d == d2);
106
107 boost::random::mt19937 int_gen;
108
109 for(unsigned i = 0; i < 200; ++i)
110 {
111 result_type r = d(int_gen);
112 BOOST_CHECK((boost::math::isfinite)(r));
113 BOOST_CHECK(r >= a);
114 BOOST_CHECK(r <= b);
115 }
116
117 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
118 large_int_generator big_int_gen;
119
120 for(unsigned i = 0; i < 200; ++i)
121 {
122 result_type r = d(big_int_gen);
123 BOOST_CHECK((boost::math::isfinite)(r));
124 BOOST_CHECK(r >= a);
125 BOOST_CHECK(r <= b);
126 }
127
128 boost::random::discard_block_engine< ranlux_big_base_01, 389, 24 > big_float_gen;
129
130 for(unsigned i = 0; i < 200; ++i)
131 {
132 result_type r = d(big_float_gen);
133 BOOST_CHECK((boost::math::isfinite)(r));
134 BOOST_CHECK(r >= a);
135 BOOST_CHECK(r <= b);
136 }
137 #endif
138
139 boost::random::ranlux64_4_01 float_gen;
140
141 for(unsigned i = 0; i < 200; ++i)
142 {
143 result_type r = d(float_gen);
144 BOOST_CHECK((boost::math::isfinite)(r));
145 BOOST_CHECK(r >= a);
146 BOOST_CHECK(r <= b);
147 }
148 }
149
150
151
BOOST_AUTO_TEST_CASE(canonical_test)152 BOOST_AUTO_TEST_CASE(canonical_test)
153 {
154 typedef big_float result_type;
155
156 boost::random::mt19937 int_gen;
157
158 for(unsigned i = 0; i < 200; ++i)
159 {
160 result_type r = boost::random::generate_canonical<big_float, std::numeric_limits<big_float>::digits>(int_gen);
161 BOOST_CHECK((boost::math::isfinite)(r));
162 BOOST_CHECK(r >= 0);
163 BOOST_CHECK(r <= 1);
164 }
165
166 large_int_generator big_int_gen;
167
168 for(unsigned i = 0; i < 200; ++i)
169 {
170 result_type r = boost::random::generate_canonical<big_float, std::numeric_limits<big_float>::digits>(big_int_gen);
171 BOOST_CHECK((boost::math::isfinite)(r));
172 BOOST_CHECK(r >= 0);
173 BOOST_CHECK(r <= 1);
174 }
175
176
177 boost::random::discard_block_engine< ranlux_big_base_01, 389, 24 > big_float_gen;
178
179 for(unsigned i = 0; i < 200; ++i)
180 {
181 result_type r = boost::random::generate_canonical<big_float, std::numeric_limits<big_float>::digits>(big_float_gen);
182 BOOST_CHECK((boost::math::isfinite)(r));
183 BOOST_CHECK(r >= 0);
184 BOOST_CHECK(r <= 1);
185 }
186
187 boost::random::ranlux64_4_01 float_gen;
188
189 for(unsigned i = 0; i < 200; ++i)
190 {
191 result_type r = boost::random::generate_canonical<big_float, std::numeric_limits<big_float>::digits>(float_gen);
192 BOOST_CHECK((boost::math::isfinite)(r));
193 BOOST_CHECK(r >= 0);
194 BOOST_CHECK(r <= 1);
195 }
196
197 }
198
199