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 --- src/boost/libs/math/test/chebyshev_test.cpp | 147 ++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/boost/libs/math/test/chebyshev_test.cpp (limited to 'src/boost/libs/math/test/chebyshev_test.cpp') diff --git a/src/boost/libs/math/test/chebyshev_test.cpp b/src/boost/libs/math/test/chebyshev_test.cpp new file mode 100644 index 00000000..b5dca51b --- /dev/null +++ b/src/boost/libs/math/test/chebyshev_test.cpp @@ -0,0 +1,147 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + */ + +#define BOOST_TEST_MODULE chebyshev_test + +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::multiprecision::cpp_bin_float_quad; +using boost::multiprecision::cpp_bin_float_50; +using boost::multiprecision::cpp_bin_float_100; +using boost::math::chebyshev_t; +using boost::math::chebyshev_t_prime; +using boost::math::chebyshev_u; + +template +void test_polynomials() +{ + std::cout << "Testing explicit polynomial representations of the Chebyshev polynomials on type " << boost::typeindex::type_id().pretty_name() << "\n"; + + Real x = -2; + Real tol = 400*std::numeric_limits::epsilon(); + if (tol > std::numeric_limits::epsilon()) + tol *= 10; // float results have much larger error rates. + while (x < 2) + { + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(0, x), Real(1), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(1, x), x, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(2, x), 2*x*x - 1, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(3, x), x*(4*x*x-3), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(4, x), 8*x*x*(x*x - 1) + 1, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(5, x), x*(16*x*x*x*x - 20*x*x + 5), tol); + x += 1/static_cast(1<<7); + } + + x = -2; + tol = 10*tol; + while (x < 2) + { + BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(0, x), Real(1), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(1, x), 2*x, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(2, x), 4*x*x - 1, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(3, x), 4*x*(2*x*x - 1), tol); + x += 1/static_cast(1<<7); + } +} + + +template +void test_derivatives() +{ + std::cout << "Testing explicit polynomial representations of the Chebyshev polynomial derivatives on type " << boost::typeindex::type_id().pretty_name() << "\n"; + + Real x = -2; + Real tol = 1000*std::numeric_limits::epsilon(); + while (x < 2) + { + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(0, x), Real(0), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(1, x), Real(1), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(2, x), 4*x, tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(3, x), 3*(4*x*x - 1), tol); + BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(4, x), 16*x*(2*x*x - 1), tol); + // This one makes the tolerance have to grow too large; the Chebyshev recurrence is more stable than naive polynomial evaluation anyway. + //BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(5, x), 5*(4*x*x*(4*x*x - 3) + 1), tol); + x += 1/static_cast(1<<7); + } +} + +template +void test_clenshaw_recurrence() +{ + using boost::math::chebyshev_clenshaw_recurrence; + boost::array c0 = { {2, 0, 0, 0, 0} }; + // Check the size = 1 case: + boost::array c01 = { {2} }; + // Check the size = 2 case: + boost::array c02 = { {2, 0} }; + boost::array c1 = { {0, 1, 0, 0} }; + boost::array c2 = { {0, 0, 1, 0} }; + boost::array c3 = { {0, 0, 0, 1, 0} }; + boost::array c4 = { {0, 0, 0, 0, 1} }; + boost::array c5 = { {0, 0, 0, 0, 0, 1} }; + boost::array c6 = { {0, 0, 0, 0, 0, 0, 1} }; + + Real x = -1; + Real tol = 10*std::numeric_limits::epsilon(); + if (tol > std::numeric_limits::epsilon()) + tol *= 100; // float results have much larger error rates. + while (x <= 1) + { + Real y = chebyshev_clenshaw_recurrence(c0.data(), c0.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol); + + y = chebyshev_clenshaw_recurrence(c01.data(), c01.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol); + + y = chebyshev_clenshaw_recurrence(c02.data(), c02.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol); + + y = chebyshev_clenshaw_recurrence(c1.data(), c1.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(1, x), tol); + + y = chebyshev_clenshaw_recurrence(c2.data(), c2.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(2, x), tol); + + y = chebyshev_clenshaw_recurrence(c3.data(), c3.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(3, x), tol); + + y = chebyshev_clenshaw_recurrence(c4.data(), c4.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(4, x), tol); + + y = chebyshev_clenshaw_recurrence(c5.data(), c5.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(5, x), tol); + + y = chebyshev_clenshaw_recurrence(c6.data(), c6.size(), x); + BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(6, x), tol); + + x += static_cast(1)/static_cast(1 << 7); + } +} + +BOOST_AUTO_TEST_CASE(chebyshev_test) +{ + test_clenshaw_recurrence(); + test_clenshaw_recurrence(); + test_clenshaw_recurrence(); + + test_polynomials(); + test_polynomials(); + test_polynomials(); + test_polynomials(); + + test_derivatives(); + test_derivatives(); + test_derivatives(); + test_derivatives(); +} -- cgit v1.2.3