• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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