From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- .../libs/math/test/cardinal_trigonometric_test.cpp | 233 +++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 src/boost/libs/math/test/cardinal_trigonometric_test.cpp (limited to 'src/boost/libs/math/test/cardinal_trigonometric_test.cpp') diff --git a/src/boost/libs/math/test/cardinal_trigonometric_test.cpp b/src/boost/libs/math/test/cardinal_trigonometric_test.cpp new file mode 100644 index 00000000..99db9cd4 --- /dev/null +++ b/src/boost/libs/math/test/cardinal_trigonometric_test.cpp @@ -0,0 +1,233 @@ +/* + * 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 +#include +#include +#include +#ifdef BOOST_HAS_FLOAT128 +#include +#endif + + +using std::sin; +using boost::math::constants::two_pi; +using boost::math::interpolators::cardinal_trigonometric; + +template +void test_constant() +{ + Real t0 = 0; + Real h = 1; + for(size_t n = 1; n < 20; ++n) + { + Real c = 8; + std::vector v(n, c); + auto ct = cardinal_trigonometric(v, t0, h); + CHECK_ULP_CLOSE(c, ct(0.3), 3); + CHECK_ULP_CLOSE(c*h*n, ct.integrate(), 3); + CHECK_ULP_CLOSE(c*c*h*n, ct.squared_l2(), 3); + CHECK_MOLLIFIED_CLOSE(Real(0), ct.prime(0.8), 25*std::numeric_limits::epsilon()); + CHECK_MOLLIFIED_CLOSE(Real(0), ct.double_prime(0.8), 25*std::numeric_limits::epsilon()); + } +} + +template +void test_interpolation_condition() +{ + std::mt19937 gen(1234); + std::uniform_real_distribution dis(1, 10); + + for(size_t n = 1; n < 20; ++n) { + Real t0 = dis(gen); + Real h = dis(gen); + std::vector v(n); + for (size_t i = 0; i < n; ++i) { + v[i] = dis(gen); + } + auto ct = cardinal_trigonometric(v, t0, h); + for (size_t i = 0; i < n; ++i) { + Real arg = t0 + i*h; + Real expected = v[i]; + Real computed = ct(arg); + if(!CHECK_ULP_CLOSE(expected, computed, 5*n)) + { + std::cerr << " Samples: " << n << "\n"; + } + } + } + +} + + +#ifdef BOOST_HAS_FLOAT128 +void test_constant_q() +{ + __float128 t0 = 0; + __float128 h = 1; + for(size_t n = 1; n < 20; ++n) + { + __float128 c = 8; + std::vector<__float128> v(n, c); + auto ct = cardinal_trigonometric(v, t0, h); + CHECK_ULP_CLOSE(boost::multiprecision::float128(c), boost::multiprecision::float128(ct(0.3)), 3); + CHECK_ULP_CLOSE(boost::multiprecision::float128(c*h*n), boost::multiprecision::float128(ct.integrate()), 3); + } +} +#endif + + +template +void test_sampled_sine() +{ + using std::sin; + using std::cos; + for (unsigned n = 15; n < 50; ++n) + { + Real t0 = 0; + Real T = 1; + Real h = T/n; + std::vector v(n); + auto s = [&](Real t) { return sin(two_pi()*(t-t0)/T);}; + auto s_prime = [&](Real t) { return two_pi()*cos(two_pi()*(t-t0)/T)/T;}; + auto s_double_prime = [&](Real t) { return -two_pi()*two_pi()*sin(two_pi()*(t-t0)/T)/(T*T);}; + for(size_t j = 0; j < v.size(); ++j) + { + Real t = t0 + j*h; + v[j] = s(t); + } + auto ct = cardinal_trigonometric(v, t0, h); + CHECK_ULP_CLOSE(T, ct.period(), 3); + std::mt19937 gen(1234); + std::uniform_real_distribution dist(0, 500); + + unsigned j = 0; + while (j++ < 50) { + Real arg = dist(gen); + Real expected = s(arg); + Real computed = ct(arg); + CHECK_MOLLIFIED_CLOSE(expected, computed, std::numeric_limits::epsilon()*4000); + + expected = s_prime(arg); + computed = ct.prime(arg); + CHECK_MOLLIFIED_CLOSE(expected, computed, 18000*std::numeric_limits::epsilon()); + + expected = s_double_prime(arg); + computed = ct.double_prime(arg); + CHECK_MOLLIFIED_CLOSE(expected, computed, 100000*std::numeric_limits::epsilon()); + + } + CHECK_MOLLIFIED_CLOSE(Real(0), ct.integrate(), std::numeric_limits::epsilon()); + } +} + +template +void test_bump() +{ + using std::exp; + using std::abs; + using std::sqrt; + using std::pow; + auto bump = [](Real x)->Real { if (abs(x) >= 1) { return Real(0); } return exp(-Real(1)/(Real(1)-x*x)); }; + auto bump_prime = [](Real x)->Real { + if (abs(x) >= 1) { return Real(0); } + + return -2*x*exp(-Real(1)/(Real(1)-x*x))/pow(1-x*x,2); + }; + + auto bump_double_prime = [](Real x)->Real { + if (abs(x) >= 1) { return Real(0); } + + return (6*pow(x,4)-2)*exp(-Real(1)/(Real(1)-x*x))/pow(1-x*x,4); + }; + + + Real t0 = -1; + size_t n = 4096; + Real h = Real(2)/Real(n); + + std::vector v(n); + for(size_t i = 0; i < n; ++i) + { + Real t = t0 + i*h; + v[i] = bump(t); + } + + auto ct = cardinal_trigonometric(v, t0, h); + std::mt19937 gen(323723); + std::uniform_real_distribution dis(-0.9, 0.9); + + size_t i = 0; + while (i++ < 1000) + { + Real t = static_cast(dis(gen)); + Real expected = bump(t); + Real computed = ct(t); + if(!CHECK_MOLLIFIED_CLOSE(expected, computed, 2*std::numeric_limits::epsilon())) { + std::cerr << " Problem occured at abscissa " << t << "\n"; + } + + expected = bump_prime(t); + computed = ct.prime(t); + if(!CHECK_MOLLIFIED_CLOSE(expected, computed, 4000*std::numeric_limits::epsilon())) { + std::cerr << " Problem occured at abscissa " << t << "\n"; + } + + expected = bump_double_prime(t); + computed = ct.double_prime(t); + if(!CHECK_MOLLIFIED_CLOSE(expected, computed, 4000*4000*std::numeric_limits::epsilon())) { + std::cerr << " Problem occured at abscissa " << t << "\n"; + } + + + } + + // Wolfram Alpha: + // NIntegrate[Exp[-1/(1-x*x)],{x,-1,1}] + CHECK_ULP_CLOSE(Real(0.443993816168079437823L), ct.integrate(), 3); + + // NIntegrate[Exp[-2/(1-x*x)],{x,-1,1}] + CHECK_ULP_CLOSE(Real(0.1330861208449942715569473279553285713625791551628130055345002588895389L), ct.squared_l2(), 1); + + +} + + +int main() +{ + +#ifdef TEST1 + test_constant(); + test_sampled_sine(); + test_bump(); + test_interpolation_condition(); +#endif + + +#ifdef TEST2 + test_constant(); + test_sampled_sine(); + test_bump(); + test_interpolation_condition(); +#endif + +#ifdef TEST3 + test_constant(); + test_sampled_sine(); + test_bump(); + test_interpolation_condition(); +#endif + +#ifdef TEST4 +#ifdef BOOST_HAS_FLOAT128 +test_constant_q(); +#endif +#endif + + return boost::math::test::report_errors(); +} -- cgit v1.2.3