]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/math/test/chebyshev_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / math / test / chebyshev_test.cpp
CommitLineData
b32b8144
FG
1/*
2 * Copyright Nick Thompson, 2017
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
8#define BOOST_TEST_MODULE chebyshev_test
9
10#include <boost/type_index.hpp>
11#include <boost/test/included/unit_test.hpp>
92f5a8d4 12#include <boost/test/tools/floating_point_comparison.hpp>
b32b8144
FG
13#include <boost/math/special_functions/chebyshev.hpp>
14#include <boost/math/special_functions/sinc.hpp>
15#include <boost/multiprecision/cpp_bin_float.hpp>
16#include <boost/multiprecision/cpp_dec_float.hpp>
17#include <boost/array.hpp>
18
19using boost::multiprecision::cpp_bin_float_quad;
20using boost::multiprecision::cpp_bin_float_50;
21using boost::multiprecision::cpp_bin_float_100;
22using boost::math::chebyshev_t;
23using boost::math::chebyshev_t_prime;
24using boost::math::chebyshev_u;
25
26template<class Real>
27void test_polynomials()
28{
29 std::cout << "Testing explicit polynomial representations of the Chebyshev polynomials on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
30
31 Real x = -2;
11fdf7f2 32 Real tol = 400*std::numeric_limits<Real>::epsilon();
b32b8144
FG
33 if (tol > std::numeric_limits<float>::epsilon())
34 tol *= 10; // float results have much larger error rates.
35 while (x < 2)
36 {
37 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(0, x), Real(1), tol);
38 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(1, x), x, tol);
39 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(2, x), 2*x*x - 1, tol);
40 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(3, x), x*(4*x*x-3), tol);
41 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(4, x), 8*x*x*(x*x - 1) + 1, tol);
42 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t(5, x), x*(16*x*x*x*x - 20*x*x + 5), tol);
43 x += 1/static_cast<Real>(1<<7);
44 }
45
46 x = -2;
47 tol = 10*tol;
48 while (x < 2)
49 {
50 BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(0, x), Real(1), tol);
51 BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(1, x), 2*x, tol);
52 BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(2, x), 4*x*x - 1, tol);
53 BOOST_CHECK_CLOSE_FRACTION(chebyshev_u(3, x), 4*x*(2*x*x - 1), tol);
54 x += 1/static_cast<Real>(1<<7);
55 }
56}
57
58
59template<class Real>
60void test_derivatives()
61{
62 std::cout << "Testing explicit polynomial representations of the Chebyshev polynomial derivatives on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
63
64 Real x = -2;
65 Real tol = 1000*std::numeric_limits<Real>::epsilon();
66 while (x < 2)
67 {
68 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(0, x), Real(0), tol);
69 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(1, x), Real(1), tol);
70 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(2, x), 4*x, tol);
71 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(3, x), 3*(4*x*x - 1), tol);
72 BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(4, x), 16*x*(2*x*x - 1), tol);
73 // This one makes the tolerance have to grow too large; the Chebyshev recurrence is more stable than naive polynomial evaluation anyway.
74 //BOOST_CHECK_CLOSE_FRACTION(chebyshev_t_prime(5, x), 5*(4*x*x*(4*x*x - 3) + 1), tol);
75 x += 1/static_cast<Real>(1<<7);
76 }
77}
78
79template<class Real>
80void test_clenshaw_recurrence()
81{
82 using boost::math::chebyshev_clenshaw_recurrence;
83 boost::array<Real, 5> c0 = { {2, 0, 0, 0, 0} };
84 // Check the size = 1 case:
85 boost::array<Real, 1> c01 = { {2} };
86 // Check the size = 2 case:
87 boost::array<Real, 2> c02 = { {2, 0} };
88 boost::array<Real, 4> c1 = { {0, 1, 0, 0} };
89 boost::array<Real, 4> c2 = { {0, 0, 1, 0} };
90 boost::array<Real, 5> c3 = { {0, 0, 0, 1, 0} };
91 boost::array<Real, 5> c4 = { {0, 0, 0, 0, 1} };
92 boost::array<Real, 6> c5 = { {0, 0, 0, 0, 0, 1} };
93 boost::array<Real, 7> c6 = { {0, 0, 0, 0, 0, 0, 1} };
94
95 Real x = -1;
96 Real tol = 10*std::numeric_limits<Real>::epsilon();
97 if (tol > std::numeric_limits<float>::epsilon())
98 tol *= 100; // float results have much larger error rates.
99 while (x <= 1)
100 {
101 Real y = chebyshev_clenshaw_recurrence(c0.data(), c0.size(), x);
102 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol);
103
104 y = chebyshev_clenshaw_recurrence(c01.data(), c01.size(), x);
105 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol);
106
107 y = chebyshev_clenshaw_recurrence(c02.data(), c02.size(), x);
108 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(0, x), tol);
109
110 y = chebyshev_clenshaw_recurrence(c1.data(), c1.size(), x);
111 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(1, x), tol);
112
113 y = chebyshev_clenshaw_recurrence(c2.data(), c2.size(), x);
114 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(2, x), tol);
115
116 y = chebyshev_clenshaw_recurrence(c3.data(), c3.size(), x);
117 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(3, x), tol);
118
119 y = chebyshev_clenshaw_recurrence(c4.data(), c4.size(), x);
120 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(4, x), tol);
121
122 y = chebyshev_clenshaw_recurrence(c5.data(), c5.size(), x);
123 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(5, x), tol);
124
125 y = chebyshev_clenshaw_recurrence(c6.data(), c6.size(), x);
126 BOOST_CHECK_CLOSE_FRACTION(y, chebyshev_t(6, x), tol);
127
128 x += static_cast<Real>(1)/static_cast<Real>(1 << 7);
129 }
130}
131
132BOOST_AUTO_TEST_CASE(chebyshev_test)
133{
134 test_clenshaw_recurrence<float>();
135 test_clenshaw_recurrence<double>();
136 test_clenshaw_recurrence<long double>();
137
138 test_polynomials<float>();
139 test_polynomials<double>();
140 test_polynomials<long double>();
141 test_polynomials<cpp_bin_float_quad>();
142
143 test_derivatives<float>();
144 test_derivatives<double>();
145 test_derivatives<long double>();
146 test_derivatives<cpp_bin_float_quad>();
147}