multiprecision_float_test.cpp 6.0 KB

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