diff --git a/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp b/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp index 22491a70a..2064caa51 100644 --- a/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp +++ b/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp @@ -225,7 +225,7 @@ cardinal_cubic_b_spline_imp::cardinal_cubic_b_spline_imp(BidiIterator f, B // mapsto // 1 0 -1 | r0 // 0 1 1/2| (r1 - r0)/4 - super_diagonal[1] = 0.5; + super_diagonal[1] = static_cast(0.5); rhs[1] = (rhs[1] - rhs[0])/4; // Now do a tridiagonal row reduction the standard way, until just before the last row: diff --git a/test/cardinal_cubic_b_spline_test.cpp b/test/cardinal_cubic_b_spline_test.cpp index 9dcef343b..90452d6e5 100644 --- a/test/cardinal_cubic_b_spline_test.cpp +++ b/test/cardinal_cubic_b_spline_test.cpp @@ -14,8 +14,13 @@ #include #include #include +#include #include +#if __has_include() +# include +#endif + using boost::multiprecision::cpp_bin_float_50; using boost::math::constants::third; using boost::math::constants::half; @@ -26,12 +31,12 @@ void test_b3_spline() std::cout << "Testing evaluation of spline basis functions on type " << boost::typeindex::type_id().pretty_name() << "\n"; // Outside the support: Real eps = std::numeric_limits::epsilon(); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline(2.5), (Real) 0); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline(-2.5), (Real) 0); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_prime(2.5), (Real) 0); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_prime(-2.5), (Real) 0); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_double_prime(2.5), (Real) 0); - BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_double_prime(-2.5), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline(Real(2.5)), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline(Real(-2.5)), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_prime(Real(2.5)), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_prime(Real(-2.5)), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_double_prime(Real(2.5)), (Real) 0); + BOOST_CHECK_SMALL(boost::math::interpolators::detail::b3_spline_double_prime(Real(-2.5)), (Real) 0); // On the boundary of support: @@ -52,7 +57,7 @@ void test_b3_spline() // Properties: B3 is an even function, B3' is an odd function. for (size_t i = 1; i < 200; ++i) { - Real arg = i*0.01; + Real arg = i*Real(0.01); BOOST_CHECK_CLOSE(boost::math::interpolators::detail::b3_spline(arg), boost::math::interpolators::detail::b3_spline(arg), eps); BOOST_CHECK_CLOSE(boost::math::interpolators::detail::b3_spline_prime(-arg), -boost::math::interpolators::detail::b3_spline_prime(arg), eps); BOOST_CHECK_CLOSE(boost::math::interpolators::detail::b3_spline_double_prime(-arg), boost::math::interpolators::detail::b3_spline_double_prime(arg), eps); @@ -76,8 +81,8 @@ void test_interpolation_condition() v[i] = dis(gen); } - Real step = 0.01; - Real a = 5; + Real step = static_cast(0.01); + Real a = Real(5); boost::math::interpolators::cardinal_cubic_b_spline spline(v.data(), v.size(), a, step); for (size_t i = 0; i < v.size(); ++i) @@ -99,21 +104,21 @@ void test_constant_function() Real constant = 50.2; for (size_t i = 0; i < v.size(); ++i) { - v[i] = 50.2; + v[i] = Real(50.2); } - Real step = 0.02; + Real step = static_cast(0.02); Real a = 5; boost::math::interpolators::cardinal_cubic_b_spline spline(v.data(), v.size(), a, step); for (size_t i = 0; i < v.size(); ++i) { // Do not test at interpolation point; we already know it works there: - Real y = spline(i*step + a + 0.001); + Real y = spline(i*step + a + Real(0.001)); BOOST_CHECK_CLOSE(y, constant, 10*std::numeric_limits::epsilon()); - Real y_prime = spline.prime(i*step + a + 0.002); + Real y_prime = spline.prime(i*step + a + Real(0.002)); BOOST_CHECK_SMALL(y_prime, 5000*std::numeric_limits::epsilon()); - Real y_double_prime = spline.double_prime(i*step + a + 0.002); + Real y_double_prime = spline.double_prime(i*step + a + Real(0.002)); BOOST_CHECK_SMALL(y_double_prime, 5000*std::numeric_limits::epsilon()); } @@ -123,9 +128,9 @@ void test_constant_function() for (size_t i = 0; i < v.size(); ++i) { - Real y = spline(i*step + a + 0.002); + Real y = spline(i*step + a + Real(0.002)); BOOST_CHECK_CLOSE(y, constant, std::numeric_limits::epsilon()); - Real y_prime = spline.prime(i*step + a + 0.002); + Real y_prime = spline.prime(i*step + a + Real(0.002)); BOOST_CHECK_SMALL(y_prime, std::numeric_limits::epsilon()); } @@ -137,9 +142,9 @@ void test_constant_function() for (size_t i = 0; i < v.size(); ++i) { // Do not test at interpolation point; we already know it works there: - Real y = spline2(i*step + a + 0.001); + Real y = spline2(i*step + a + Real(0.001)); BOOST_CHECK_CLOSE(y, constant, 10 * std::numeric_limits::epsilon()); - Real y_prime = spline2.prime(i*step + a + 0.002); + Real y_prime = spline2.prime(i*step + a + Real(0.002)); BOOST_CHECK_SMALL(y_prime, 5000 * std::numeric_limits::epsilon()); } @@ -148,9 +153,9 @@ void test_constant_function() for (size_t i = 0; i < v.size(); ++i) { - Real y = spline2(i*step + a + 0.002); + Real y = spline2(i*step + a + Real(0.002)); BOOST_CHECK_CLOSE(y, constant, std::numeric_limits::epsilon()); - Real y_prime = spline2.prime(i*step + a + 0.002); + Real y_prime = spline2.prime(i*step + a + Real(0.002)); BOOST_CHECK_SMALL(y_prime, std::numeric_limits::epsilon()); } } @@ -164,7 +169,7 @@ void test_affine_function() std::vector v(500); Real a = 10; Real b = 8; - Real step = 0.005; + Real step = static_cast(0.005); auto f = [a, b](Real x) { return a*x + b; }; for (size_t i = 0; i < v.size(); ++i) @@ -176,7 +181,7 @@ void test_affine_function() for (size_t i = 0; i < v.size() - 1; ++i) { - Real arg = i*step + 0.0001; + Real arg = static_cast(i*step + Real(0.0001)); Real y = spline(arg); BOOST_CHECK_CLOSE(y, f(arg), sqrt(std::numeric_limits::epsilon())); Real y_prime = spline.prime(arg); @@ -188,7 +193,7 @@ void test_affine_function() for (size_t i = 0; i < v.size() - 1; ++i) { - Real arg = i*step + 0.0001; + Real arg = static_cast(i*step + Real(0.0001)); Real y = spline(arg); BOOST_CHECK_CLOSE(y, f(arg), sqrt(std::numeric_limits::epsilon())); Real y_prime = spline.prime(arg); @@ -203,10 +208,10 @@ void test_quadratic_function() using std::sqrt; std::cout << "Testing that quadratic functions are interpolated correctly by cubic b splines on type " << boost::typeindex::type_id().pretty_name() << "\n"; std::vector v(500); - Real a = 1.2; - Real b = -3.4; - Real c = -8.6; - Real step = 0.01; + Real a = static_cast(1.2); + Real b = static_cast(-3.4); + Real c = static_cast(-8.6); + Real step = static_cast(0.01); auto f = [a, b, c](Real x) { return a*x*x + b*x + c; }; for (size_t i = 0; i < v.size(); ++i) @@ -218,11 +223,11 @@ void test_quadratic_function() for (size_t i = 0; i < v.size() -1; ++i) { - Real arg = i*step + 0.001; + Real arg = static_cast(i*step + Real(0.001)); Real y = spline(arg); - BOOST_CHECK_CLOSE(y, f(arg), 0.1); + BOOST_CHECK_CLOSE(y, f(arg), Real(0.1)); Real y_prime = spline.prime(arg); - BOOST_CHECK_CLOSE(y_prime, 2*a*arg + b, 2.0); + BOOST_CHECK_CLOSE(y_prime, 2*a*arg + b, Real(2.0)); } } @@ -233,9 +238,9 @@ void test_circ_conic_function() using std::sqrt; std::cout << "Testing that conic section of a circle is interpolated correctly by cubic b splines on type " << boost::typeindex::type_id().pretty_name() << '\n'; std::vector v(500); - Real cv = 0.1; - Real w = 2.0; - Real step = 2 * w / (v.size() - 1); + Real cv = Real(0.1); + Real w = Real(2.0); + Real step = Real(2 * w / (v.size() - 1)); auto f = [cv](Real x) { return cv * x * x / (1 + sqrt(1 - cv * cv * x * x)); }; auto df = [cv](Real x) { return cv * x / sqrt(1 - cv * cv * x * x); }; @@ -256,11 +261,11 @@ void test_circ_conic_function() for (size_t i = 0; i < v.size() - 1; ++i) { - Real arg = -w + i * step + 0.001; + Real arg = -w + i * step + Real(0.001); Real y = spline(arg); - BOOST_CHECK_CLOSE(y, f(arg), 2.0); + BOOST_CHECK_CLOSE(y, f(arg), Real(2.0)); Real y_prime = spline.prime(arg); - BOOST_CHECK_CLOSE(y_prime, df(arg), 1.0); + BOOST_CHECK_CLOSE(y_prime, df(arg), Real(1.0)); } } @@ -272,7 +277,7 @@ void test_trig_function() std::mt19937 gen; std::vector v(500); Real x0 = 1; - Real step = 0.125; + Real step = Real(0.125); for (size_t i = 0; i < v.size(); ++i) { @@ -287,9 +292,9 @@ void test_trig_function() { Real x = abscissa(gen); Real y = spline(x); - BOOST_CHECK_CLOSE(y, sin(x), 1.0); + BOOST_CHECK_CLOSE(y, Real(sin(x)), Real(1.0)); auto y_prime = spline.prime(x); - BOOST_CHECK_CLOSE(y_prime, cos(x), 2.0); + BOOST_CHECK_CLOSE(y_prime, Real(cos(x)), Real(2.0)); } } @@ -299,7 +304,8 @@ void test_copy_move() std::cout << "Testing that copy/move operation succeed on cubic b spline\n"; std::vector v(500); Real x0 = 1; - Real step = 0.125; + Real step = static_cast(0.125); + constexpr Real tol = Real(0.01); for (size_t i = 0; i < v.size(); ++i) { @@ -312,22 +318,22 @@ void test_copy_move() // Default constructor should compile so that splines can be member variables: boost::math::interpolators::cardinal_cubic_b_spline d; d = boost::math::interpolators::cardinal_cubic_b_spline(v.data(), v.size(), x0, step); - BOOST_CHECK_CLOSE(d(x0), sin(x0), 0.01); + BOOST_CHECK_CLOSE(d(x0), Real(sin(x0)), tol); // Passing to lambda should compile: auto f = [=](Real x) { return d(x); }; // Make sure this variable is used. - BOOST_CHECK_CLOSE(f(x0), sin(x0), 0.01); + BOOST_CHECK_CLOSE(f(x0), Real(sin(x0)), tol); // Move operations should compile. auto s = std::move(spline); // Copy operations should compile: boost::math::interpolators::cardinal_cubic_b_spline c = d; - BOOST_CHECK_CLOSE(c(x0), sin(x0), 0.01); + BOOST_CHECK_CLOSE(c(x0), Real(sin(x0)), tol); // Test with std::bind: - auto h = std::bind(&boost::math::interpolators::cardinal_cubic_b_spline::operator(), &s, std::placeholders::_1); - BOOST_CHECK_CLOSE(h(x0), sin(x0), 0.01); + auto h = std::bind(&boost::math::interpolators::cardinal_cubic_b_spline::operator(), &s, std::placeholders::_1); + BOOST_CHECK_CLOSE(h(x0), Real(sin(x0)), tol); } template @@ -336,7 +342,7 @@ void test_outside_interval() std::cout << "Testing that the spline can be evaluated outside the interpolation interval\n"; std::vector v(400); Real x0 = 1; - Real step = 0.125; + Real step = Real(0.125); for (size_t i = 0; i < v.size(); ++i) { @@ -354,54 +360,70 @@ void test_outside_interval() BOOST_AUTO_TEST_CASE(test_cubic_b_spline) { + #ifdef __STDCPP_FLOAT32_T__ + + test_b3_spline(); + test_interpolation_condition(); + test_constant_function(); + test_affine_function(); + test_quadratic_function(); + test_circ_conic_function(); + test_trig_function(); + + #else + test_b3_spline(); - test_b3_spline(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_b3_spline(); -#endif - test_b3_spline(); - test_interpolation_condition(); - test_interpolation_condition(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_interpolation_condition(); -#endif - test_interpolation_condition(); - test_constant_function(); - test_constant_function(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_constant_function(); -#endif - test_constant_function(); - test_affine_function(); - test_affine_function(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_affine_function(); -#endif - test_affine_function(); - test_quadratic_function(); - test_quadratic_function(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_quadratic_function(); -#endif - test_quadratic_function(); - test_circ_conic_function(); - test_circ_conic_function(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_circ_conic_function(); -#endif - test_trig_function(); - test_trig_function(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_trig_function(); -#endif - test_trig_function(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + + test_b3_spline(); + test_interpolation_condition(); + test_constant_function(); + test_affine_function(); + test_quadratic_function(); + test_circ_conic_function(); + test_trig_function(); + test_copy_move(); + test_outside_interval(); + + #else + + test_b3_spline(); + test_interpolation_condition(); + test_constant_function(); + test_affine_function(); + test_quadratic_function(); + test_circ_conic_function(); + test_trig_function(); test_copy_move(); test_outside_interval(); + + #endif + + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + + test_b3_spline(); + test_interpolation_condition(); + test_constant_function(); + test_affine_function(); + test_quadratic_function(); + test_circ_conic_function(); + test_trig_function(); + + #endif + + test_b3_spline(); + test_interpolation_condition(); + test_constant_function(); + test_affine_function(); + test_quadratic_function(); + test_trig_function(); }