test_remez.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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.hpp>
  7. #ifdef _MSC_VER
  8. # pragma warning(disable : 4267) // conversion from 'size_t' to 'const unsigned int', possible loss of data
  9. # pragma warning(disable : 4180) // qualifier applied to function type has no meaning; ignored
  10. # pragma warning(disable : 4224) // nonstandard extension used : formal parameter 'function_ptr' was previously defined as a type
  11. # pragma warning(disable : 4100) // unreferenced formal parameter (in ublas/functional)
  12. #endif
  13. #include <boost/math/tools/remez.hpp>
  14. #define BOOST_TEST_MAIN
  15. #include <boost/test/unit_test.hpp>
  16. #include <boost/test/tools/floating_point_comparison.hpp>
  17. #include <boost/math/special_functions/expm1.hpp>
  18. #include <iostream>
  19. #include <iomanip>
  20. void test_polynomial()
  21. {
  22. #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  23. double (*f)(double) = boost::math::expm1<double>;
  24. #else
  25. double (*f)(double) = boost::math::expm1;
  26. #endif
  27. std::cout << "Testing expm1 approximation, pinned to origin, abolute error, 6 term polynomial\n";
  28. boost::math::tools::remez_minimax<double> approx1(f, 6, 0, -1, 1, true, false);
  29. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  30. for(unsigned i = 0; i < 7; ++i)
  31. {
  32. approx1.iterate();
  33. std::cout << approx1.error_term() << " " << approx1.max_error() << " " << approx1.max_change() << std::endl;
  34. }
  35. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  36. std::cout << "Testing expm1 approximation, pinned to origin, relative error, 6 term polynomial\n";
  37. boost::math::tools::remez_minimax<double> approx2(f, 6, 0, -1, 1, true, true);
  38. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  39. for(unsigned i = 0; i < 7; ++i)
  40. {
  41. approx2.iterate();
  42. std::cout << approx2.error_term() << " " << approx2.max_error() << " " << approx2.max_change() << std::endl;
  43. }
  44. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  45. f = std::exp;
  46. std::cout << "Testing exp approximation, not pinned to origin, abolute error, 6 term polynomial\n";
  47. boost::math::tools::remez_minimax<double> approx3(f, 6, 0, -1, 1, false, false);
  48. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  49. for(unsigned i = 0; i < 7; ++i)
  50. {
  51. approx3.iterate();
  52. std::cout << approx3.error_term() << " " << approx3.max_error() << " " << approx3.max_change() << std::endl;
  53. }
  54. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  55. std::cout << "Testing exp approximation, not pinned to origin, relative error, 6 term polynomial\n";
  56. boost::math::tools::remez_minimax<double> approx4(f, 6, 0, -1, 1, false, true);
  57. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  58. for(unsigned i = 0; i < 7; ++i)
  59. {
  60. approx4.iterate();
  61. std::cout << approx4.error_term() << " " << approx4.max_error() << " " << approx4.max_change() << std::endl;
  62. }
  63. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  64. f = std::cos;
  65. std::cout << "Testing cos approximation, not pinned to origin, abolute error, 5 term polynomial\n";
  66. boost::math::tools::remez_minimax<double> approx5(f, 5, 0, -1, 1, false, false);
  67. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  68. for(unsigned i = 0; i < 7; ++i)
  69. {
  70. approx5.iterate();
  71. std::cout << approx5.error_term() << " " << approx5.max_error() << " " << approx5.max_change() << std::endl;
  72. }
  73. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  74. std::cout << "Testing cos approximation, not pinned to origin, relative error, 5 term polynomial\n";
  75. boost::math::tools::remez_minimax<double> approx6(f, 5, 0, -1, 1, false, true);
  76. for(unsigned i = 0; i < 7; ++i)
  77. {
  78. approx6.iterate();
  79. std::cout << approx6.error_term() << " " << approx6.max_error() << " " << approx6.max_change() << std::endl;
  80. }
  81. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  82. f = std::sin;
  83. std::cout << "Testing sin approximation, pinned to origin, abolute error, 4 term polynomial\n";
  84. boost::math::tools::remez_minimax<double> approx7(f, 4, 0, 0, 1, true, false);
  85. for(unsigned i = 0; i < 7; ++i)
  86. {
  87. approx7.iterate();
  88. std::cout << approx7.error_term() << " " << approx7.max_error() << " " << approx7.max_change() << std::endl;
  89. }
  90. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  91. std::cout << "Testing sin approximation, pinned to origin, relative error, 4 term polynomial\n";
  92. boost::math::tools::remez_minimax<double> approx8(f, 4, 0, 0, 1, true, true);
  93. for(unsigned i = 0; i < 7; ++i)
  94. {
  95. approx8.iterate();
  96. std::cout << approx8.error_term() << " " << approx8.max_error() << " " << approx8.max_change() << std::endl;
  97. }
  98. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  99. }
  100. void test_rational()
  101. {
  102. #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  103. double (*f)(double) = boost::math::expm1<double>;
  104. #else
  105. double (*f)(double) = boost::math::expm1;
  106. #endif
  107. std::cout << "Testing expm1 approximation, pinned to origin, abolute error, 3+3 term rational\n";
  108. boost::math::tools::remez_minimax<double> approx1(f, 3, 3, -1, 1, true, false);
  109. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  110. for(unsigned i = 0; i < 7; ++i)
  111. {
  112. approx1.iterate();
  113. std::cout << approx1.error_term() << " " << approx1.max_error() << " " << approx1.max_change() << std::endl;
  114. }
  115. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  116. #if 0
  117. //
  118. // This one causes UBLAS to fail on some systems, so disabled for now.
  119. //
  120. std::cout << "Testing expm1 approximation, pinned to origin, relative error, 3+3 term rational\n";
  121. boost::math::tools::remez_minimax<double> approx2(f, 3, 3, -1, 1, true, true);
  122. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  123. for(unsigned i = 0; i < 7; ++i)
  124. {
  125. approx2.iterate();
  126. std::cout << approx2.error_term() << " " << approx2.max_error() << " " << approx2.max_change() << std::endl;
  127. }
  128. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  129. #endif
  130. f = std::exp;
  131. std::cout << "Testing exp approximation, not pinned to origin, abolute error, 3+3 term rational\n";
  132. boost::math::tools::remez_minimax<double> approx3(f, 3, 3, -1, 1, false, false);
  133. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  134. for(unsigned i = 0; i < 7; ++i)
  135. {
  136. approx3.iterate();
  137. std::cout << approx3.error_term() << " " << approx3.max_error() << " " << approx3.max_change() << std::endl;
  138. }
  139. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  140. std::cout << "Testing exp approximation, not pinned to origin, relative error, 3+3 term rational\n";
  141. boost::math::tools::remez_minimax<double> approx4(f, 3, 3, -1, 1, false, true);
  142. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  143. for(unsigned i = 0; i < 7; ++i)
  144. {
  145. approx4.iterate();
  146. std::cout << approx4.error_term() << " " << approx4.max_error() << " " << approx4.max_change() << std::endl;
  147. }
  148. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  149. f = std::cos;
  150. std::cout << "Testing cos approximation, not pinned to origin, abolute error, 2+2 term rational\n";
  151. boost::math::tools::remez_minimax<double> approx5(f, 2, 2, 0, 1, false, false);
  152. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  153. for(unsigned i = 0; i < 7; ++i)
  154. {
  155. approx5.iterate();
  156. std::cout << approx5.error_term() << " " << approx5.max_error() << " " << approx5.max_change() << std::endl;
  157. }
  158. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  159. std::cout << "Testing cos approximation, not pinned to origin, relative error, 2+2 term rational\n";
  160. boost::math::tools::remez_minimax<double> approx6(f, 2, 2, 0, 1, false, true);
  161. std::cout << "Interpolation Error: " << approx1.max_error() << std::endl;
  162. for(unsigned i = 0; i < 7; ++i)
  163. {
  164. approx6.iterate();
  165. std::cout << approx6.error_term() << " " << approx6.max_error() << " " << approx6.max_change() << std::endl;
  166. }
  167. std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
  168. }
  169. BOOST_AUTO_TEST_CASE( test_main )
  170. {
  171. test_polynomial();
  172. test_rational();
  173. }