test_mpfi.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2012 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
  5. #ifdef _MSC_VER
  6. #define _SCL_SECURE_NO_WARNINGS
  7. #endif
  8. #include "test.hpp"
  9. #include <boost/multiprecision/mpfi.hpp>
  10. #include <boost/multiprecision/random.hpp>
  11. using namespace boost::multiprecision;
  12. using namespace boost::random;
  13. void test_exp()
  14. {
  15. std::cout << "Testing exp\n";
  16. mpfr_float_50 val = 1.25;
  17. for (unsigned i = 0; i < 2000; ++i)
  18. {
  19. mpfr_float_100 a(val);
  20. mpfr_float_100 b = exp(a);
  21. mpfi_float_50 in = val;
  22. in = exp(in);
  23. BOOST_CHECK((boost::math::isfinite)(in));
  24. BOOST_CHECK(lower(in) <= b);
  25. BOOST_CHECK(upper(in) >= b);
  26. b = log(a);
  27. in = val;
  28. in = log(in);
  29. BOOST_CHECK((boost::math::isfinite)(in));
  30. BOOST_CHECK(lower(in) <= b);
  31. BOOST_CHECK(upper(in) >= b);
  32. val *= 1.01;
  33. }
  34. val = 1;
  35. for (unsigned i = 0; i < 2000; ++i)
  36. {
  37. mpfr_float_100 a(val);
  38. mpfr_float_100 b = exp(a);
  39. mpfi_float_50 in = val;
  40. in = exp(in);
  41. BOOST_CHECK((boost::math::isfinite)(in));
  42. BOOST_CHECK(lower(in) <= b);
  43. BOOST_CHECK(upper(in) >= b);
  44. b = log(a);
  45. in = val;
  46. in = log(in);
  47. BOOST_CHECK((boost::math::isfinite)(in));
  48. BOOST_CHECK(lower(in) <= b);
  49. BOOST_CHECK(upper(in) >= b);
  50. val /= 1.01;
  51. }
  52. }
  53. void test_pow()
  54. {
  55. std::cout << "Testing pow function\n";
  56. mt19937 gen;
  57. uniform_real_distribution<mpfr_float_50> dist1(0, 400);
  58. for (unsigned i = 0; i < 5000; ++i)
  59. {
  60. mpfr_float_50 base, p;
  61. base = dist1(gen);
  62. p = dist1(gen);
  63. mpfr_float_100 a, b, r;
  64. a = base;
  65. b = p;
  66. r = pow(a, b);
  67. mpfi_float_50 ai, bi, ri;
  68. ai = base;
  69. bi = p;
  70. ri = pow(ai, bi);
  71. BOOST_CHECK((boost::math::isfinite)(ri));
  72. BOOST_CHECK(lower(ri) <= r);
  73. BOOST_CHECK(upper(ri) >= r);
  74. }
  75. }
  76. void test_trig()
  77. {
  78. std::cout << "Testing trig functions\n";
  79. mt19937 gen;
  80. uniform_real_distribution<mpfr_float_50> dist1(-1.57079632679, 1.57079632679);
  81. uniform_real_distribution<mpfr_float_50> dist2(-1, 1);
  82. for (unsigned i = 0; i < 5000; ++i)
  83. {
  84. mpfr_float_50 val;
  85. val = dist1(gen);
  86. mpfr_float_100 a = val;
  87. mpfr_float_100 b = sin(a);
  88. mpfi_float_50 a2 = val;
  89. mpfi_float_50 b2 = sin(a2);
  90. BOOST_CHECK((boost::math::isfinite)(b2));
  91. BOOST_CHECK(lower(b2) <= b);
  92. BOOST_CHECK(upper(b2) >= b);
  93. b = cos(a);
  94. b2 = cos(a2);
  95. BOOST_CHECK((boost::math::isfinite)(b2));
  96. BOOST_CHECK(lower(b2) <= b);
  97. BOOST_CHECK(upper(b2) >= b);
  98. b = tan(a);
  99. b2 = tan(a2);
  100. BOOST_CHECK((boost::math::isfinite)(b2));
  101. BOOST_CHECK(lower(b2) <= b);
  102. BOOST_CHECK(upper(b2) >= b);
  103. }
  104. for (unsigned i = 0; i < 5000; ++i)
  105. {
  106. mpfr_float_50 val;
  107. val = dist2(gen);
  108. mpfr_float_100 a = val;
  109. mpfr_float_100 b = asin(a);
  110. mpfi_float_50 a2 = val;
  111. mpfi_float_50 b2 = asin(a2);
  112. BOOST_CHECK((boost::math::isfinite)(b2));
  113. BOOST_CHECK(lower(b2) <= b);
  114. BOOST_CHECK(upper(b2) >= b);
  115. b = acos(a);
  116. b2 = acos(a2);
  117. BOOST_CHECK((boost::math::isfinite)(b2));
  118. BOOST_CHECK(lower(b2) <= b);
  119. BOOST_CHECK(upper(b2) >= b);
  120. b = atan(a);
  121. b2 = atan(a2);
  122. BOOST_CHECK((boost::math::isfinite)(b2));
  123. BOOST_CHECK(lower(b2) <= b);
  124. BOOST_CHECK(upper(b2) >= b);
  125. }
  126. }
  127. void test_hyp()
  128. {
  129. std::cout << "Testing hyperbolic trig functions\n";
  130. mt19937 gen;
  131. uniform_real_distribution<mpfr_float_50> dist1(-10, 10);
  132. uniform_real_distribution<mpfr_float_50> dist2(-1, 1);
  133. for (unsigned i = 0; i < 5000; ++i)
  134. {
  135. mpfr_float_50 val;
  136. val = dist1(gen);
  137. mpfr_float_100 a = val;
  138. mpfr_float_100 b = sinh(a);
  139. mpfi_float_50 a2 = val;
  140. mpfi_float_50 b2 = sinh(a2);
  141. BOOST_CHECK((boost::math::isfinite)(b2));
  142. BOOST_CHECK(lower(b2) <= b);
  143. BOOST_CHECK(upper(b2) >= b);
  144. b = cosh(a);
  145. b2 = cosh(a2);
  146. BOOST_CHECK((boost::math::isfinite)(b2));
  147. BOOST_CHECK(lower(b2) <= b);
  148. BOOST_CHECK(upper(b2) >= b);
  149. b = tanh(a);
  150. b2 = tanh(a2);
  151. BOOST_CHECK((boost::math::isfinite)(b2));
  152. BOOST_CHECK(lower(b2) <= b);
  153. BOOST_CHECK(upper(b2) >= b);
  154. }
  155. }
  156. void test_intervals()
  157. {
  158. mpfi_float_50 a(1, 2);
  159. mpfi_float_50 b(1.5, 2.5);
  160. BOOST_CHECK_EQUAL(lower(a), 1);
  161. BOOST_CHECK_EQUAL(upper(a), 2);
  162. BOOST_CHECK_EQUAL(median(a), 1.5);
  163. BOOST_CHECK_EQUAL(width(a), 1);
  164. mpfi_float_50 r = intersect(a, b);
  165. BOOST_CHECK_EQUAL(lower(r), 1.5);
  166. BOOST_CHECK_EQUAL(upper(r), 2);
  167. r = hull(a, b);
  168. BOOST_CHECK_EQUAL(lower(r), 1);
  169. BOOST_CHECK_EQUAL(upper(r), 2.5);
  170. BOOST_CHECK(overlap(a, b));
  171. BOOST_CHECK(in(mpfr_float_50(1.5), a));
  172. BOOST_CHECK(in(mpfr_float_50(1), a));
  173. BOOST_CHECK(in(mpfr_float_50(2), a));
  174. BOOST_CHECK(!zero_in(a));
  175. b = mpfi_float_50(1.5, 1.75);
  176. BOOST_CHECK(subset(b, a));
  177. BOOST_CHECK(proper_subset(b, a));
  178. BOOST_CHECK(!empty(a));
  179. BOOST_CHECK(!singleton(a));
  180. b = mpfi_float_50(5, 6);
  181. r = intersect(a, b);
  182. BOOST_CHECK(empty(r));
  183. }
  184. #ifdef TEST_SPECIAL
  185. #include "math/table_type.hpp"
  186. #include <boost/math/special_functions.hpp>
  187. #define T mpfi_float_50
  188. typedef number<mpfi_float_backend<25> > mpfi_float_25;
  189. void test_log1p_expm1()
  190. {
  191. #include "../../math/test/log1p_expm1_data.ipp"
  192. std::cout << std::setprecision(std::numeric_limits<mpfi_float_25>::max_digits10);
  193. std::cout << "Testing log1p and expm1\n";
  194. for (unsigned i = 0; i < log1p_expm1_data.size(); ++i)
  195. {
  196. mpfi_float_25 in(log1p_expm1_data[i][0]);
  197. mpfi_float_25 out = boost::math::log1p(in);
  198. mpfi_float_25 expected(log1p_expm1_data[i][1]);
  199. if (!subset(expected, out))
  200. {
  201. std::cout << in << std::endl;
  202. std::cout << out << std::endl;
  203. std::cout << expected << std::endl;
  204. BOOST_CHECK(lower(out) <= lower(expected));
  205. BOOST_CHECK(upper(out) >= upper(expected));
  206. }
  207. out = boost::math::expm1(in);
  208. expected = mpfi_float_25(log1p_expm1_data[i][2]);
  209. if (!subset(expected, out))
  210. {
  211. std::cout << in << std::endl;
  212. std::cout << out << std::endl;
  213. std::cout << expected << std::endl;
  214. BOOST_CHECK(lower(out) <= lower(expected));
  215. BOOST_CHECK(upper(out) >= upper(expected));
  216. }
  217. }
  218. }
  219. void test_bessel()
  220. {
  221. #include "../../math/test/bessel_i_int_data.ipp"
  222. #include "../../math/test/bessel_i_data.ipp"
  223. std::cout << std::setprecision(std::numeric_limits<mpfi_float_25>::max_digits10);
  224. std::cout << "Testing Bessel Functions\n";
  225. for (unsigned i = 0; i < bessel_i_int_data.size(); ++i)
  226. {
  227. int v = boost::lexical_cast<int>(static_cast<const char*>(bessel_i_int_data[i][0]));
  228. mpfi_float_25 in(bessel_i_int_data[i][1]);
  229. mpfi_float_25 out = boost::math::cyl_bessel_i(v, in);
  230. mpfi_float_25 expected(bessel_i_int_data[i][2]);
  231. if (!subset(expected, out))
  232. {
  233. std::cout << in << std::endl;
  234. std::cout << out << std::endl;
  235. std::cout << expected << std::endl;
  236. BOOST_CHECK(lower(out) <= lower(expected));
  237. BOOST_CHECK(upper(out) >= upper(expected));
  238. }
  239. }
  240. }
  241. #endif
  242. int main()
  243. {
  244. #ifdef TEST_SPECIAL
  245. test_log1p_expm1();
  246. test_bessel();
  247. #endif
  248. test_intervals();
  249. test_exp();
  250. test_pow();
  251. test_trig();
  252. test_hyp();
  253. return boost::report_errors();
  254. }