test_sinc.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // (C) Copyright John Maddock 2018.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <pch_light.hpp>
  6. #include "test_sinc.hpp"
  7. #include <boost/multiprecision/cpp_bin_float.hpp>
  8. #include <boost/math/special_functions/next.hpp>
  9. //
  10. // DESCRIPTION:
  11. // ~~~~~~~~~~~~
  12. //
  13. // This file tests the sinc_pi function. 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. add_expected_result(
  38. ".*", // compiler
  39. ".*", // stdlib
  40. ".*", // platform
  41. ".*", // test type(s)
  42. ".*", // test data group
  43. ".*", 3, 3); // test function
  44. //
  45. // Finish off by printing out the compiler/stdlib/platform names,
  46. // we do this to make it easier to mark up expected error rates.
  47. //
  48. std::cout << "Tests run with " << BOOST_COMPILER << ", "
  49. << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
  50. }
  51. template <class T>
  52. void test_close_to_transition()
  53. {
  54. T transition = 3.3f * boost::math::tools::forth_root_epsilon<T>();
  55. T val = transition;
  56. for (unsigned i = 0; i < 100; ++i)
  57. {
  58. boost::multiprecision::cpp_bin_float_50 extended = val;
  59. extended = sin(extended) / extended;
  60. T expected = extended.template convert_to<T>();
  61. T result = boost::math::sinc_pi(val);
  62. BOOST_CHECK_LE(boost::math::epsilon_difference(result, expected), 3);
  63. result = boost::math::sinc_pi(-val);
  64. BOOST_CHECK_LE(boost::math::epsilon_difference(result, expected), 3);
  65. val = boost::math::float_prior(val);
  66. }
  67. for (unsigned i = 0; i < 100; ++i)
  68. {
  69. boost::multiprecision::cpp_bin_float_50 extended = val;
  70. extended = sin(extended) / extended;
  71. T expected = extended.template convert_to<T>();
  72. T result = boost::math::sinc_pi(val);
  73. BOOST_CHECK_LE(boost::math::epsilon_difference(result, expected), 3);
  74. result = boost::math::sinc_pi(-val);
  75. BOOST_CHECK_LE(boost::math::epsilon_difference(result, expected), 3);
  76. val = boost::math::float_next(val);
  77. }
  78. }
  79. BOOST_AUTO_TEST_CASE( test_main )
  80. {
  81. BOOST_MATH_CONTROL_FP;
  82. expected_results();
  83. test_sinc(0.1F, "float");
  84. test_close_to_transition<float>();
  85. test_sinc(0.1, "double");
  86. test_close_to_transition<double>();
  87. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  88. test_sinc(0.1L, "long double");
  89. test_close_to_transition<long double>();
  90. #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
  91. test_sinc(boost::math::concepts::real_concept(0.1), "real_concept");
  92. #endif
  93. #else
  94. std::cout << "<note>The long double tests have been disabled on this platform "
  95. "either because the long double overloads of the usual math functions are "
  96. "not available at all, or because they are too inaccurate for these tests "
  97. "to pass.</note>" << std::endl;
  98. #endif
  99. }