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)
8 #include "math_unit_test.hpp"
12 #include <boost/core/demangle.hpp>
13 #include <boost/math/interpolators/whittaker_shannon.hpp>
14 #ifdef BOOST_HAS_FLOAT128
15 #include <boost/multiprecision/float128.hpp>
16 using boost::multiprecision::float128
;
19 using boost::math::interpolators::whittaker_shannon
;
25 Real h
= Real(1)/Real(16);
26 std::vector
<Real
> v
{1.5};
27 std::vector
<Real
> v_copy
= v
;
28 auto ws
= whittaker_shannon
<decltype(v
)>(std::move(v
), t0
, h
);
32 if(!CHECK_MOLLIFIED_CLOSE(expected
, ws
.prime(0), 10*std::numeric_limits
<Real
>::epsilon())) {
33 std::cerr
<< " Problem occurred at abscissa " << 0 << "\n";
36 expected
= -v_copy
[0]/h
;
37 if(!CHECK_MOLLIFIED_CLOSE(expected
, ws
.prime(h
), 10*std::numeric_limits
<Real
>::epsilon())) {
38 std::cerr
<< " Problem occurred at abscissa " << 0 << "\n";
46 Real h
= Real(1)/Real(16);
48 std::vector
<Real
> v(n
);
49 std::mt19937
gen(323723);
50 std::uniform_real_distribution
<Real
> dis(1.0, 2.0);
52 for(size_t i
= 0; i
< n
; ++i
) {
53 v
[i
] = static_cast<Real
>(dis(gen
));
55 auto ws
= whittaker_shannon
<decltype(v
)>(std::move(v
), t0
, h
);
60 Real expected
= ws
[i
];
61 Real computed
= ws(t
);
62 CHECK_ULP_CLOSE(expected
, computed
, 16);
73 auto bump
= [](Real x
) { if (abs(x
) >= 1) { return Real(0); } return exp(-Real(1)/(Real(1)-x
*x
)); };
75 auto bump_prime
= [&bump
](Real x
) { Real z
= 1-x
*x
; return -2*x
*bump(x
)/(z
*z
); };
79 Real h
= Real(2)/Real(n
-1);
81 std::vector
<Real
> v(n
);
82 for(size_t i
= 0; i
< n
; ++i
) {
88 std::vector
<Real
> v_copy
= v
;
89 auto ws
= whittaker_shannon
<decltype(v
)>(std::move(v
), t0
, h
);
92 for(size_t i
= v_copy
.size()/4; i
< 3*v_copy
.size()/4; ++i
) {
94 Real expected
= v_copy
[i
];
95 Real computed
= ws(t
);
96 if(!CHECK_MOLLIFIED_CLOSE(expected
, computed
, 10*std::numeric_limits
<Real
>::epsilon())) {
97 std::cerr
<< " Problem occurred at abscissa " << t
<< "\n";
100 Real expected_prime
= bump_prime(t
);
101 Real computed_prime
= ws
.prime(t
);
102 if(!CHECK_MOLLIFIED_CLOSE(expected_prime
, computed_prime
, 1000*std::numeric_limits
<Real
>::epsilon())) {
103 std::cerr
<< " Problem occurred at abscissa " << t
<< "\n";
108 std::mt19937
gen(323723);
109 std::uniform_real_distribution
<long double> dis(-0.85, 0.85);
114 Real t
= static_cast<Real
>(dis(gen
));
115 Real expected
= bump(t
);
116 Real computed
= ws(t
);
117 if(!CHECK_MOLLIFIED_CLOSE(expected
, computed
, 10*std::numeric_limits
<Real
>::epsilon())) {
118 std::cerr
<< " Problem occurred at abscissa " << t
<< "\n";
121 Real expected_prime
= bump_prime(t
);
122 Real computed_prime
= ws
.prime(t
);
123 if(!CHECK_MOLLIFIED_CLOSE(expected_prime
, computed_prime
, sqrt(std::numeric_limits
<Real
>::epsilon()))) {
124 std::cerr
<< " Problem occurred at abscissa " << t
<< "\n";
133 test_knots
<double>();
134 test_knots
<long double>();
137 test_bump
<long double>();
139 test_trivial
<float>();
140 test_trivial
<double>();
141 return boost::math::test::report_errors();