2
0
mirror of https://github.com/boostorg/math.git synced 2026-02-25 04:22:15 +00:00
Files
math/test/cardinal_quadratic_b_spline_test.cpp
jzmaddock fae96bf542 S390x testing: make all the tests 128-bit float safe.
* Remove tests we don't need right now.
!!!REVERT THIS COMMIT BEFORE MERGING!!!

* Add s390x testing to drone.

* Correct drone file.

* Correct drone file (again)

* Prevent complete cancellation in bessel_jy logic.

* Correct testing for 128-bit floats.

* Make some more tests 128-bit long double safe.

* Make more tests 128-bit float safe.

* Fix some more 128-bit testing issues.

* More 128-bit float fixes.

* Make more tests 128-bit float safe.

* Fix up remaining tests for 128-bit floats.

* Yet more 128-bit float test case fixes.

* Fix up more tests for 128-bit floats and non-intel platforms.

* Fix up more tests to be 128-bit long double safe.

* More test case adjustments.

* More 128-bit float error rate adjustments.

* Fixes for autodiff tests

* Two more test fixes.

* Fix up daubechies_scaling_test.cpp and reinstate full CI.

Co-authored-by: Matt Borland <matt@mattborland.com>
2023-01-11 18:31:05 +00:00

136 lines
3.4 KiB
C++

/*
* Copyright Nick Thompson, 2019
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "math_unit_test.hpp"
#include <numeric>
#include <utility>
#include <boost/math/interpolators/cardinal_quadratic_b_spline.hpp>
using boost::math::interpolators::cardinal_quadratic_b_spline;
template<class Real>
void test_constant()
{
Real c = 7.2;
Real t0 = 0;
Real h = Real(1)/Real(16);
size_t n = 512;
std::vector<Real> v(n, c);
auto qbs = cardinal_quadratic_b_spline<Real>(v.data(), v.size(), t0, h);
size_t i = 0;
while (i < n) {
Real t = t0 + i*h;
CHECK_ULP_CLOSE(c, qbs(t), 2);
CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), (std::numeric_limits<Real>::digits > 100 ? 200 : 100) * std::numeric_limits<Real>::epsilon());
++i;
}
i = 0;
while (i < n) {
Real t = t0 + i*h + h/2;
CHECK_ULP_CLOSE(c, qbs(t), 2);
CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), 300*std::numeric_limits<Real>::epsilon());
t = t0 + i*h + h/4;
CHECK_ULP_CLOSE(c, qbs(t), 2);
CHECK_MOLLIFIED_CLOSE(0, qbs.prime(t), (std::numeric_limits<Real>::digits > 100 ? 300 : 150) * std::numeric_limits<Real>::epsilon());
++i;
}
}
template<class Real>
void test_linear()
{
Real m = 8.3;
Real b = 7.2;
Real t0 = 0;
Real h = Real(1)/Real(16);
size_t n = 512;
std::vector<Real> y(n);
for (size_t i = 0; i < n; ++i) {
Real t = i*h;
y[i] = m*t + b;
}
auto qbs = cardinal_quadratic_b_spline<Real>(y.data(), y.size(), t0, h);
size_t i = 0;
while (i < n) {
Real t = t0 + i*h;
CHECK_ULP_CLOSE(m*t+b, qbs(t), 2);
CHECK_ULP_CLOSE(m, qbs.prime(t), 820);
++i;
}
i = 0;
while (i < n) {
Real t = t0 + i*h + h/2;
CHECK_ULP_CLOSE(m*t+b, qbs(t), 2);
CHECK_MOLLIFIED_CLOSE(m, qbs.prime(t), 1500*std::numeric_limits<Real>::epsilon());
t = t0 + i*h + h/4;
CHECK_ULP_CLOSE(m*t+b, qbs(t), 3);
CHECK_MOLLIFIED_CLOSE(m, qbs.prime(t), 1500*std::numeric_limits<Real>::epsilon());
++i;
}
}
template<class Real>
void test_quadratic()
{
Real a = 8.2;
Real b = 7.2;
Real c = -9.2;
Real t0 = 0;
Real h = Real(1)/Real(16);
size_t n = 513;
std::vector<Real> y(n);
for (size_t i = 0; i < n; ++i) {
Real t = i*h;
y[i] = a*t*t + b*t + c;
}
Real t_max = t0 + (n-1)*h;
auto qbs = cardinal_quadratic_b_spline<Real>(y, t0, h, b, 2*a*t_max + b);
size_t i = 0;
while (i < n) {
Real t = t0 + i*h;
CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 2);
++i;
}
i = 0;
while (i < n) {
Real t = t0 + i*h + h/2;
CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 47);
t = t0 + i*h + h/4;
if (!CHECK_ULP_CLOSE(a*t*t + b*t + c, qbs(t), 104)) {
std::cerr << " Problem abscissa t = " << t << "\n";
}
++i;
}
}
int main()
{
test_constant<float>();
test_constant<double>();
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_constant<long double>();
#endif
test_linear<float>();
test_linear<double>();
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_linear<long double>();
#endif
test_quadratic<double>();
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_quadratic<long double>();
#endif
return boost::math::test::report_errors();
}