test_erf.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright John Maddock 2006.
  2. // Copyright Paul A. Bristow 2007
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <pch_light.hpp>
  7. #include "test_erf.hpp"
  8. //
  9. // DESCRIPTION:
  10. // ~~~~~~~~~~~~
  11. //
  12. // This file tests the functions erf, erfc, and the inverses
  13. // erf_inv and erfc_inv. There are two sets of tests, spot
  14. // tests which compare our results with selected values computed
  15. // using the online special function calculator at
  16. // functions.wolfram.com, while the bulk of the accuracy tests
  17. // use values generated with NTL::RR at 1000-bit precision
  18. // and our generic versions of these functions.
  19. //
  20. // Note that when this file is first run on a new platform many of
  21. // these tests will fail: the default accuracy is 1 epsilon which
  22. // is too tight for most platforms. In this situation you will
  23. // need to cast a human eye over the error rates reported and make
  24. // a judgement as to whether they are acceptable. Either way please
  25. // report the results to the Boost mailing list. Acceptable rates of
  26. // error are marked up below as a series of regular expressions that
  27. // identify the compiler/stdlib/platform/data-type/test-data/test-function
  28. // along with the maximum expected peek and RMS mean errors for that
  29. // test.
  30. //
  31. void expected_results()
  32. {
  33. //
  34. // Define the max and mean errors expected for
  35. // various compilers and platforms.
  36. //
  37. const char* largest_type;
  38. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  39. if(boost::math::policies::digits<double, boost::math::policies::policy<> >() == boost::math::policies::digits<long double, boost::math::policies::policy<> >())
  40. {
  41. largest_type = "(long\\s+)?double|real_concept";
  42. }
  43. else
  44. {
  45. largest_type = "long double|real_concept";
  46. }
  47. #else
  48. largest_type = "(long\\s+)?double";
  49. #endif
  50. //
  51. // On MacOS X erfc has much higher error levels than
  52. // expected: given that the implementation is basically
  53. // just a rational function evaluation combined with
  54. // exponentiation, we conclude that exp and pow are less
  55. // accurate on this platform, especially when the result
  56. // is outside the range of a double.
  57. //
  58. add_expected_result(
  59. ".*", // compiler
  60. ".*", // stdlib
  61. "Mac OS", // platform
  62. largest_type, // test type(s)
  63. "Erf Function:.*Large.*", // test data group
  64. "erfc", 4300, 1300); // test function
  65. add_expected_result(
  66. ".*", // compiler
  67. ".*", // stdlib
  68. "Mac OS", // platform
  69. largest_type, // test type(s)
  70. "Erf Function:.*", // test data group
  71. "erfc", 40, 10); // test function
  72. add_expected_result(
  73. ".*", // compiler
  74. ".*", // stdlib
  75. ".*", // platform
  76. "real_concept", // test type(s)
  77. "Erf Function:.*", // test data group
  78. "erfc?", 20, 6); // test function
  79. add_expected_result(
  80. ".*", // compiler
  81. ".*", // stdlib
  82. ".*", // platform
  83. "real_concept", // test type(s)
  84. "Inverse Erfc.*", // test data group
  85. "erfc_inv", 80, 10); // test function
  86. //
  87. // Catch all cases come last:
  88. //
  89. add_expected_result(
  90. ".*", // compiler
  91. ".*", // stdlib
  92. ".*", // platform
  93. ".*", // test type(s)
  94. "Erf Function:.*", // test data group
  95. "erfc?", 2, 2); // test function
  96. add_expected_result(
  97. ".*aCC.*", // compiler
  98. ".*", // stdlib
  99. ".*", // platform
  100. ".*", // test type(s)
  101. "Inverse Erfc.*", // test data group
  102. "erfc_inv", 80, 10); // test function
  103. add_expected_result(
  104. ".*", // compiler
  105. ".*", // stdlib
  106. ".*", // platform
  107. ".*", // test type(s)
  108. "Inverse Erf.*", // test data group
  109. "erfc?_inv", 18, 4); // test function
  110. //
  111. // Finish off by printing out the compiler/stdlib/platform names,
  112. // we do this to make it easier to mark up expected error rates.
  113. //
  114. std::cout << "Tests run with " << BOOST_COMPILER << ", "
  115. << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
  116. }
  117. BOOST_AUTO_TEST_CASE( test_main )
  118. {
  119. BOOST_MATH_CONTROL_FP;
  120. test_spots(0.0F, "float");
  121. test_spots(0.0, "double");
  122. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  123. test_spots(0.0L, "long double");
  124. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
  125. test_spots(boost::math::concepts::real_concept(0.1), "real_concept");
  126. #endif
  127. #endif
  128. expected_results();
  129. test_erf(0.1F, "float");
  130. test_erf(0.1, "double");
  131. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  132. test_erf(0.1L, "long double");
  133. #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
  134. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
  135. test_erf(boost::math::concepts::real_concept(0.1), "real_concept");
  136. #endif
  137. #endif
  138. #else
  139. std::cout << "<note>The long double tests have been disabled on this platform "
  140. "either because the long double overloads of the usual math functions are "
  141. "not available at all, or because they are too inaccurate for these tests "
  142. "to pass.</note>" << std::endl;
  143. #endif
  144. }
  145. /*
  146. Output:
  147. test_erf.cpp
  148. Compiling manifest to resources...
  149. Linking...
  150. Embedding manifest...
  151. Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\test_erf.exe"
  152. Running 1 test case...
  153. Testing basic sanity checks for type float
  154. Testing basic sanity checks for type double
  155. Testing basic sanity checks for type long double
  156. Testing basic sanity checks for type real_concept
  157. Tests run with Microsoft Visual C++ version 8.0, Dinkumware standard library version 405, Win32
  158. Testing Erf Function: Small Values with type float
  159. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  160. boost::math::erf<float> Max = 0 RMS Mean=0
  161. boost::math::erfc<float> Max = 0 RMS Mean=0
  162. Testing Erf Function: Medium Values with type float
  163. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  164. boost::math::erf<float> Max = 0 RMS Mean=0
  165. boost::math::erfc<float> Max = 0 RMS Mean=0
  166. Testing Erf Function: Large Values with type float
  167. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  168. boost::math::erf<float> Max = 0 RMS Mean=0
  169. boost::math::erfc<float> Max = 0 RMS Mean=0
  170. Testing Inverse Erf Function with type float
  171. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172. boost::math::erf_inv<float> Max = 0 RMS Mean=0
  173. Testing Inverse Erfc Function with type float
  174. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  175. boost::math::erfc_inv<float> Max = 0 RMS Mean=0
  176. Testing Erf Function: Small Values with type double
  177. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  178. boost::math::erf<double> Max = 0 RMS Mean=0
  179. boost::math::erfc<double> Max = 0.7857 RMS Mean=0.06415
  180. worst case at row: 149
  181. { 0.3343, 0.3636, 0.6364 }
  182. Testing Erf Function: Medium Values with type double
  183. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  184. boost::math::erf<double> Max = 0.9219 RMS Mean=0.1016
  185. worst case at row: 273
  186. { 0.5252, 0.5424, 0.4576 }
  187. boost::math::erfc<double> Max = 1.08 RMS Mean=0.3224
  188. worst case at row: 287
  189. { 0.8461, 0.7685, 0.2315 }
  190. Testing Erf Function: Large Values with type double
  191. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  192. boost::math::erf<double> Max = 0 RMS Mean=0
  193. boost::math::erfc<double> Max = 1.048 RMS Mean=0.2032
  194. worst case at row: 50
  195. { 20.96, 1, 4.182e-193 }
  196. Testing Inverse Erf Function with type double
  197. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  198. boost::math::erf_inv<double> Max = 1.124 RMS Mean=0.5082
  199. worst case at row: 98
  200. { 0.9881, 1.779 }
  201. Testing Inverse Erfc Function with type double
  202. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  203. boost::math::erfc_inv<double> Max = 1.124 RMS Mean=0.5006
  204. worst case at row: 98
  205. { 1.988, -1.779 }
  206. Testing Erf Function: Small Values with type long double
  207. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  208. boost::math::erf<long double> Max = 0 RMS Mean=0
  209. boost::math::erfc<long double> Max = 0.7857 RMS Mean=0.06415
  210. worst case at row: 149
  211. { 0.3343, 0.3636, 0.6364 }
  212. Testing Erf Function: Medium Values with type long double
  213. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  214. boost::math::erf<long double> Max = 0.9219 RMS Mean=0.1016
  215. worst case at row: 273
  216. { 0.5252, 0.5424, 0.4576 }
  217. boost::math::erfc<long double> Max = 1.08 RMS Mean=0.3224
  218. worst case at row: 287
  219. { 0.8461, 0.7685, 0.2315 }
  220. Testing Erf Function: Large Values with type long double
  221. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  222. boost::math::erf<long double> Max = 0 RMS Mean=0
  223. boost::math::erfc<long double> Max = 1.048 RMS Mean=0.2032
  224. worst case at row: 50
  225. { 20.96, 1, 4.182e-193 }
  226. Testing Inverse Erf Function with type long double
  227. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  228. boost::math::erf_inv<long double> Max = 1.124 RMS Mean=0.5082
  229. worst case at row: 98
  230. { 0.9881, 1.779 }
  231. Testing Inverse Erfc Function with type long double
  232. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  233. boost::math::erfc_inv<long double> Max = 1.124 RMS Mean=0.5006
  234. worst case at row: 98
  235. { 1.988, -1.779 }
  236. Testing Erf Function: Small Values with type real_concept
  237. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  238. boost::math::erf<real_concept> Max = 1.271 RMS Mean=0.5381
  239. worst case at row: 144
  240. { 0.0109, 0.0123, 0.9877 }
  241. boost::math::erfc<real_concept> Max = 0.7857 RMS Mean=0.07777
  242. worst case at row: 149
  243. { 0.3343, 0.3636, 0.6364 }
  244. Testing Erf Function: Medium Values with type real_concept
  245. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  246. boost::math::erf<real_concept> Max = 22.5 RMS Mean=4.224
  247. worst case at row: 233
  248. { -0.7852, -0.7332, 1.733 }
  249. Peak error greater than expected value of 20
  250. i:/boost-sandbox/math_toolkit/libs/math/test/handle_test_result.hpp(146): error in "test_main_caller( argc, argv )": check bounds.first >= max_error_found failed
  251. boost::math::erfc<real_concept> Max = 97.77 RMS Mean=8.373
  252. worst case at row: 289
  253. { 0.9849, 0.8363, 0.1637 }
  254. Peak error greater than expected value of 20
  255. i:/boost-sandbox/math_toolkit/libs/math/test/handle_test_result.hpp(146): error in "test_main_caller( argc, argv )": check bounds.first >= max_error_found failed
  256. Mean error greater than expected value of 6
  257. i:/boost-sandbox/math_toolkit/libs/math/test/handle_test_result.hpp(151): error in "test_main_caller( argc, argv )": check bounds.second >= mean_error_found failed
  258. Testing Erf Function: Large Values with type real_concept
  259. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  260. boost::math::erf<real_concept> Max = 0 RMS Mean=0
  261. boost::math::erfc<real_concept> Max = 1.395 RMS Mean=0.2908
  262. worst case at row: 11
  263. { 10.99, 1, 1.87e-054 }
  264. Testing Inverse Erf Function with type real_concept
  265. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  266. boost::math::erf_inv<real_concept> Max = 1.124 RMS Mean=0.5082
  267. worst case at row: 98
  268. { 0.9881, 1.779 }
  269. Testing Inverse Erfc Function with type real_concept
  270. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  271. boost::math::erfc_inv<real_concept> Max = 1.124 RMS Mean=0.5006
  272. worst case at row: 98
  273. { 1.988, -1.779 }
  274. Test suite "Test Program" failed with:
  275. 181 assertions out of 184 passed
  276. 3 assertions out of 184 failed
  277. 1 test case out of 1 failed
  278. Test case "test_main_caller( argc, argv )" failed with:
  279. 181 assertions out of 184 passed
  280. 3 assertions out of 184 failed
  281. Build Time 0:15
  282. */