cardinal_quadratic_b_spline_test.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright Nick Thompson, 2019
  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. */
  7. #include "math_unit_test.hpp"
  8. #include <numeric>
  9. #include <utility>
  10. #include <boost/math/interpolators/cardinal_quadratic_b_spline.hpp>
  11. using boost::math::interpolators::cardinal_quadratic_b_spline;
  12. template<class Real>
  13. void test_constant()
  14. {
  15. Real c = 7.2;
  16. Real t0 = 0;
  17. Real h = Real(1)/Real(16);
  18. size_t n = 512;
  19. std::vector<Real> v(n, c);
  20. auto qbs = cardinal_quadratic_b_spline<Real>(v.data(), v.size(), t0, h);
  21. size_t i = 0;
  22. while (i < n) {
  23. Real t = t0 + i*h;
  24. CHECK_ULP_CLOSE(c, qbs(t), 2);
  25. CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), 100*std::numeric_limits<Real>::epsilon());
  26. ++i;
  27. }
  28. i = 0;
  29. while (i < n) {
  30. Real t = t0 + i*h + h/2;
  31. CHECK_ULP_CLOSE(c, qbs(t), 2);
  32. CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), 300*std::numeric_limits<Real>::epsilon());
  33. t = t0 + i*h + h/4;
  34. CHECK_ULP_CLOSE(c, qbs(t), 2);
  35. CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), 150*std::numeric_limits<Real>::epsilon());
  36. ++i;
  37. }
  38. }
  39. template<class Real>
  40. void test_linear()
  41. {
  42. Real m = 8.3;
  43. Real b = 7.2;
  44. Real t0 = 0;
  45. Real h = Real(1)/Real(16);
  46. size_t n = 512;
  47. std::vector<Real> y(n);
  48. for (size_t i = 0; i < n; ++i) {
  49. Real t = i*h;
  50. y[i] = m*t + b;
  51. }
  52. auto qbs = cardinal_quadratic_b_spline<Real>(y.data(), y.size(), t0, h);
  53. size_t i = 0;
  54. while (i < n) {
  55. Real t = t0 + i*h;
  56. CHECK_ULP_CLOSE(m*t+b, qbs(t), 2);
  57. CHECK_ULP_CLOSE(m, qbs.prime(t), 820);
  58. ++i;
  59. }
  60. i = 0;
  61. while (i < n) {
  62. Real t = t0 + i*h + h/2;
  63. CHECK_ULP_CLOSE(m*t+b, qbs(t), 2);
  64. CHECK_MOLLIFIED_CLOSE(m, qbs.prime(t), 1500*std::numeric_limits<Real>::epsilon());
  65. t = t0 + i*h + h/4;
  66. CHECK_ULP_CLOSE(m*t+b, qbs(t), 3);
  67. CHECK_MOLLIFIED_CLOSE(m, qbs.prime(t), 1500*std::numeric_limits<Real>::epsilon());
  68. ++i;
  69. }
  70. }
  71. template<class Real>
  72. void test_quadratic()
  73. {
  74. Real a = 8.2;
  75. Real b = 7.2;
  76. Real c = -9.2;
  77. Real t0 = 0;
  78. Real h = Real(1)/Real(16);
  79. size_t n = 513;
  80. std::vector<Real> y(n);
  81. for (size_t i = 0; i < n; ++i) {
  82. Real t = i*h;
  83. y[i] = a*t*t + b*t + c;
  84. }
  85. Real t_max = t0 + (n-1)*h;
  86. auto qbs = cardinal_quadratic_b_spline<Real>(y, t0, h, b, 2*a*t_max + b);
  87. size_t i = 0;
  88. while (i < n) {
  89. Real t = t0 + i*h;
  90. CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 2);
  91. ++i;
  92. }
  93. i = 0;
  94. while (i < n) {
  95. Real t = t0 + i*h + h/2;
  96. CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 47);
  97. t = t0 + i*h + h/4;
  98. if (!CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 104)) {
  99. std::cerr << " Problem abscissa t = " << t << "\n";
  100. }
  101. ++i;
  102. }
  103. }
  104. int main()
  105. {
  106. test_constant<float>();
  107. test_constant<double>();
  108. test_constant<long double>();
  109. test_linear<float>();
  110. test_linear<double>();
  111. test_linear<long double>();
  112. test_quadratic<double>();
  113. test_quadratic<long double>();
  114. return boost::math::test::report_errors();
  115. }