From 7a6efabba5af757defc87aedecc1cc4d18d52b4d Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 24 Apr 2023 14:25:13 +0200 Subject: [PATCH 01/53] First draft of promotion --- include/boost/math/tools/promotion.hpp | 123 ++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/include/boost/math/tools/promotion.hpp b/include/boost/math/tools/promotion.hpp index 55ba064c71..6a89cf9140 100644 --- a/include/boost/math/tools/promotion.hpp +++ b/include/boost/math/tools/promotion.hpp @@ -2,6 +2,7 @@ // Copyright John Maddock 2006. // Copyright Paul A. Bristow 2006. +// Copyright Matt Borland 2023. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. @@ -25,6 +26,10 @@ #include #include +#if __has_include() +# include +#endif + namespace boost { namespace math @@ -63,6 +68,19 @@ namespace boost template <> struct promote_arg { using type = long double; }; template <> struct promote_arg { using type = double; }; + #ifdef __STDCPP_FLOAT16_T__ + template <> struct promote_arg { using type = std::float16_t; }; + #endif + #ifdef __STDCPP_FLOAT32_T__ + template <> struct promote_arg { using type = std::float32_t; }; + #endif + #ifdef __STDCPP_FLOAT64_T__ + template <> struct promote_arg { using type = std::float64_t; }; + #endif + #ifdef __STDCPP_FLOAT128_T__ + template <> struct promote_arg { using type = std::float128_t; }; + #endif + template using promote_arg_t = typename promote_arg::type; @@ -78,14 +96,35 @@ namespace boost #ifdef BOOST_MATH_USE_FLOAT128 typename std::conditional::value || std::is_same<__float128, T2P>::value, // either long double? __float128, -#endif +#endif +#ifdef __STDCPP_FLOAT128_T__ + typename std::conditional::value || std::is_same::value, // either long double? + std::float128_t, +#endif typename std::conditional::value || std::is_same::value, // either long double? long double, // then result type is long double. +#ifdef __STDCPP_FLOAT64_T__ + typename std::conditional::value || std::is_same::value, // either float64? + std::float64_t, // then result type is float64_t. +#endif typename std::conditional::value || std::is_same::value, // either double? double, // result type is double. +#ifdef __STDCPP_FLOAT32_T__ + typename std::conditional::value || std::is_same::value, // either float32? + std::float32_t, // then result type is float32_t. +#endif float // else result type is float. >::type #ifdef BOOST_MATH_USE_FLOAT128 + >::type, +#endif +#ifdef __STDCPP_FLOAT128_T__ + >::type +#endif +#ifdef __STDCPP_FLOAT64_T__ + >::type +#endif +#ifdef __STDCPP_FLOAT32_T__ >::type #endif >::type, @@ -111,6 +150,88 @@ namespace boost template <> struct promote_args_2 { using type = long double; }; template <> struct promote_args_2 { using type = long double; }; + #ifdef __STDCPP_FLOAT128_T__ + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + + #ifdef __STDCPP_FLOAT16_T__ + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + #endif + + #ifdef __STDCPP_FLOAT32_T__ + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + #endif + + #ifdef __STDCPP_FLOAT64_T__ + template <> struct promote_args_2 { using type = std::float128_t; }; + template <> struct promote_args_2 { using type = std::float128_t; }; + #endif + + template <> struct promote_args_2 { using type = std::float128_t; }; + #endif + + #ifdef __STDCPP_FLOAT64_T__ + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + + #ifdef __STDCPP_FLOAT16_T__ + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + #endif + + #ifdef __STDCPP_FLOAT32_T__ + template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float64_t; }; + #endif + + template <> struct promote_args_2 { using type = std::float64_t; }; + #endif + + #ifdef __STDCPP_FLOAT32_T__ + template <> struct promote_args_2 { using type = std::float32_t; }; + template <> struct promote_args_2 { using type = std::float32_t; }; + template <> struct promote_args_2 { using type = std::float32_t; }; + template <> struct promote_args_2 { using type = std::float32_t; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + + #ifdef __STDCPP_FLOAT16_T__ + template <> struct promote_args_2 { using type = std::float32_t; }; + template <> struct promote_args_2 { using type = std::float32_t; }; + #endif + + template <> struct promote_args_2 { using type = std::float64_t; }; + #endif + + #ifdef __STDCPP_FLOAT16_T__ + template <> struct promote_args_2 { using type = std::float16_t; }; + template <> struct promote_args_2 { using type = std::float16_t; }; + template <> struct promote_args_2 { using type = float; }; + template <> struct promote_args_2 { using type = float; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + + template <> struct promote_args_2 { using type = std::float16_t; }; + #endif + template using promote_args_2_t = typename promote_args_2::type; From 5dcf5a9fdbe729c245ee1478285f3c97ef972e4f Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 24 Apr 2023 14:53:05 +0200 Subject: [PATCH 02/53] Test beta dist for F64, F32, and F16 --- include/boost/math/distributions/beta.hpp | 31 +++++++++--------- include/boost/math/special_functions/beta.hpp | 5 +-- .../boost/math/special_functions/log1p.hpp | 32 +++++++++---------- test/test_beta_dist.cpp | 30 +++++++++++++++++ 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/include/boost/math/distributions/beta.hpp b/include/boost/math/distributions/beta.hpp index bbc0d6d6a3..6c17ffa1a2 100644 --- a/include/boost/math/distributions/beta.hpp +++ b/include/boost/math/distributions/beta.hpp @@ -2,6 +2,7 @@ // Copyright John Maddock 2006. // Copyright Paul A. Bristow 2006. +// Copyright Matt Borland 2023. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. @@ -241,7 +242,7 @@ namespace boost { return result; } - return ibeta_inva(beta, x, probability, Policy()); + return static_cast(ibeta_inva(beta, x, probability, Policy())); } // RealType find_alpha(beta, a, probability) static RealType find_beta( @@ -264,7 +265,7 @@ namespace boost { return result; } - return ibeta_invb(alpha, x, probability, Policy()); + return static_cast(ibeta_invb(alpha, x, probability, Policy())); } // RealType find_beta(alpha, x, probability) private: @@ -396,7 +397,7 @@ namespace boost { if (a == 1) { - return 1 / beta(a, b); + return static_cast(1 / beta(a, b)); } else if (a < 1) { @@ -411,7 +412,7 @@ namespace boost { if (b == 1) { - return 1 / beta(a, b); + return static_cast(1 / beta(a, b)); } else if (b < 1) { @@ -423,7 +424,7 @@ namespace boost } } - return ibeta_derivative(a, b, x, Policy()); + return static_cast(ibeta_derivative(a, b, x, Policy())); } // pdf template @@ -454,7 +455,7 @@ namespace boost { return 1; } - return ibeta(a, b, x, Policy()); + return static_cast(ibeta(a, b, x, Policy())); } // beta cdf template @@ -481,16 +482,16 @@ namespace boost } if (x == 0) { - return 1; + return RealType(1); } else if (x == 1) { - return 0; + return RealType(0); } // Calculate cdf beta using the incomplete beta function. // Use of ibeta here prevents cancellation errors in calculating // 1 - x if x is very small, perhaps smaller than machine epsilon. - return ibetac(a, b, x, Policy()); + return static_cast(ibetac(a, b, x, Policy())); } // beta cdf template @@ -519,13 +520,13 @@ namespace boost // Special cases: if (p == 0) { - return 0; + return RealType(0); } if (p == 1) { - return 1; + return RealType(1); } - return ibeta_inv(a, b, p, static_cast(nullptr), Policy()); + return static_cast(ibeta_inv(a, b, p, static_cast(nullptr), Policy())); } // quantile template @@ -555,14 +556,14 @@ namespace boost // Special cases: if(q == 1) { - return 0; + return RealType(0); } if(q == 0) { - return 1; + return RealType(1); } - return ibetac_inv(a, b, q, static_cast(nullptr), Policy()); + return static_cast(ibetac_inv(a, b, q, static_cast(nullptr), Policy())); } // Quantile Complement } // namespace math diff --git a/include/boost/math/special_functions/beta.hpp b/include/boost/math/special_functions/beta.hpp index 77ca35dcd8..f566f2afe1 100644 --- a/include/boost/math/special_functions/beta.hpp +++ b/include/boost/math/special_functions/beta.hpp @@ -1501,8 +1501,9 @@ template inline typename tools::promote_args::type beta(RT1 a, RT2 b, A arg) { - typedef typename policies::is_policy::type tag; - return boost::math::detail::beta(a, b, arg, static_cast(nullptr)); + using tag = typename policies::is_policy::type; + using ReturnType = tools::promote_args_t; + return static_cast(boost::math::detail::beta(a, b, arg, static_cast(nullptr))); } template diff --git a/include/boost/math/special_functions/log1p.hpp b/include/boost/math/special_functions/log1p.hpp index 8121a573cd..9b8a8e0eb7 100644 --- a/include/boost/math/special_functions/log1p.hpp +++ b/include/boost/math/special_functions/log1p.hpp @@ -136,24 +136,24 @@ T log1p_imp(T const& x, const Policy& pol, const std::integral_constant // Maximum Relative Change in Control Points: 8.138e-004 // Max Error found at double precision = 3.250766e-016 static const T P[] = { - 0.15141069795941984e-16L, - 0.35495104378055055e-15L, - 0.33333333333332835L, - 0.99249063543365859L, - 1.1143969784156509L, - 0.58052937949269651L, - 0.13703234928513215L, - 0.011294864812099712L + static_cast(0.15141069795941984e-16L), + static_cast(0.35495104378055055e-15L), + static_cast(0.33333333333332835L), + static_cast(0.99249063543365859L), + static_cast(1.1143969784156509L), + static_cast(0.58052937949269651L), + static_cast(0.13703234928513215L), + static_cast(0.011294864812099712L) }; static const T Q[] = { - 1L, - 3.7274719063011499L, - 5.5387948649720334L, - 4.159201143419005L, - 1.6423855110312755L, - 0.31706251443180914L, - 0.022665554431410243L, - -0.29252538135177773e-5L + static_cast(1L), + static_cast(3.7274719063011499L), + static_cast(5.5387948649720334L), + static_cast(4.159201143419005L), + static_cast(1.6423855110312755L), + static_cast(0.31706251443180914L), + static_cast(0.022665554431410243L), + static_cast(-0.29252538135177773e-5L) }; T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); diff --git a/test/test_beta_dist.cpp b/test/test_beta_dist.cpp index d441e5b9dd..943718a39f 100644 --- a/test/test_beta_dist.cpp +++ b/test/test_beta_dist.cpp @@ -52,6 +52,10 @@ using std::endl; #include using std::numeric_limits; +#if __has_include() +# include +#endif + template void test_spot( RealType a, // alpha a @@ -135,6 +139,14 @@ void test_spots(RealType) cout << "epsilon = " << tolerance; tolerance *= 100000; // Note: NO * 100 because is fraction, NOT %. + + #ifdef __STDCPP_FLOAT16_T__ + if constexpr (std::is_same_v) + { + tolerance *= 100; + } + #endif + cout << ", Tolerance = " << tolerance * 100 << "%." << endl; // RealType teneps = boost::math::tools::epsilon() * 10; @@ -527,7 +539,14 @@ void test_spots(RealType) } // has_infinity // Error handling checks: + #ifdef __STDCPP_FLOAT16_T__ + if constexpr (!std::is_same_v) + { + check_out_of_range >(1, 1); // (All) valid constructor parameter values. + } + #else check_out_of_range >(1, 1); // (All) valid constructor parameter values. + #endif // and range and non-finite. // Not needed?????? @@ -631,6 +650,17 @@ BOOST_AUTO_TEST_CASE( test_main ) test_spots(boost::math::concepts::real_concept(0.)); // Test real concept. #endif #endif + +#ifdef __STDCPP_FLOAT64_T__ + test_spots(0.0F64); +#endif +#ifdef __STDCPP_FLOAT32_T__ + test_spots(0.0F32); +#endif +#ifdef __STDCPP_FLOAT16_T__ + test_spots(0.0F16); +#endif + } // BOOST_AUTO_TEST_CASE( test_main ) /* From 4c753c20f7e4263e1b8b28337b4fb325424761a6 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 25 Apr 2023 12:06:16 +0200 Subject: [PATCH 03/53] Reverse 128bits and prefer F64 over long double when it's 64bits --- include/boost/math/tools/promotion.hpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/include/boost/math/tools/promotion.hpp b/include/boost/math/tools/promotion.hpp index 6a89cf9140..701f1927fa 100644 --- a/include/boost/math/tools/promotion.hpp +++ b/include/boost/math/tools/promotion.hpp @@ -90,16 +90,15 @@ namespace boost // for both parameter types, if integral promote to double. using T1P = typename promote_arg::type; // T1 perhaps promoted. using T2P = typename promote_arg::type; // T2 perhaps promoted. - - using type = typename std::conditional< + using intermediate_type = typename std::conditional< std::is_floating_point::value && std::is_floating_point::value, // both T1P and T2P are floating-point? -#ifdef BOOST_MATH_USE_FLOAT128 - typename std::conditional::value || std::is_same<__float128, T2P>::value, // either long double? - __float128, -#endif #ifdef __STDCPP_FLOAT128_T__ typename std::conditional::value || std::is_same::value, // either long double? std::float128_t, +#endif +#ifdef BOOST_MATH_USE_FLOAT128 + typename std::conditional::value || std::is_same<__float128, T2P>::value, // either long double? + __float128, #endif typename std::conditional::value || std::is_same::value, // either long double? long double, // then result type is long double. @@ -116,7 +115,7 @@ namespace boost float // else result type is float. >::type #ifdef BOOST_MATH_USE_FLOAT128 - >::type, + >::type #endif #ifdef __STDCPP_FLOAT128_T__ >::type @@ -130,6 +129,13 @@ namespace boost >::type, // else one or the other is a user-defined type: typename std::conditional::value && std::is_convertible::value, T2P, T1P>::type>::type; + +#ifdef __STDCPP_FLOAT64_T__ + // If long doubles are doubles then we should prefer to use std::float64_t when available + using type = std::conditional_t<(sizeof(double) == sizeof(long double) && std::is_same::value), std::float64_t, intermediate_type>; +#else + using type = intermediate_type; +#endif }; // promote_arg2 // These full specialisations reduce std::conditional usage and speed up // compilation: From 2f0b0ed3661c92d3b78bce6d614325d9ae3e38f3 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 25 Apr 2023 13:35:29 +0200 Subject: [PATCH 04/53] Add more testing --- ...adaptive_gauss_kronrod_quadrature_test.cpp | 15 ++++++++++ test/tanh_sinh_quadrature_test.cpp | 28 +++++++++++++++++-- test/test_exponential_dist.cpp | 17 ++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/test/adaptive_gauss_kronrod_quadrature_test.cpp b/test/adaptive_gauss_kronrod_quadrature_test.cpp index 04cefb9e10..f2c703e92a 100644 --- a/test/adaptive_gauss_kronrod_quadrature_test.cpp +++ b/test/adaptive_gauss_kronrod_quadrature_test.cpp @@ -9,6 +9,10 @@ #include #include +#if __has_include() +# include +#endif + #if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && !defined(BOOST_NO_SFINAE_EXPR) #include @@ -258,6 +262,17 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) test_integration_over_real_line(); test_right_limit_infinite(); test_left_limit_infinite(); + + #ifdef __STDCPP_FLOAT64_T__ + test_linear(); + test_quadratic(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_integration_over_real_line(); + test_right_limit_infinite(); + test_left_limit_infinite(); + #endif + #endif #ifdef TEST1A #if LDBL_MANT_DIG < 100 // If we have too many digits in a long double, we get build errors due to a constexpr issue. diff --git a/test/tanh_sinh_quadrature_test.cpp b/test/tanh_sinh_quadrature_test.cpp index e06c3cfd49..20ce99a97e 100644 --- a/test/tanh_sinh_quadrature_test.cpp +++ b/test/tanh_sinh_quadrature_test.cpp @@ -26,6 +26,10 @@ #include #include +#if __has_include() +# include +#endif + #ifdef BOOST_HAS_FLOAT128 #include #endif @@ -318,8 +322,14 @@ void test_ca() // Slightly higher tolerance for type float, this marginal change was // caused by no more than changing the order in which the terms are summed: // - if (std::is_same::value) - tol *= 1.5; + BOOST_IF_CONSTEXPR (std::is_same::value + #ifdef __STDCPP_FLOAT32_T__ + || std::is_same::value + #endif + ) + { + tol *= static_cast(1.5); + } BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol); BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol); @@ -896,6 +906,20 @@ BOOST_AUTO_TEST_CASE(tanh_sinh_quadrature_test) test_horrible(); test_integration_over_real_line(); test_nr_examples(); + + #ifdef __STDCPP_FLOAT32_T__ + test_right_limit_infinite(); + test_left_limit_infinite(); + test_linear(); + test_quadratic(); + test_singular(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_horrible(); + test_integration_over_real_line(); + test_nr_examples(); + #endif + #endif #ifdef TEST1A test_early_termination(); diff --git a/test/test_exponential_dist.cpp b/test/test_exponential_dist.cpp index c659b91c2b..d1898fa7c4 100644 --- a/test/test_exponential_dist.cpp +++ b/test/test_exponential_dist.cpp @@ -26,6 +26,10 @@ using std::setprecision; using std::log; +#if __has_include() +# include +#endif + template void test_spot(RealType l, RealType x, RealType p, RealType q, RealType logp, RealType logq, RealType tolerance, RealType logtolerance) { @@ -208,7 +212,11 @@ void test_spots(RealType T) static_cast(-9.210390371559516069440021374287500922116L), // log(p), static_cast(-0.000100000000000000000000000000000000000L), // log(q) tolerance, - std::is_same::value ? tolerance * 10 : tolerance); + std::is_same::value + #ifdef __STDCPP_FLOAT32_T__ + || std::is_same::value + #endif + ? tolerance * 10 : tolerance); /* // This test data appears to be erroneous, MathCad appears // to suffer from cancellation error as x -> 0 @@ -375,6 +383,13 @@ BOOST_AUTO_TEST_CASE( test_main ) "to pass." << std::endl; #endif + #ifdef __STDCPP_FLOAT32_T__ + test_spots(0.0F32); + #endif + #ifdef __STDCPP_FLOAT64_T__ + test_spots(0.0F64); + #endif + } // BOOST_AUTO_TEST_CASE( test_main ) /* From bc79263bd0481e0cd96f0c91d0febf5804327def Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 2 May 2023 13:11:44 +0200 Subject: [PATCH 05/53] Add compile tests for F32 and F64 --- test/Jamfile.v2 | 5 +++++ test/compile_test/float32.cpp | 32 +++++++++++++++++++++++++++++++ test/compile_test/float64.cpp | 32 +++++++++++++++++++++++++++++++ test/compile_test/instantiate.hpp | 4 +++- 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test/compile_test/float32.cpp create mode 100644 test/compile_test/float64.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 48c3ff21e3..051e332247 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -902,6 +902,11 @@ test-suite distribution_tests : [ run scipy_issue_18302.cpp ../../test/build//boost_unit_test_framework ] ; +test-suite new_floats : + [ compile compile_test/float32.cpp ] + [ compile compile_test/float64.cpp ] +; + test-suite mp : [ run test_nc_t_quad.cpp pch ../../test/build//boost_unit_test_framework : : : release [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : -lquadmath ] ] diff --git a/test/compile_test/float32.cpp b/test/compile_test/float32.cpp new file mode 100644 index 0000000000..a757b0bb4d --- /dev/null +++ b/test/compile_test/float32.cpp @@ -0,0 +1,32 @@ +// Copyright Matt Borland 2023. +// 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) + +#if __has_include() +# include +#endif + +#ifdef __STDCPP_FLOAT32_T__ + +#define TEST_COMPLEX + +#include "instantiate.hpp" + +int main(int argc, char* []) +{ + if(argc > 10000) + { + instantiate(0.0F32); + instantiate_mixed(0.0F32); + } +} + +#else + +int main(int, char*[]) +{ + return 0; +} + +#endif diff --git a/test/compile_test/float64.cpp b/test/compile_test/float64.cpp new file mode 100644 index 0000000000..a989b93350 --- /dev/null +++ b/test/compile_test/float64.cpp @@ -0,0 +1,32 @@ +// Copyright Matt Borland 2023. +// 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) + +#if __has_include() +# include +#endif + +#ifdef __STDCPP_FLOAT64_T__ + +#define TEST_COMPLEX + +#include "instantiate.hpp" + +int main(int argc, char* []) +{ + if(argc > 10000) + { + instantiate(0.0F64); + instantiate_mixed(0.0F64); + } +} + +#else + +int main(int, char*[]) +{ + return 0; +} + +#endif diff --git a/test/compile_test/instantiate.hpp b/test/compile_test/instantiate.hpp index 024e79c5d6..33939a25ad 100644 --- a/test/compile_test/instantiate.hpp +++ b/test/compile_test/instantiate.hpp @@ -181,7 +181,9 @@ void instantiate(RealType) int i = 1; // Deal with unused variable warnings: (void)i; - RealType v1(0.5), v2(0.5), v3(0.5); + auto v1(static_cast(0.5)); + auto v2(static_cast(0.5)); + auto v3(static_cast(0.5)); boost::detail::dummy_constructor dc; boost::output_iterator_archetype oi(dc); #ifdef TEST_GROUP_4 From 2b1d5b613a7a366524c54db2e3fc65c44faebd1b Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 2 May 2023 13:17:56 +0200 Subject: [PATCH 06/53] Cast assignment of promoted type --- include/boost/math/special_functions/bessel.hpp | 4 ++-- include/boost/math/special_functions/binomial.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/math/special_functions/bessel.hpp b/include/boost/math/special_functions/bessel.hpp index 35ad350262..2f9d6a1c42 100644 --- a/include/boost/math/special_functions/bessel.hpp +++ b/include/boost/math/special_functions/bessel.hpp @@ -680,7 +680,7 @@ inline OutputIterator cyl_bessel_j_zero(T v, for(int i = 0; i < static_cast(number_of_zeros); ++i) { - *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); + *out_it = static_cast(boost::math::cyl_bessel_j_zero(v, start_index + i, pol)); ++out_it; } return out_it; @@ -741,7 +741,7 @@ inline OutputIterator cyl_neumann_zero(T v, for(int i = 0; i < static_cast(number_of_zeros); ++i) { - *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); + *out_it = static_cast(boost::math::cyl_neumann_zero(v, start_index + i, pol)); ++out_it; } return out_it; diff --git a/include/boost/math/special_functions/binomial.hpp b/include/boost/math/special_functions/binomial.hpp index f76b48cc13..20bcf3e8c6 100644 --- a/include/boost/math/special_functions/binomial.hpp +++ b/include/boost/math/special_functions/binomial.hpp @@ -46,9 +46,9 @@ T binomial_coefficient(unsigned n, unsigned k, const Policy& pol) { // Use the beta function: if(k < n - k) - result = k * beta(static_cast(k), static_cast(n-k+1), pol); + result = static_cast(k * beta(static_cast(k), static_cast(n-k+1), pol)); else - result = (n - k) * beta(static_cast(k+1), static_cast(n-k), pol); + result = static_cast((n - k) * beta(static_cast(k+1), static_cast(n-k), pol)); if(result == 0) return policies::raise_overflow_error(function, nullptr, pol); result = 1 / result; From be37704674fa6926f956c3fad69e6b00b82f7274 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 2 May 2023 13:50:31 +0200 Subject: [PATCH 07/53] Explicit casting of promoted types --- .../math/special_functions/bessel_prime.hpp | 6 +- .../math/special_functions/chebyshev.hpp | 2 +- .../math/special_functions/factorials.hpp | 10 +- .../boost/math/special_functions/gamma.hpp | 54 +- .../boost/math/special_functions/hermite.hpp | 2 +- .../boost/math/special_functions/laguerre.hpp | 2 +- .../boost/math/special_functions/legendre.hpp | 6 +- .../boost/math/special_functions/math_fwd.hpp | 764 +++++++++--------- 8 files changed, 424 insertions(+), 422 deletions(-) diff --git a/include/boost/math/special_functions/bessel_prime.hpp b/include/boost/math/special_functions/bessel_prime.hpp index 9615d40644..6d8b466f2a 100644 --- a/include/boost/math/special_functions/bessel_prime.hpp +++ b/include/boost/math/special_functions/bessel_prime.hpp @@ -38,9 +38,9 @@ inline T cyl_bessel_j_prime_imp(T v, T x, const Policy& pol) if (x == 0) { if (v == 1) - return 0.5; + return static_cast(0.5); else if (v == -1) - return -0.5; + return static_cast(-0.5); else if (floor(v) == v || v > 1) return 0; else return boost::math::policies::raise_domain_error( @@ -126,7 +126,7 @@ inline T cyl_bessel_i_prime_imp(T v, T x, const Policy& pol) if (x == 0) { if (v == 1 || v == -1) - return 0.5; + return static_cast(0.5); else if (floor(v) == v || v > 1) return 0; else return boost::math::policies::raise_domain_error( diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index d69fd9c50e..dc414a37cc 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -84,7 +84,7 @@ inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) while(l < n) { std::swap(T0, T1); - T1 = boost::math::chebyshev_next(x, T0, T1); + T1 = static_cast(boost::math::chebyshev_next(x, T0, T1)); ++l; } return T1; diff --git a/include/boost/math/special_functions/factorials.hpp b/include/boost/math/special_functions/factorials.hpp index 02cca91a80..7229635cb9 100644 --- a/include/boost/math/special_functions/factorials.hpp +++ b/include/boost/math/special_functions/factorials.hpp @@ -145,13 +145,13 @@ T rising_factorial_imp(T x, int n, const Policy& pol) if(x == 0) { if(n < 0) - return -boost::math::tgamma_delta_ratio(x + 1, static_cast(-n), pol); + return static_cast(-boost::math::tgamma_delta_ratio(x + 1, static_cast(-n), pol)); else return 0; } if((x < 1) && (x + n < 0)) { - T val = boost::math::tgamma_delta_ratio(1 - x, static_cast(-n), pol); + const auto val = static_cast(boost::math::tgamma_delta_ratio(1 - x, static_cast(-n), pol)); return (n & 1) ? T(-val) : val; } // @@ -159,7 +159,7 @@ T rising_factorial_imp(T x, int n, const Policy& pol) // tgamma_delta_ratio is already optimised for that // use case: // - return 1 / boost::math::tgamma_delta_ratio(x, static_cast(n), pol); + return 1 / static_cast(boost::math::tgamma_delta_ratio(x, static_cast(n), pol)); } template @@ -206,7 +206,7 @@ inline T falling_factorial_imp(T x, unsigned n, const Policy& pol) unsigned n2 = itrunc((T)floor(xp1), pol); if(n2 == xp1) return 0; - T result = boost::math::tgamma_delta_ratio(xp1, -static_cast(n2), pol); + auto result = static_cast(boost::math::tgamma_delta_ratio(xp1, -static_cast(n2), pol)); x -= n2; result *= x; ++n2; @@ -221,7 +221,7 @@ inline T falling_factorial_imp(T x, unsigned n, const Policy& pol) // because tgamma_delta_ratio is already optimised // for that use case: // - return boost::math::tgamma_delta_ratio(x + 1, -static_cast(n), pol); + return static_cast(boost::math::tgamma_delta_ratio(x + 1, -static_cast(n), pol)); } } // namespace detail diff --git a/include/boost/math/special_functions/gamma.hpp b/include/boost/math/special_functions/gamma.hpp index 68afe66e30..b84389a340 100644 --- a/include/boost/math/special_functions/gamma.hpp +++ b/include/boost/math/special_functions/gamma.hpp @@ -1917,11 +1917,11 @@ template const typename lgamma_initializer::init lgamma_initializer::initializer; template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma(T1 a, T2 z, const Policy&, const std::false_type) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; // typedef typename lanczos::lanczos::type evaluation_type; typedef typename policies::normalise< @@ -1940,7 +1940,7 @@ inline typename tools::promote_args::type } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma(T1 a, T2 z, const std::false_type& tag) { return tgamma(a, z, policies::policy<>(), tag); @@ -2026,31 +2026,33 @@ inline typename tools::promote_args::type // Full upper incomplete gamma: // template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma(T1 a, T2 z) { // // Type T2 could be a policy object, or a value, select the // right overload based on T2: // - typedef typename policies::is_policy::type maybe_policy; - return detail::tgamma(a, z, maybe_policy()); + using maybe_policy = typename policies::is_policy::type; + using result_type = tools::promote_args_t; + return static_cast(detail::tgamma(a, z, maybe_policy())); } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma(T1 a, T2 z, const Policy& pol) { - return detail::tgamma(a, z, pol, std::false_type()); + using result_type = tools::promote_args_t; + return static_cast(detail::tgamma(a, z, pol, std::false_type())); } // // Full lower incomplete gamma: // template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_lower(T1 a, T2 z, const Policy&) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; // typedef typename lanczos::lanczos::type evaluation_type; typedef typename policies::normalise< @@ -2068,7 +2070,7 @@ inline typename tools::promote_args::type forwarding_policy(), static_cast(nullptr)), "tgamma_lower<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_lower(T1 a, T2 z) { return tgamma_lower(a, z, policies::policy<>()); @@ -2077,11 +2079,11 @@ inline typename tools::promote_args::type // Regularised upper incomplete gamma: // template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_q(T1 a, T2 z, const Policy& /* pol */) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; // typedef typename lanczos::lanczos::type evaluation_type; typedef typename policies::normalise< @@ -2099,7 +2101,7 @@ inline typename tools::promote_args::type forwarding_policy(), static_cast(nullptr)), "gamma_q<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_q(T1 a, T2 z) { return gamma_q(a, z, policies::policy<>()); @@ -2108,11 +2110,11 @@ inline typename tools::promote_args::type // Regularised lower incomplete gamma: // template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_p(T1 a, T2 z, const Policy&) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; // typedef typename lanczos::lanczos::type evaluation_type; typedef typename policies::normalise< @@ -2130,7 +2132,7 @@ inline typename tools::promote_args::type forwarding_policy(), static_cast(nullptr)), "gamma_p<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_p(T1 a, T2 z) { return gamma_p(a, z, policies::policy<>()); @@ -2138,11 +2140,11 @@ inline typename tools::promote_args::type // ratios of gamma functions: template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; typedef typename policies::normalise< Policy, @@ -2154,16 +2156,16 @@ inline typename tools::promote_args::type return policies::checked_narrowing_cast(detail::tgamma_delta_ratio_imp(static_cast(z), static_cast(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta) { return tgamma_delta_ratio(z, delta, policies::policy<>()); } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_ratio(T1 a, T2 b, const Policy&) { - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; typedef typename policies::normalise< Policy, @@ -2175,18 +2177,18 @@ inline typename tools::promote_args::type return policies::checked_narrowing_cast(detail::tgamma_ratio_imp(static_cast(a), static_cast(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t tgamma_ratio(T1 a, T2 b) { return tgamma_ratio(a, b, policies::policy<>()); } template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_p_derivative(T1 a, T2 x, const Policy&) { BOOST_FPU_EXCEPTION_GUARD - typedef typename tools::promote_args::type result_type; + typedef tools::promote_args_t result_type; typedef typename policies::evaluation::type value_type; typedef typename policies::normalise< Policy, @@ -2198,7 +2200,7 @@ inline typename tools::promote_args::type return policies::checked_narrowing_cast(detail::gamma_p_derivative_imp(static_cast(a), static_cast(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)"); } template -inline typename tools::promote_args::type +inline tools::promote_args_t gamma_p_derivative(T1 a, T2 x) { return gamma_p_derivative(a, x, policies::policy<>()); diff --git a/include/boost/math/special_functions/hermite.hpp b/include/boost/math/special_functions/hermite.hpp index dcc352f55f..778954be98 100644 --- a/include/boost/math/special_functions/hermite.hpp +++ b/include/boost/math/special_functions/hermite.hpp @@ -43,7 +43,7 @@ T hermite_imp(unsigned n, T x) while(c < n) { std::swap(p0, p1); - p1 = hermite_next(c, x, p0, p1); + p1 = static_cast(hermite_next(c, x, p0, p1)); ++c; } return p1; diff --git a/include/boost/math/special_functions/laguerre.hpp b/include/boost/math/special_functions/laguerre.hpp index cd9aa31c46..d747274536 100644 --- a/include/boost/math/special_functions/laguerre.hpp +++ b/include/boost/math/special_functions/laguerre.hpp @@ -105,7 +105,7 @@ T laguerre_imp(unsigned n, unsigned m, T x, const Policy& pol) while(c < n) { std::swap(p0, p1); - p1 = laguerre_next(c, m, x, p0, p1); + p1 = static_cast(laguerre_next(c, m, x, p0, p1)); ++c; } return p1; diff --git a/include/boost/math/special_functions/legendre.hpp b/include/boost/math/special_functions/legendre.hpp index e8e90f580b..23f552dc91 100644 --- a/include/boost/math/special_functions/legendre.hpp +++ b/include/boost/math/special_functions/legendre.hpp @@ -66,7 +66,7 @@ T legendre_imp(unsigned l, T x, const Policy& pol, bool second = false) while(n < l) { std::swap(p0, p1); - p1 = boost::math::legendre_next(n, x, p0, p1); + p1 = static_cast(boost::math::legendre_next(n, x, p0, p1)); ++n; } return p1; @@ -115,7 +115,7 @@ T legendre_p_prime_imp(unsigned l, T x, const Policy& pol, T* Pn while(n < l - 1) { std::swap(p0, p1); - p1 = boost::math::legendre_next(n, x, p0, p1); + p1 = static_cast(boost::math::legendre_next(n, x, p0, p1)); ++n; if (odd) { @@ -131,7 +131,7 @@ T legendre_p_prime_imp(unsigned l, T x, const Policy& pol, T* Pn if (Pn) { std::swap(p0, p1); - *Pn = boost::math::legendre_next(n, x, p0, p1); + *Pn = static_cast(boost::math::legendre_next(n, x, p0, p1)); } return p_prime; } diff --git a/include/boost/math/special_functions/math_fwd.hpp b/include/boost/math/special_functions/math_fwd.hpp index 6f9d739e1e..7b99651402 100644 --- a/include/boost/math/special_functions/math_fwd.hpp +++ b/include/boost/math/special_functions/math_fwd.hpp @@ -39,111 +39,111 @@ namespace boost // Beta functions. template - typename tools::promote_args::type + tools::promote_args_t beta(RT1 a, RT2 b); // Beta function (2 arguments). template - typename tools::promote_args::type + tools::promote_args_t beta(RT1 a, RT2 b, A x); // Beta function (3 arguments). template - typename tools::promote_args::type + tools::promote_args_t beta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Beta function (3 arguments). template - typename tools::promote_args::type + tools::promote_args_t betac(RT1 a, RT2 b, RT3 x); template - typename tools::promote_args::type + tools::promote_args_t betac(RT1 a, RT2 b, RT3 x, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ibeta(RT1 a, RT2 b, RT3 x); // Incomplete beta function. template - typename tools::promote_args::type + tools::promote_args_t ibeta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta function. template - typename tools::promote_args::type + tools::promote_args_t ibetac(RT1 a, RT2 b, RT3 x); // Incomplete beta complement function. template - typename tools::promote_args::type + tools::promote_args_t ibetac(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta complement function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_inv(T1 a, T2 b, T3 p, T4* py); template - typename tools::promote_args::type + tools::promote_args_t ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ibeta_inv(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_inv(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_inva(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_inva(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_invb(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_invb(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_inv(T1 a, T2 b, T3 q, T4* py); template - typename tools::promote_args::type + tools::promote_args_t ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ibetac_inv(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_inva(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_inva(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_invb(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibetac_invb(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. template - typename tools::promote_args::type + tools::promote_args_t ibeta_derivative(RT1 a, RT2 b, RT3 x); // derivative of incomplete beta template - typename tools::promote_args::type + tools::promote_args_t ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy& pol); // derivative of incomplete beta // Binomial: @@ -154,35 +154,35 @@ namespace boost // erf & erfc error functions. template // Error function. - typename tools::promote_args::type erf(RT z); + tools::promote_args_t erf(RT z); template // Error function. - typename tools::promote_args::type erf(RT z, const Policy&); + tools::promote_args_t erf(RT z, const Policy&); template // Error function complement. - typename tools::promote_args::type erfc(RT z); + tools::promote_args_t erfc(RT z); template // Error function complement. - typename tools::promote_args::type erfc(RT z, const Policy&); + tools::promote_args_t erfc(RT z, const Policy&); template // Error function inverse. - typename tools::promote_args::type erf_inv(RT z); + tools::promote_args_t erf_inv(RT z); template // Error function inverse. - typename tools::promote_args::type erf_inv(RT z, const Policy& pol); + tools::promote_args_t erf_inv(RT z, const Policy& pol); template // Error function complement inverse. - typename tools::promote_args::type erfc_inv(RT z); + tools::promote_args_t erfc_inv(RT z); template // Error function complement inverse. - typename tools::promote_args::type erfc_inv(RT z, const Policy& pol); + tools::promote_args_t erfc_inv(RT z, const Policy& pol); // Polynomials: template - typename tools::promote_args::type + tools::promote_args_t legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1); template - typename tools::promote_args::type + tools::promote_args_t legendre_p(int l, T x); template - typename tools::promote_args::type + tools::promote_args_t legendre_p_prime(int l, T x); @@ -193,46 +193,46 @@ namespace boost inline std::vector legendre_p_zeros(int l); template - typename std::enable_if::value, typename tools::promote_args::type>::type + typename std::enable_if::value, tools::promote_args_t>::type legendre_p(int l, T x, const Policy& pol); template - inline typename std::enable_if::value, typename tools::promote_args::type>::type + inline typename std::enable_if::value, tools::promote_args_t>::type legendre_p_prime(int l, T x, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t legendre_q(unsigned l, T x); template - typename std::enable_if::value, typename tools::promote_args::type>::type + typename std::enable_if::value, tools::promote_args_t>::type legendre_q(unsigned l, T x, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1); template - typename tools::promote_args::type + tools::promote_args_t legendre_p(int l, int m, T x); template - typename tools::promote_args::type + tools::promote_args_t legendre_p(int l, int m, T x, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1); template - typename tools::promote_args::type + tools::promote_args_t laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1); template - typename tools::promote_args::type + tools::promote_args_t laguerre(unsigned n, T x); template - typename tools::promote_args::type + tools::promote_args_t laguerre(unsigned n, unsigned m, T x, const Policy& pol); template @@ -250,144 +250,144 @@ namespace boost laguerre(unsigned n, T1 m, T2 x); template - typename tools::promote_args::type + tools::promote_args_t hermite(unsigned n, T x); template - typename tools::promote_args::type + tools::promote_args_t hermite(unsigned n, T x, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1); template - typename tools::promote_args::type chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1); + tools::promote_args_t chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1); template - typename tools::promote_args::type + tools::promote_args_t chebyshev_t(unsigned n, Real const & x, const Policy&); template - typename tools::promote_args::type chebyshev_t(unsigned n, Real const & x); + tools::promote_args_t chebyshev_t(unsigned n, Real const & x); template - typename tools::promote_args::type + tools::promote_args_t chebyshev_u(unsigned n, Real const & x, const Policy&); template - typename tools::promote_args::type chebyshev_u(unsigned n, Real const & x); + tools::promote_args_t chebyshev_u(unsigned n, Real const & x); template - typename tools::promote_args::type + tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x, const Policy&); template - typename tools::promote_args::type chebyshev_t_prime(unsigned n, Real const & x); + tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x); template Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const T2& x); template - std::complex::type> + std::complex> spherical_harmonic(unsigned n, int m, T1 theta, T2 phi); template - std::complex::type> + std::complex> spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi); template - typename tools::promote_args::type + tools::promote_args_t spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi); template - typename tools::promote_args::type + tools::promote_args_t spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); // Elliptic integrals: template - typename tools::promote_args::type + tools::promote_args_t ellint_rf(T1 x, T2 y, T3 z); template - typename tools::promote_args::type + tools::promote_args_t ellint_rf(T1 x, T2 y, T3 z, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ellint_rd(T1 x, T2 y, T3 z); template - typename tools::promote_args::type + tools::promote_args_t ellint_rd(T1 x, T2 y, T3 z, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ellint_rc(T1 x, T2 y); template - typename tools::promote_args::type + tools::promote_args_t ellint_rc(T1 x, T2 y, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ellint_rj(T1 x, T2 y, T3 z, T4 p); template - typename tools::promote_args::type + tools::promote_args_t ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol); template - typename tools::promote_args::type + tools::promote_args_t ellint_rg(T1 x, T2 y, T3 z); template - typename tools::promote_args::type + tools::promote_args_t ellint_rg(T1 x, T2 y, T3 z, const Policy& pol); template - typename tools::promote_args::type ellint_2(T k); + tools::promote_args_t ellint_2(T k); template - typename tools::promote_args::type ellint_2(T1 k, T2 phi); + tools::promote_args_t ellint_2(T1 k, T2 phi); template - typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol); + tools::promote_args_t ellint_2(T1 k, T2 phi, const Policy& pol); template - typename tools::promote_args::type ellint_1(T k); + tools::promote_args_t ellint_1(T k); template - typename tools::promote_args::type ellint_1(T1 k, T2 phi); + tools::promote_args_t ellint_1(T1 k, T2 phi); template - typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol); + tools::promote_args_t ellint_1(T1 k, T2 phi, const Policy& pol); template - typename tools::promote_args::type ellint_d(T k); + tools::promote_args_t ellint_d(T k); template - typename tools::promote_args::type ellint_d(T1 k, T2 phi); + tools::promote_args_t ellint_d(T1 k, T2 phi); template - typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol); + tools::promote_args_t ellint_d(T1 k, T2 phi, const Policy& pol); template - typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi); + tools::promote_args_t jacobi_zeta(T1 k, T2 phi); template - typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi, const Policy& pol); + tools::promote_args_t jacobi_zeta(T1 k, T2 phi, const Policy& pol); template - typename tools::promote_args::type heuman_lambda(T1 k, T2 phi); + tools::promote_args_t heuman_lambda(T1 k, T2 phi); template - typename tools::promote_args::type heuman_lambda(T1 k, T2 phi, const Policy& pol); + tools::promote_args_t heuman_lambda(T1 k, T2 phi, const Policy& pol); namespace detail{ @@ -396,8 +396,8 @@ namespace boost { using type = typename std::conditional< policies::is_policy::value, - typename tools::promote_args::type, - typename tools::promote_args::type + tools::promote_args_t, + tools::promote_args_t >::type; }; @@ -408,10 +408,10 @@ namespace boost typename detail::ellint_3_result::type ellint_3(T1 k, T2 v, T3 phi); template - typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const Policy& pol); + tools::promote_args_t ellint_3(T1 k, T2 v, T3 phi, const Policy& pol); template - typename tools::promote_args::type ellint_3(T1 k, T2 v); + tools::promote_args_t ellint_3(T1 k, T2 v); // Factorial functions. // Note: not for integral types, at present. @@ -429,211 +429,211 @@ namespace boost RT double_factorial(unsigned i, const Policy& pol); template - typename tools::promote_args::type falling_factorial(RT x, unsigned n); + tools::promote_args_t falling_factorial(RT x, unsigned n); template - typename tools::promote_args::type falling_factorial(RT x, unsigned n, const Policy& pol); + tools::promote_args_t falling_factorial(RT x, unsigned n, const Policy& pol); template - typename tools::promote_args::type rising_factorial(RT x, int n); + tools::promote_args_t rising_factorial(RT x, int n); template - typename tools::promote_args::type rising_factorial(RT x, int n, const Policy& pol); + tools::promote_args_t rising_factorial(RT x, int n, const Policy& pol); // Gamma functions. template - typename tools::promote_args::type tgamma(RT z); + tools::promote_args_t tgamma(RT z); template - typename tools::promote_args::type tgamma1pm1(RT z); + tools::promote_args_t tgamma1pm1(RT z); template - typename tools::promote_args::type tgamma1pm1(RT z, const Policy& pol); + tools::promote_args_t tgamma1pm1(RT z, const Policy& pol); template - typename tools::promote_args::type tgamma(RT1 a, RT2 z); + tools::promote_args_t tgamma(RT1 a, RT2 z); template - typename tools::promote_args::type tgamma(RT1 a, RT2 z, const Policy& pol); + tools::promote_args_t tgamma(RT1 a, RT2 z, const Policy& pol); template - typename tools::promote_args::type lgamma(RT z, int* sign); + tools::promote_args_t lgamma(RT z, int* sign); template - typename tools::promote_args::type lgamma(RT z, int* sign, const Policy& pol); + tools::promote_args_t lgamma(RT z, int* sign, const Policy& pol); template - typename tools::promote_args::type lgamma(RT x); + tools::promote_args_t lgamma(RT x); template - typename tools::promote_args::type lgamma(RT x, const Policy& pol); + tools::promote_args_t lgamma(RT x, const Policy& pol); template - typename tools::promote_args::type tgamma_lower(RT1 a, RT2 z); + tools::promote_args_t tgamma_lower(RT1 a, RT2 z); template - typename tools::promote_args::type tgamma_lower(RT1 a, RT2 z, const Policy&); + tools::promote_args_t tgamma_lower(RT1 a, RT2 z, const Policy&); template - typename tools::promote_args::type gamma_q(RT1 a, RT2 z); + tools::promote_args_t gamma_q(RT1 a, RT2 z); template - typename tools::promote_args::type gamma_q(RT1 a, RT2 z, const Policy&); + tools::promote_args_t gamma_q(RT1 a, RT2 z, const Policy&); template - typename tools::promote_args::type gamma_p(RT1 a, RT2 z); + tools::promote_args_t gamma_p(RT1 a, RT2 z); template - typename tools::promote_args::type gamma_p(RT1 a, RT2 z, const Policy&); + tools::promote_args_t gamma_p(RT1 a, RT2 z, const Policy&); template - typename tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta); + tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta); template - typename tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta, const Policy&); + tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta, const Policy&); template - typename tools::promote_args::type tgamma_ratio(T1 a, T2 b); + tools::promote_args_t tgamma_ratio(T1 a, T2 b); template - typename tools::promote_args::type tgamma_ratio(T1 a, T2 b, const Policy&); + tools::promote_args_t tgamma_ratio(T1 a, T2 b, const Policy&); template - typename tools::promote_args::type gamma_p_derivative(T1 a, T2 x); + tools::promote_args_t gamma_p_derivative(T1 a, T2 x); template - typename tools::promote_args::type gamma_p_derivative(T1 a, T2 x, const Policy&); + tools::promote_args_t gamma_p_derivative(T1 a, T2 x, const Policy&); // gamma inverse. template - typename tools::promote_args::type gamma_p_inv(T1 a, T2 p); + tools::promote_args_t gamma_p_inv(T1 a, T2 p); template - typename tools::promote_args::type gamma_p_inva(T1 a, T2 p, const Policy&); + tools::promote_args_t gamma_p_inva(T1 a, T2 p, const Policy&); template - typename tools::promote_args::type gamma_p_inva(T1 a, T2 p); + tools::promote_args_t gamma_p_inva(T1 a, T2 p); template - typename tools::promote_args::type gamma_p_inv(T1 a, T2 p, const Policy&); + tools::promote_args_t gamma_p_inv(T1 a, T2 p, const Policy&); template - typename tools::promote_args::type gamma_q_inv(T1 a, T2 q); + tools::promote_args_t gamma_q_inv(T1 a, T2 q); template - typename tools::promote_args::type gamma_q_inv(T1 a, T2 q, const Policy&); + tools::promote_args_t gamma_q_inv(T1 a, T2 q, const Policy&); template - typename tools::promote_args::type gamma_q_inva(T1 a, T2 q); + tools::promote_args_t gamma_q_inva(T1 a, T2 q); template - typename tools::promote_args::type gamma_q_inva(T1 a, T2 q, const Policy&); + tools::promote_args_t gamma_q_inva(T1 a, T2 q, const Policy&); // digamma: template - typename tools::promote_args::type digamma(T x); + tools::promote_args_t digamma(T x); template - typename tools::promote_args::type digamma(T x, const Policy&); + tools::promote_args_t digamma(T x, const Policy&); // trigamma: template - typename tools::promote_args::type trigamma(T x); + tools::promote_args_t trigamma(T x); template - typename tools::promote_args::type trigamma(T x, const Policy&); + tools::promote_args_t trigamma(T x, const Policy&); // polygamma: template - typename tools::promote_args::type polygamma(int n, T x); + tools::promote_args_t polygamma(int n, T x); template - typename tools::promote_args::type polygamma(int n, T x, const Policy&); + tools::promote_args_t polygamma(int n, T x, const Policy&); // Hypotenuse function sqrt(x ^ 2 + y ^ 2). template - typename tools::promote_args::type + tools::promote_args_t hypot(T1 x, T2 y); template - typename tools::promote_args::type + tools::promote_args_t hypot(T1 x, T2 y, const Policy&); // cbrt - cube root. template - typename tools::promote_args::type cbrt(RT z); + tools::promote_args_t cbrt(RT z); template - typename tools::promote_args::type cbrt(RT z, const Policy&); + tools::promote_args_t cbrt(RT z, const Policy&); // log1p is log(x + 1) template - typename tools::promote_args::type log1p(T); + tools::promote_args_t log1p(T); template - typename tools::promote_args::type log1p(T, const Policy&); + tools::promote_args_t log1p(T, const Policy&); // log1pmx is log(x + 1) - x template - typename tools::promote_args::type log1pmx(T); + tools::promote_args_t log1pmx(T); template - typename tools::promote_args::type log1pmx(T, const Policy&); + tools::promote_args_t log1pmx(T, const Policy&); // Exp (x) minus 1 functions. template - typename tools::promote_args::type expm1(T); + tools::promote_args_t expm1(T); template - typename tools::promote_args::type expm1(T, const Policy&); + tools::promote_args_t expm1(T, const Policy&); // Power - 1 template - typename tools::promote_args::type + tools::promote_args_t powm1(const T1 a, const T2 z); template - typename tools::promote_args::type + tools::promote_args_t powm1(const T1 a, const T2 z, const Policy&); // sqrt(1+x) - 1 template - typename tools::promote_args::type sqrt1pm1(const T& val); + tools::promote_args_t sqrt1pm1(const T& val); template - typename tools::promote_args::type sqrt1pm1(const T& val, const Policy&); + tools::promote_args_t sqrt1pm1(const T& val, const Policy&); // sinus cardinals: template - typename tools::promote_args::type sinc_pi(T x); + tools::promote_args_t sinc_pi(T x); template - typename tools::promote_args::type sinc_pi(T x, const Policy&); + tools::promote_args_t sinc_pi(T x, const Policy&); template - typename tools::promote_args::type sinhc_pi(T x); + tools::promote_args_t sinhc_pi(T x); template - typename tools::promote_args::type sinhc_pi(T x, const Policy&); + tools::promote_args_t sinhc_pi(T x, const Policy&); // inverse hyperbolics: template - typename tools::promote_args::type asinh(T x); + tools::promote_args_t asinh(T x); template - typename tools::promote_args::type asinh(T x, const Policy&); + tools::promote_args_t asinh(T x, const Policy&); template - typename tools::promote_args::type acosh(T x); + tools::promote_args_t acosh(T x); template - typename tools::promote_args::type acosh(T x, const Policy&); + tools::promote_args_t acosh(T x, const Policy&); template - typename tools::promote_args::type atanh(T x); + tools::promote_args_t atanh(T x); template - typename tools::promote_args::type atanh(T x, const Policy&); + tools::promote_args_t atanh(T x, const Policy&); namespace detail{ @@ -647,7 +647,7 @@ namespace boost using result_type = typename std::conditional< std::is_integral::value, typename tools::promote_args::type, - typename tools::promote_args::type + tools::promote_args_t >::type; typedef typename policies::precision::type precision_type; @@ -798,28 +798,28 @@ namespace boost std::complex >::result_type> sph_hankel_2(T1 v, T2 x); template - typename tools::promote_args::type airy_ai(T x, const Policy&); + tools::promote_args_t airy_ai(T x, const Policy&); template - typename tools::promote_args::type airy_ai(T x); + tools::promote_args_t airy_ai(T x); template - typename tools::promote_args::type airy_bi(T x, const Policy&); + tools::promote_args_t airy_bi(T x, const Policy&); template - typename tools::promote_args::type airy_bi(T x); + tools::promote_args_t airy_bi(T x); template - typename tools::promote_args::type airy_ai_prime(T x, const Policy&); + tools::promote_args_t airy_ai_prime(T x, const Policy&); template - typename tools::promote_args::type airy_ai_prime(T x); + tools::promote_args_t airy_ai_prime(T x); template - typename tools::promote_args::type airy_bi_prime(T x, const Policy&); + tools::promote_args_t airy_bi_prime(T x, const Policy&); template - typename tools::promote_args::type airy_bi_prime(T x); + tools::promote_args_t airy_bi_prime(T x); template T airy_ai_zero(int m); @@ -856,16 +856,16 @@ namespace boost const Policy&); template - typename tools::promote_args::type sin_pi(T x, const Policy&); + tools::promote_args_t sin_pi(T x, const Policy&); template - typename tools::promote_args::type sin_pi(T x); + tools::promote_args_t sin_pi(T x); template - typename tools::promote_args::type cos_pi(T x, const Policy&); + tools::promote_args_t cos_pi(T x, const Policy&); template - typename tools::promote_args::type cos_pi(T x); + tools::promote_args_t cos_pi(T x); template int fpclassify BOOST_NO_MACRO_EXPAND(T t); @@ -902,7 +902,7 @@ namespace boost { typedef typename std::conditional< policies::is_policy::value, - typename tools::promote_args::type, + tools::promote_args_t, typename tools::promote_args::type >::type type; }; @@ -910,219 +910,219 @@ namespace boost } // namespace detail template - typename tools::promote_args::type expint(unsigned n, T z, const Policy&); + tools::promote_args_t expint(unsigned n, T z, const Policy&); template typename detail::expint_result::type expint(T const z, U const u); template - typename tools::promote_args::type expint(T z); + tools::promote_args_t expint(T z); // Zeta: template - typename tools::promote_args::type zeta(T s, const Policy&); + tools::promote_args_t zeta(T s, const Policy&); // Owen's T function: template - typename tools::promote_args::type owens_t(T1 h, T2 a, const Policy& pol); + tools::promote_args_t owens_t(T1 h, T2 a, const Policy& pol); template - typename tools::promote_args::type owens_t(T1 h, T2 a); + tools::promote_args_t owens_t(T1 h, T2 a); // Jacobi Functions: template - typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&); + tools::promote_args_t jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&); template - typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn = 0, V* pdn = 0); + tools::promote_args_t jacobi_elliptic(T k, U theta, V* pcn = 0, V* pdn = 0); template - typename tools::promote_args::type jacobi_sn(U k, T theta, const Policy& pol); + tools::promote_args_t jacobi_sn(U k, T theta, const Policy& pol); template - typename tools::promote_args::type jacobi_sn(U k, T theta); + tools::promote_args_t jacobi_sn(U k, T theta); template - typename tools::promote_args::type jacobi_cn(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_cn(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_cn(T k, U theta); + tools::promote_args_t jacobi_cn(T k, U theta); template - typename tools::promote_args::type jacobi_dn(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_dn(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_dn(T k, U theta); + tools::promote_args_t jacobi_dn(T k, U theta); template - typename tools::promote_args::type jacobi_cd(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_cd(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_cd(T k, U theta); + tools::promote_args_t jacobi_cd(T k, U theta); template - typename tools::promote_args::type jacobi_dc(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_dc(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_dc(T k, U theta); + tools::promote_args_t jacobi_dc(T k, U theta); template - typename tools::promote_args::type jacobi_ns(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_ns(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_ns(T k, U theta); + tools::promote_args_t jacobi_ns(T k, U theta); template - typename tools::promote_args::type jacobi_sd(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_sd(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_sd(T k, U theta); + tools::promote_args_t jacobi_sd(T k, U theta); template - typename tools::promote_args::type jacobi_ds(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_ds(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_ds(T k, U theta); + tools::promote_args_t jacobi_ds(T k, U theta); template - typename tools::promote_args::type jacobi_nc(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_nc(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_nc(T k, U theta); + tools::promote_args_t jacobi_nc(T k, U theta); template - typename tools::promote_args::type jacobi_nd(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_nd(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_nd(T k, U theta); + tools::promote_args_t jacobi_nd(T k, U theta); template - typename tools::promote_args::type jacobi_sc(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_sc(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_sc(T k, U theta); + tools::promote_args_t jacobi_sc(T k, U theta); template - typename tools::promote_args::type jacobi_cs(T k, U theta, const Policy& pol); + tools::promote_args_t jacobi_cs(T k, U theta, const Policy& pol); template - typename tools::promote_args::type jacobi_cs(T k, U theta); + tools::promote_args_t jacobi_cs(T k, U theta); // Jacobi Theta Functions: template - typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta1(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta1(T z, U q); + tools::promote_args_t jacobi_theta1(T z, U q); template - typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta2(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta2(T z, U q); + tools::promote_args_t jacobi_theta2(T z, U q); template - typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta3(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta3(T z, U q); + tools::promote_args_t jacobi_theta3(T z, U q); template - typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta4(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta4(T z, U q); + tools::promote_args_t jacobi_theta4(T z, U q); template - typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta1tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta1tau(T z, U tau); + tools::promote_args_t jacobi_theta1tau(T z, U tau); template - typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta2tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta2tau(T z, U tau); + tools::promote_args_t jacobi_theta2tau(T z, U tau); template - typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta3tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta3tau(T z, U tau); + tools::promote_args_t jacobi_theta3tau(T z, U tau); template - typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta4tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta4tau(T z, U tau); + tools::promote_args_t jacobi_theta4tau(T z, U tau); template - typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta3m1(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta3m1(T z, U q); + tools::promote_args_t jacobi_theta3m1(T z, U q); template - typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy& pol); + tools::promote_args_t jacobi_theta4m1(T z, U q, const Policy& pol); template - typename tools::promote_args::type jacobi_theta4m1(T z, U q); + tools::promote_args_t jacobi_theta4m1(T z, U q); template - typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta3m1tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau); + tools::promote_args_t jacobi_theta3m1tau(T z, U tau); template - typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy& pol); + tools::promote_args_t jacobi_theta4m1tau(T z, U tau, const Policy& pol); template - typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau); + tools::promote_args_t jacobi_theta4m1tau(T z, U tau); template - typename tools::promote_args::type zeta(T s); + tools::promote_args_t zeta(T s); // pow: template - BOOST_CXX14_CONSTEXPR typename tools::promote_args::type pow(T base, const Policy& policy); + BOOST_CXX14_CONSTEXPR tools::promote_args_t pow(T base, const Policy& policy); template - BOOST_CXX14_CONSTEXPR typename tools::promote_args::type pow(T base); + BOOST_CXX14_CONSTEXPR tools::promote_args_t pow(T base); // next: template - typename tools::promote_args::type nextafter(const T&, const U&, const Policy&); + tools::promote_args_t nextafter(const T&, const U&, const Policy&); template - typename tools::promote_args::type nextafter(const T&, const U&); + tools::promote_args_t nextafter(const T&, const U&); template - typename tools::promote_args::type float_next(const T&, const Policy&); + tools::promote_args_t float_next(const T&, const Policy&); template - typename tools::promote_args::type float_next(const T&); + tools::promote_args_t float_next(const T&); template - typename tools::promote_args::type float_prior(const T&, const Policy&); + tools::promote_args_t float_prior(const T&, const Policy&); template - typename tools::promote_args::type float_prior(const T&); + tools::promote_args_t float_prior(const T&); template - typename tools::promote_args::type float_distance(const T&, const U&, const Policy&); + tools::promote_args_t float_distance(const T&, const U&, const Policy&); template - typename tools::promote_args::type float_distance(const T&, const U&); + tools::promote_args_t float_distance(const T&, const U&); template - typename tools::promote_args::type float_advance(T val, int distance, const Policy& pol); + tools::promote_args_t float_advance(T val, int distance, const Policy& pol); template - typename tools::promote_args::type float_advance(const T& val, int distance); + tools::promote_args_t float_advance(const T& val, int distance); template - typename tools::promote_args::type ulp(const T& val, const Policy& pol); + tools::promote_args_t ulp(const T& val, const Policy& pol); template - typename tools::promote_args::type ulp(const T& val); + tools::promote_args_t ulp(const T& val); template - typename tools::promote_args::type relative_difference(const T&, const U&); + tools::promote_args_t relative_difference(const T&, const U&); template - typename tools::promote_args::type epsilon_difference(const T&, const U&); + tools::promote_args_t epsilon_difference(const T&, const U&); template BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n); @@ -1155,34 +1155,34 @@ namespace boost // Lambert W: template - typename boost::math::tools::promote_args::type lambert_w0(T z, const Policy& pol); + boost::math::tools::promote_args_t lambert_w0(T z, const Policy& pol); template - typename boost::math::tools::promote_args::type lambert_w0(T z); + boost::math::tools::promote_args_t lambert_w0(T z); template - typename boost::math::tools::promote_args::type lambert_wm1(T z, const Policy& pol); + boost::math::tools::promote_args_t lambert_wm1(T z, const Policy& pol); template - typename boost::math::tools::promote_args::type lambert_wm1(T z); + boost::math::tools::promote_args_t lambert_wm1(T z); template - typename boost::math::tools::promote_args::type lambert_w0_prime(T z, const Policy& pol); + boost::math::tools::promote_args_t lambert_w0_prime(T z, const Policy& pol); template - typename boost::math::tools::promote_args::type lambert_w0_prime(T z); + boost::math::tools::promote_args_t lambert_w0_prime(T z); template - typename boost::math::tools::promote_args::type lambert_wm1_prime(T z, const Policy& pol); + boost::math::tools::promote_args_t lambert_wm1_prime(T z, const Policy& pol); template - typename boost::math::tools::promote_args::type lambert_wm1_prime(T z); + boost::math::tools::promote_args_t lambert_wm1_prime(T z); // Hypergeometrics: - template typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z); - template typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z, const Policy&); + template tools::promote_args_t hypergeometric_1F0(T1 a, T2 z); + template tools::promote_args_t hypergeometric_1F0(T1 a, T2 z, const Policy&); - template typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z); - template typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z, const Policy&); + template tools::promote_args_t hypergeometric_0F1(T1 b, T2 z); + template tools::promote_args_t hypergeometric_0F1(T1 b, T2 z, const Policy&); - template typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z); - template typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy&); + template tools::promote_args_t hypergeometric_2F0(T1 a1, T2 a2, T3 z); + template tools::promote_args_t hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy&); - template typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z); - template typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy&); + template tools::promote_args_t hypergeometric_1F1(T1 a, T2 b, T3 z); + template tools::promote_args_t hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy&); } // namespace math @@ -1201,7 +1201,7 @@ namespace boost # define BOOST_MATH_DETAIL_11_FUNC(Policy)\ template \ - inline typename boost::math::tools::promote_args::type hypergeometric_1F1(const T& a, const U& b, const V& z)\ + inline boost::math::tools::promote_args_t hypergeometric_1F1(const T& a, const U& b, const V& z)\ { return boost::math::hypergeometric_1F1(a, b, z, Policy()); }\ #define BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)\ @@ -1210,99 +1210,99 @@ namespace boost BOOST_MATH_DETAIL_11_FUNC(Policy)\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ beta(RT1 a, RT2 b) { return ::boost::math::beta(a, b, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ beta(RT1 a, RT2 b, A x){ return ::boost::math::beta(a, b, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ betac(RT1 a, RT2 b, RT3 x) { return ::boost::math::betac(a, b, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta(a, b, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibetac(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibetac(a, b, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta_inv(T1 a, T2 b, T3 p, T4* py){ return ::boost::math::ibeta_inv(a, b, p, py, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta_inv(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inv(a, b, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibetac_inv(T1 a, T2 b, T3 q, T4* py){ return ::boost::math::ibetac_inv(a, b, q, py, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta_inva(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inva(a, b, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibetac_inva(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_inva(a, b, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta_invb(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_invb(a, b, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibetac_invb(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_invb(a, b, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibetac_inv(RT1 a, RT2 b, RT3 q){ return ::boost::math::ibetac_inv(a, b, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ibeta_derivative(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta_derivative(a, b, x, Policy()); }\ \ template T binomial_coefficient(unsigned n, unsigned k){ return ::boost::math::binomial_coefficient(n, k, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type erf(RT z) { return ::boost::math::erf(z, Policy()); }\ + inline boost::math::tools::promote_args_t erf(RT z) { return ::boost::math::erf(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type erfc(RT z){ return ::boost::math::erfc(z, Policy()); }\ + inline boost::math::tools::promote_args_t erfc(RT z){ return ::boost::math::erfc(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type erf_inv(RT z) { return ::boost::math::erf_inv(z, Policy()); }\ + inline boost::math::tools::promote_args_t erf_inv(RT z) { return ::boost::math::erf_inv(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type erfc_inv(RT z){ return ::boost::math::erfc_inv(z, Policy()); }\ + inline boost::math::tools::promote_args_t erfc_inv(RT z){ return ::boost::math::erfc_inv(z, Policy()); }\ \ using boost::math::legendre_next;\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ legendre_p(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ legendre_p_prime(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ legendre_q(unsigned l, T x){ return ::boost::math::legendre_q(l, x, Policy()); }\ \ using ::boost::math::legendre_next;\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ legendre_p(int l, int m, T x){ return ::boost::math::legendre_p(l, m, x, Policy()); }\ \ using ::boost::math::laguerre_next;\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ laguerre(unsigned n, T x){ return ::boost::math::laguerre(n, x, Policy()); }\ \ template \ @@ -1310,7 +1310,7 @@ namespace boost laguerre(unsigned n, T1 m, T2 x) { return ::boost::math::laguerre(n, m, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ hermite(unsigned n, T x){ return ::boost::math::hermite(n, x, Policy()); }\ \ using boost::math::hermite_next;\ @@ -1329,70 +1329,70 @@ namespace boost using ::boost::math::chebyshev_clenshaw_recurrence;\ \ template \ - inline std::complex::type> \ + inline std::complex> \ spherical_harmonic(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic(n, m, theta, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi){ return ::boost::math::spherical_harmonic_r(n, m, theta, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic_i(n, m, theta, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ellint_rf(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rf(x, y, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ellint_rd(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rd(x, y, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ellint_rc(T1 x, T2 y){ return ::boost::math::ellint_rc(x, y, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ellint_rj(T1 x, T2 y, T3 z, T4 p){ return boost::math::ellint_rj(x, y, z, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ ellint_rg(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rg(x, y, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_2(T k){ return boost::math::ellint_2(k, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_2(T k){ return boost::math::ellint_2(k, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_2(T1 k, T2 phi){ return boost::math::ellint_2(k, phi, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_2(T1 k, T2 phi){ return boost::math::ellint_2(k, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_d(T k){ return boost::math::ellint_d(k, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_d(T k){ return boost::math::ellint_d(k, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_d(T1 k, T2 phi){ return boost::math::ellint_d(k, phi, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_d(T1 k, T2 phi){ return boost::math::ellint_d(k, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_zeta(T1 k, T2 phi){ return boost::math::jacobi_zeta(k, phi, Policy()); }\ + inline boost::math::tools::promote_args_t jacobi_zeta(T1 k, T2 phi){ return boost::math::jacobi_zeta(k, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type heuman_lambda(T1 k, T2 phi){ return boost::math::heuman_lambda(k, phi, Policy()); }\ + inline boost::math::tools::promote_args_t heuman_lambda(T1 k, T2 phi){ return boost::math::heuman_lambda(k, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_1(T k){ return boost::math::ellint_1(k, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_1(T k){ return boost::math::ellint_1(k, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_1(T1 k, T2 phi){ return boost::math::ellint_1(k, phi, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_1(T1 k, T2 phi){ return boost::math::ellint_1(k, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi){ return boost::math::ellint_3(k, v, phi, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_3(T1 k, T2 v, T3 phi){ return boost::math::ellint_3(k, v, phi, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type ellint_3(T1 k, T2 v){ return boost::math::ellint_3(k, v, Policy()); }\ + inline boost::math::tools::promote_args_t ellint_3(T1 k, T2 v){ return boost::math::ellint_3(k, v, Policy()); }\ \ using boost::math::max_factorial;\ template \ @@ -1401,101 +1401,101 @@ namespace boost template \ inline RT double_factorial(unsigned i){ return boost::math::double_factorial(i, Policy()); }\ template \ - inline typename boost::math::tools::promote_args::type falling_factorial(RT x, unsigned n){ return boost::math::falling_factorial(x, n, Policy()); }\ + inline boost::math::tools::promote_args_t falling_factorial(RT x, unsigned n){ return boost::math::falling_factorial(x, n, Policy()); }\ template \ - inline typename boost::math::tools::promote_args::type rising_factorial(RT x, unsigned n){ return boost::math::rising_factorial(x, n, Policy()); }\ + inline boost::math::tools::promote_args_t rising_factorial(RT x, unsigned n){ return boost::math::rising_factorial(x, n, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma(RT z){ return boost::math::tgamma(z, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma(RT z){ return boost::math::tgamma(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma1pm1(RT z){ return boost::math::tgamma1pm1(z, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma1pm1(RT z){ return boost::math::tgamma1pm1(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma(RT1 a, RT2 z){ return boost::math::tgamma(a, z, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma(RT1 a, RT2 z){ return boost::math::tgamma(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type lgamma(RT z, int* sign){ return boost::math::lgamma(z, sign, Policy()); }\ + inline boost::math::tools::promote_args_t lgamma(RT z, int* sign){ return boost::math::lgamma(z, sign, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type lgamma(RT x){ return boost::math::lgamma(x, Policy()); }\ + inline boost::math::tools::promote_args_t lgamma(RT x){ return boost::math::lgamma(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma_lower(RT1 a, RT2 z){ return boost::math::tgamma_lower(a, z, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma_lower(RT1 a, RT2 z){ return boost::math::tgamma_lower(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_q(RT1 a, RT2 z){ return boost::math::gamma_q(a, z, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_q(RT1 a, RT2 z){ return boost::math::gamma_q(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_p(RT1 a, RT2 z){ return boost::math::gamma_p(a, z, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_p(RT1 a, RT2 z){ return boost::math::gamma_p(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta){ return boost::math::tgamma_delta_ratio(z, delta, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta){ return boost::math::tgamma_delta_ratio(z, delta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type tgamma_ratio(T1 a, T2 b) { return boost::math::tgamma_ratio(a, b, Policy()); }\ + inline boost::math::tools::promote_args_t tgamma_ratio(T1 a, T2 b) { return boost::math::tgamma_ratio(a, b, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_p_derivative(T1 a, T2 x){ return boost::math::gamma_p_derivative(a, x, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_p_derivative(T1 a, T2 x){ return boost::math::gamma_p_derivative(a, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_p_inv(T1 a, T2 p){ return boost::math::gamma_p_inv(a, p, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_p_inv(T1 a, T2 p){ return boost::math::gamma_p_inv(a, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_p_inva(T1 a, T2 p){ return boost::math::gamma_p_inva(a, p, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_p_inva(T1 a, T2 p){ return boost::math::gamma_p_inva(a, p, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_q_inv(T1 a, T2 q){ return boost::math::gamma_q_inv(a, q, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_q_inv(T1 a, T2 q){ return boost::math::gamma_q_inv(a, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type gamma_q_inva(T1 a, T2 q){ return boost::math::gamma_q_inva(a, q, Policy()); }\ + inline boost::math::tools::promote_args_t gamma_q_inva(T1 a, T2 q){ return boost::math::gamma_q_inva(a, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type digamma(T x){ return boost::math::digamma(x, Policy()); }\ + inline boost::math::tools::promote_args_t digamma(T x){ return boost::math::digamma(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type trigamma(T x){ return boost::math::trigamma(x, Policy()); }\ + inline boost::math::tools::promote_args_t trigamma(T x){ return boost::math::trigamma(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type polygamma(int n, T x){ return boost::math::polygamma(n, x, Policy()); }\ + inline boost::math::tools::promote_args_t polygamma(int n, T x){ return boost::math::polygamma(n, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ hypot(T1 x, T2 y){ return boost::math::hypot(x, y, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type cbrt(RT z){ return boost::math::cbrt(z, Policy()); }\ + inline boost::math::tools::promote_args_t cbrt(RT z){ return boost::math::cbrt(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type log1p(T x){ return boost::math::log1p(x, Policy()); }\ + inline boost::math::tools::promote_args_t log1p(T x){ return boost::math::log1p(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type log1pmx(T x){ return boost::math::log1pmx(x, Policy()); }\ + inline boost::math::tools::promote_args_t log1pmx(T x){ return boost::math::log1pmx(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type expm1(T x){ return boost::math::expm1(x, Policy()); }\ + inline boost::math::tools::promote_args_t expm1(T x){ return boost::math::expm1(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type \ + inline boost::math::tools::promote_args_t \ powm1(const T1 a, const T2 z){ return boost::math::powm1(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type sqrt1pm1(const T& val){ return boost::math::sqrt1pm1(val, Policy()); }\ + inline boost::math::tools::promote_args_t sqrt1pm1(const T& val){ return boost::math::sqrt1pm1(val, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type sinc_pi(T x){ return boost::math::sinc_pi(x, Policy()); }\ + inline boost::math::tools::promote_args_t sinc_pi(T x){ return boost::math::sinc_pi(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type sinhc_pi(T x){ return boost::math::sinhc_pi(x, Policy()); }\ + inline boost::math::tools::promote_args_t sinhc_pi(T x){ return boost::math::sinhc_pi(x, Policy()); }\ \ template\ - inline typename boost::math::tools::promote_args::type asinh(const T x){ return boost::math::asinh(x, Policy()); }\ + inline boost::math::tools::promote_args_t asinh(const T x){ return boost::math::asinh(x, Policy()); }\ \ template\ - inline typename boost::math::tools::promote_args::type acosh(const T x){ return boost::math::acosh(x, Policy()); }\ + inline boost::math::tools::promote_args_t acosh(const T x){ return boost::math::acosh(x, Policy()); }\ \ template\ - inline typename boost::math::tools::promote_args::type atanh(const T x){ return boost::math::atanh(x, Policy()); }\ + inline boost::math::tools::promote_args_t atanh(const T x){ return boost::math::atanh(x, Policy()); }\ \ template \ inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x)\ @@ -1568,10 +1568,10 @@ template \ { boost::math::cyl_neumann_zero(v, start_index, number_of_zeros, out_it, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type sin_pi(T x){ return boost::math::sin_pi(x, Policy()); }\ + inline boost::math::tools::promote_args_t sin_pi(T x){ return boost::math::sin_pi(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type cos_pi(T x){ return boost::math::cos_pi(x, Policy()); }\ + inline boost::math::tools::promote_args_t cos_pi(T x){ return boost::math::cos_pi(x, Policy()); }\ \ using boost::math::fpclassify;\ using boost::math::isfinite;\ @@ -1584,14 +1584,14 @@ template \ using boost::math::changesign;\ \ template \ - inline typename boost::math::tools::promote_args::type expint(T const& z, U const& u)\ + inline typename boost::math::tools::promote_args_t expint(T const& z, U const& u)\ { return boost::math::expint(z, u, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type expint(T z){ return boost::math::expint(z, Policy()); }\ + inline boost::math::tools::promote_args_t expint(T z){ return boost::math::expint(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type zeta(T s){ return boost::math::zeta(s, Policy()); }\ + inline boost::math::tools::promote_args_t zeta(T s){ return boost::math::zeta(s, Policy()); }\ \ template \ inline T round(const T& v){ using boost::math::round; return round(v, Policy()); }\ @@ -1621,16 +1621,16 @@ template \ inline T modf(const T& v, long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type pow(T v){ return boost::math::pow(v, Policy()); }\ + inline boost::math::tools::promote_args_t pow(T v){ return boost::math::pow(v, Policy()); }\ \ - template T nextafter(const T& a, const T& b){ return boost::math::nextafter(a, b, Policy()); }\ - template T float_next(const T& a){ return boost::math::float_next(a, Policy()); }\ - template T float_prior(const T& a){ return boost::math::float_prior(a, Policy()); }\ - template T float_distance(const T& a, const T& b){ return boost::math::float_distance(a, b, Policy()); }\ - template T ulp(const T& a){ return boost::math::ulp(a, Policy()); }\ + template T nextafter(const T& a, const T& b){ return static_cast(boost::math::nextafter(a, b, Policy())); }\ + template T float_next(const T& a){ return static_cast(boost::math::float_next(a, Policy())); }\ + template T float_prior(const T& a){ return static_cast(boost::math::float_prior(a, Policy())); }\ + template T float_distance(const T& a, const T& b){ return static_cast(boost::math::float_distance(a, b, Policy())); }\ + template T ulp(const T& a){ return static_cast(boost::math::ulp(a, Policy())); }\ \ template \ - inline typename boost::math::tools::promote_args::type owens_t(RT1 a, RT2 z){ return boost::math::owens_t(a, z, Policy()); }\ + inline boost::math::tools::promote_args_t owens_t(RT1 a, RT2 z){ return boost::math::owens_t(a, z, Policy()); }\ \ template \ inline std::complex::result_type> cyl_hankel_1(T1 v, T2 x)\ @@ -1649,119 +1649,119 @@ template \ { return boost::math::sph_hankel_2(v, x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_elliptic(T k, T theta, T* pcn, T* pdn)\ - { return boost::math::jacobi_elliptic(k, theta, pcn, pdn, Policy()); }\ + inline boost::math::tools::promote_args_t jacobi_elliptic(T k, T theta, T* pcn, T* pdn)\ + { return static_cast>(boost::math::jacobi_elliptic(k, theta, pcn, pdn, Policy())); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_sn(U k, T theta)\ + inline boost::math::tools::promote_args_t jacobi_sn(U k, T theta)\ { return boost::math::jacobi_sn(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_cn(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_cn(T k, U theta)\ { return boost::math::jacobi_cn(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_dn(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_dn(T k, U theta)\ { return boost::math::jacobi_dn(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_cd(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_cd(T k, U theta)\ { return boost::math::jacobi_cd(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_dc(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_dc(T k, U theta)\ { return boost::math::jacobi_dc(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_ns(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_ns(T k, U theta)\ { return boost::math::jacobi_ns(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_sd(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_sd(T k, U theta)\ { return boost::math::jacobi_sd(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_ds(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_ds(T k, U theta)\ { return boost::math::jacobi_ds(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_nc(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_nc(T k, U theta)\ { return boost::math::jacobi_nc(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_nd(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_nd(T k, U theta)\ { return boost::math::jacobi_nd(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_sc(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_sc(T k, U theta)\ { return boost::math::jacobi_sc(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_cs(T k, U theta)\ + inline boost::math::tools::promote_args_t jacobi_cs(T k, U theta)\ { return boost::math::jacobi_cs(k, theta, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta1(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta1(T z, U q)\ { return boost::math::jacobi_theta1(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta2(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta2(T z, U q)\ { return boost::math::jacobi_theta2(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta3(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta3(T z, U q)\ { return boost::math::jacobi_theta3(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta4(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta4(T z, U q)\ { return boost::math::jacobi_theta4(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta1tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta1tau(T z, U q)\ { return boost::math::jacobi_theta1tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta2tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta2tau(T z, U q)\ { return boost::math::jacobi_theta2tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta3tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta3tau(T z, U q)\ { return boost::math::jacobi_theta3tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta4tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta4tau(T z, U q)\ { return boost::math::jacobi_theta4tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta3m1(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta3m1(T z, U q)\ { return boost::math::jacobi_theta3m1(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta4m1(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta4m1(T z, U q)\ { return boost::math::jacobi_theta4m1(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta3m1tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta3m1tau(T z, U q)\ { return boost::math::jacobi_theta3m1tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type jacobi_theta4m1tau(T z, U q)\ + inline boost::math::tools::promote_args_t jacobi_theta4m1tau(T z, U q)\ { return boost::math::jacobi_theta4m1tau(z, q, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type airy_ai(T x)\ + inline boost::math::tools::promote_args_t airy_ai(T x)\ { return boost::math::airy_ai(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type airy_bi(T x)\ + inline boost::math::tools::promote_args_t airy_bi(T x)\ { return boost::math::airy_bi(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type airy_ai_prime(T x)\ + inline boost::math::tools::promote_args_t airy_ai_prime(T x)\ { return boost::math::airy_ai_prime(x, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type airy_bi_prime(T x)\ + inline boost::math::tools::promote_args_t airy_bi_prime(T x)\ { return boost::math::airy_bi_prime(x, Policy()); }\ \ template \ @@ -1792,21 +1792,21 @@ template \ OutputIterator tangent_t2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\ { return boost::math::tangent_t2n(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\ \ - template inline typename boost::math::tools::promote_args::type lambert_w0(T z) { return boost::math::lambert_w0(z, Policy()); }\ - template inline typename boost::math::tools::promote_args::type lambert_wm1(T z) { return boost::math::lambert_w0(z, Policy()); }\ - template inline typename boost::math::tools::promote_args::type lambert_w0_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ - template inline typename boost::math::tools::promote_args::type lambert_wm1_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_w0(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_wm1(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_w0_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_wm1_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type hypergeometric_1F0(const T& a, const U& z)\ + inline boost::math::tools::promote_args_t hypergeometric_1F0(const T& a, const U& z)\ { return boost::math::hypergeometric_1F0(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type hypergeometric_0F1(const T& a, const U& z)\ + inline boost::math::tools::promote_args_t hypergeometric_0F1(const T& a, const U& z)\ { return boost::math::hypergeometric_0F1(a, z, Policy()); }\ \ template \ - inline typename boost::math::tools::promote_args::type hypergeometric_2F0(const T& a1, const U& a2, const V& z)\ + inline boost::math::tools::promote_args_t hypergeometric_2F0(const T& a1, const U& a2, const V& z)\ { return boost::math::hypergeometric_2F0(a1, a2, z, Policy()); }\ \ From 5d044d52f59361d071262fbfc25259b576cf5ffe Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 9 May 2023 13:43:55 +0200 Subject: [PATCH 08/53] Remove cast for output iterator --- include/boost/math/special_functions/bessel.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/math/special_functions/bessel.hpp b/include/boost/math/special_functions/bessel.hpp index 2f9d6a1c42..35ad350262 100644 --- a/include/boost/math/special_functions/bessel.hpp +++ b/include/boost/math/special_functions/bessel.hpp @@ -680,7 +680,7 @@ inline OutputIterator cyl_bessel_j_zero(T v, for(int i = 0; i < static_cast(number_of_zeros); ++i) { - *out_it = static_cast(boost::math::cyl_bessel_j_zero(v, start_index + i, pol)); + *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); ++out_it; } return out_it; @@ -741,7 +741,7 @@ inline OutputIterator cyl_neumann_zero(T v, for(int i = 0; i < static_cast(number_of_zeros); ++i) { - *out_it = static_cast(boost::math::cyl_neumann_zero(v, start_index + i, pol)); + *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); ++out_it; } return out_it; From 6a3a89bfd11cd52a4582553abd9e259eea9f2ec3 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 May 2023 14:36:24 +0200 Subject: [PATCH 09/53] Add testing to quadrature --- test/exp_sinh_quadrature_test.cpp | 22 ++++ test/gauss_kronrod_quadrature_test.cpp | 27 +++++ test/gauss_quadrature_test.cpp | 23 ++++ test/naive_monte_carlo_test.cpp | 160 +++++++++++++++++++++++++ test/test_trapezoidal.cpp | 41 +++++++ 5 files changed, 273 insertions(+) diff --git a/test/exp_sinh_quadrature_test.cpp b/test/exp_sinh_quadrature_test.cpp index da0c3a5483..d39ec4c5dc 100644 --- a/test/exp_sinh_quadrature_test.cpp +++ b/test/exp_sinh_quadrature_test.cpp @@ -29,6 +29,10 @@ #include #endif +#if __has_include() +# include +#endif + using std::exp; using std::cos; using std::tan; @@ -586,17 +590,35 @@ BOOST_AUTO_TEST_CASE(exp_sinh_quadrature_test) */ #ifdef TEST1 + +#ifdef __STDCPP_FLOAT32_T__ + test_left_limit_infinite(); + test_right_limit_infinite(); + test_nr_examples(); + test_crc(); +#else test_left_limit_infinite(); test_right_limit_infinite(); test_nr_examples(); test_crc(); #endif + +#endif #ifdef TEST2 + +#ifdef __STDCPP_FLOAT64_T__ + test_left_limit_infinite(); + test_right_limit_infinite(); + test_nr_examples(); + test_crc(); +#else test_left_limit_infinite(); test_right_limit_infinite(); test_nr_examples(); test_crc(); #endif + +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS #ifdef TEST3 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS diff --git a/test/gauss_kronrod_quadrature_test.cpp b/test/gauss_kronrod_quadrature_test.cpp index 3ee9c85740..5877146d71 100644 --- a/test/gauss_kronrod_quadrature_test.cpp +++ b/test/gauss_kronrod_quadrature_test.cpp @@ -38,6 +38,10 @@ #pragma warning(disable:4127) // Conditional expression is constant #endif +#if __has_include() +# include +#endif + using std::expm1; using std::atan; using std::tan; @@ -456,6 +460,16 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) { #ifdef TEST1 std::cout << "Testing 15 point approximation:\n"; + +#ifdef __STDCPP_FLOAT64_T__ + test_linear(); + test_quadratic(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_integration_over_real_line(); + test_right_limit_infinite(); + test_left_limit_infinite(); +#else test_linear(); test_quadratic(); test_ca(); @@ -463,9 +477,20 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) test_integration_over_real_line(); test_right_limit_infinite(); test_left_limit_infinite(); +#endif // test one case where we do not have pre-computed constants: std::cout << "Testing 17 point approximation:\n"; + +#ifdef __STDCPP_FLOAT64_T__ + test_linear(); + test_quadratic(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_integration_over_real_line(); + test_right_limit_infinite(); + test_left_limit_infinite(); +#else test_linear(); test_quadratic(); test_ca(); @@ -473,6 +498,8 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) test_integration_over_real_line(); test_right_limit_infinite(); test_left_limit_infinite(); +#endif + test_complex_lambert_w>(); test_complex_lambert_w>(); #endif diff --git a/test/gauss_quadrature_test.cpp b/test/gauss_quadrature_test.cpp index e1d61243e9..91eca9ec20 100644 --- a/test/gauss_quadrature_test.cpp +++ b/test/gauss_quadrature_test.cpp @@ -31,6 +31,10 @@ #pragma warning(disable:4127) // Conditional expression is constant #endif +#if __has_include() +# include +#endif + #if !defined(TEST1) && !defined(TEST2) && !defined(TEST3) # define TEST1 # define TEST2 @@ -445,6 +449,24 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) { #ifdef TEST1 + +#ifdef __STDCPP_FLOAT64_T__ + test_linear(); + test_quadratic(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_integration_over_real_line(); + test_right_limit_infinite(); + test_left_limit_infinite(); + + test_linear(); + test_quadratic(); + test_ca(); + test_three_quadrature_schemes_examples(); + test_integration_over_real_line(); + test_right_limit_infinite(); + test_left_limit_infinite(); +#else test_linear(); test_quadratic(); test_ca(); @@ -460,6 +482,7 @@ BOOST_AUTO_TEST_CASE(gauss_quadrature_test) test_integration_over_real_line(); test_right_limit_infinite(); test_left_limit_infinite(); +#endif #if LDBL_MANT_DIG < 100 && defined(BOOST_MATH_RUN_MP_TESTS) test_linear(); diff --git a/test/naive_monte_carlo_test.cpp b/test/naive_monte_carlo_test.cpp index 358ebdd0a9..47e8f54baf 100644 --- a/test/naive_monte_carlo_test.cpp +++ b/test/naive_monte_carlo_test.cpp @@ -16,6 +16,10 @@ #include #include +#if __has_include() +# include +#endif + using std::abs; using std::vector; using std::pair; @@ -452,93 +456,249 @@ BOOST_AUTO_TEST_CASE(naive_monte_carlo_test) { std::cout << "Default hardware concurrency = " << std::thread::hardware_concurrency() << std::endl; #if !defined(TEST) || TEST == 1 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_finite_singular_boundary(); + test_finite_singular_boundary(); +#else test_finite_singular_boundary(); test_finite_singular_boundary(); #endif + +#endif #if !defined(TEST) || TEST == 2 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_pi(); + test_pi(); +#else test_pi(); test_pi(); #endif + +#endif #if !defined(TEST) || TEST == 3 + +#ifdef __STDCPP_FLOAT32_T__ + test_pi_multithreaded(); + test_constant(); +#else test_pi_multithreaded(); test_constant(); +#endif + #endif //test_pi(); #if !defined(TEST) || TEST == 4 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_constant(); + test_cancel_and_restart(); +#else test_constant(); //test_constant(); test_cancel_and_restart(); #endif + +#endif #if !defined(TEST) || TEST == 5 + +#ifdef __STDCPP_FLOAT32_T__ + test_exception_from_integrand(); + test_variance(); +#else test_exception_from_integrand(); test_variance(); #endif + +#endif #if !defined(TEST) || TEST == 6 + +#ifdef __STDCPP_FLOAT64_T__ + test_variance(); + test_multithreaded_variance(); +#else test_variance(); test_multithreaded_variance(); #endif + +#endif #if !defined(TEST) || TEST == 7 + +#ifdef __STDCPP_FLOAT32_T__ + test_product(); + test_product(); +#else test_product(); test_product(); #endif + +#endif #if !defined(TEST) || TEST == 8 + +#ifdef __STDCPP_FLOAT32_T__ + test_product(); + test_product(); + test_product(); +#else test_product(); test_product(); test_product(); #endif + +#endif #if !defined(TEST) || TEST == 9 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_product(); + test_product(); +#else test_product(); test_product(); #endif + +#endif #if !defined(TEST) || TEST == 10 + +#ifdef __STDCPP_FLOAT64_T__ + test_product(); +#else test_product(); #endif + +#endif #if !defined(TEST) || TEST == 11 + +#ifdef __STDCPP_FLOAT64_T__ + test_product(); + test_product(); +#else test_product(); test_product(); #endif + +#endif #if !defined(TEST) || TEST == 12 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_upper_bound_infinite(); + test_upper_bound_infinite(); +#else test_upper_bound_infinite(); test_upper_bound_infinite(); #endif + +#endif #if !defined(TEST) || TEST == 13 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_lower_bound_infinite(); + test_lower_bound_infinite(); +#else test_lower_bound_infinite(); test_lower_bound_infinite(); #endif + +#endif #if !defined(TEST) || TEST == 14 + +#ifdef __STDCPP_FLOAT32_T__ + test_lower_bound_infinite2(); +#else test_lower_bound_infinite2(); #endif + +#endif #if !defined(TEST) || TEST == 15 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_double_infinite(); + test_double_infinite(); +#else test_double_infinite(); test_double_infinite(); #endif + +#endif #if !defined(TEST) || TEST == 16 + +#ifdef __STDCPP_FLOAT32_T__ + test_radovic(); + test_radovic(); +#else test_radovic(); test_radovic(); #endif + +#endif #if !defined(TEST) || TEST == 17 + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_radovic(); + test_radovic(); +#else test_radovic(); test_radovic(); #endif + +#endif #if !defined(TEST) || TEST == 18 + +#ifdef __STDCPP_FLOAT64_T__ + test_radovic(); + test_radovic(); +#else test_radovic(); test_radovic(); #endif + +#endif #if !defined(TEST) || TEST == 19 + +#ifdef __STDCPP_FLOAT64_T__ + test_radovic(); + test_radovic(); +#else test_radovic(); test_radovic(); #endif + +#endif #if !defined(TEST) || TEST == 20 + +#ifdef __STDCPP_FLOAT32_T__ + test_alternative_rng_1(); +#else test_alternative_rng_1(); #endif + +#endif #if !defined(TEST) || TEST == 21 + +#ifdef __STDCPP_FLOAT64_T__ + test_alternative_rng_1(); +#else test_alternative_rng_1(); #endif + +#endif #if !defined(TEST) || TEST == 22 + +#ifdef __STDCPP_FLOAT32_T__ + test_alternative_rng_2(); +#else test_alternative_rng_2(); #endif + +#endif #if !defined(TEST) || TEST == 23 + +#ifdef __STDCPP_FLOAT64_T__ + test_alternative_rng_2(); +#else test_alternative_rng_2(); #endif +#endif + } diff --git a/test/test_trapezoidal.cpp b/test/test_trapezoidal.cpp index dc5eb88ac5..ed8eeb3dea 100644 --- a/test/test_trapezoidal.cpp +++ b/test/test_trapezoidal.cpp @@ -21,6 +21,11 @@ #ifdef BOOST_HAS_FLOAT128 #include #endif + +#if __has_include() +# include +#endif + using boost::multiprecision::cpp_bin_float_50; using boost::multiprecision::cpp_bin_float_100; using boost::math::quadrature::trapezoidal; @@ -230,8 +235,14 @@ void test_rational_sin() BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) { + +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_constant(); + test_constant(); +#else test_constant(); test_constant(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_constant(); #endif @@ -241,8 +252,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_constant(); test_constant(); +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_rational_periodic(); + test_rational_periodic(); +#else test_rational_periodic(); test_rational_periodic(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_rational_periodic(); #endif @@ -255,8 +271,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_rational_periodic(); #endif +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_bump_function(); + test_bump_function(); +#else test_bump_function(); test_bump_function(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_bump_function(); #endif @@ -268,8 +289,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_rational_periodic(); #endif +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_zero_function(); + test_zero_function(); +#else test_zero_function(); test_zero_function(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_zero_function(); #endif @@ -282,8 +308,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_zero_function(); #endif +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_sinsq(); + test_sinsq(); +#else test_sinsq(); test_sinsq(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_sinsq(); #endif @@ -296,8 +327,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_sinsq(); #endif +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_slowly_converging(); + test_slowly_converging(); +#else test_slowly_converging(); test_slowly_converging(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_slowly_converging(); #endif @@ -305,8 +341,13 @@ BOOST_AUTO_TEST_CASE(trapezoidal_quadrature) test_slowly_converging(); #endif +#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) + test_rational_sin(); + test_rational_sin(); +#else test_rational_sin(); test_rational_sin(); +#endif #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_rational_sin(); #endif From 3c2a04e96a443271c2650e169b979f03d980842d Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 May 2023 15:01:54 +0200 Subject: [PATCH 10/53] Add gcc-13 to drone config Revert this commit --- .drone.star | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/.drone.star b/.drone.star index 5c4cc5db8a..fe27f2a106 100644 --- a/.drone.star +++ b/.drone.star @@ -16,6 +16,7 @@ windowsglobalimage="cppalliance/dronevs2019" def main(ctx): things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests" ] + gcc13_things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests", "new_floats" ] sanitizer_test = [ "special_fun", "distribution_tests", "misc", "interpolators", "quadrature", "float128_tests" ] gnu_5_stds = [ "gnu++14", "c++14" ] gnu_6_stds = [ "gnu++14", "c++14", "gnu++17", "c++17" ] @@ -23,42 +24,13 @@ def main(ctx): gnu_9_stds = [ "gnu++14", "c++14", "gnu++17", "c++17", "gnu++2a", "c++2a" ] clang_10_stds = [ "c++14", "c++17", "c++2a" ] gnu_non_native = [ "gnu++17" ] + gcc13_stds = [ "c++23" ] result = [] - for suite in sanitizer_test: - # - # Sanitizers: - # - result.append(linux_cxx("Ubuntu g++-10 C++2a ASAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=address -fsanitize=address -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-10 C++2a USAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=undefined -fsanitize=undefined -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-10 C++2a TSAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=thread -fsanitize=thread -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu clang++-10 C++2a ISAN" + " " + suite, "clang++-10", packages="clang-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=integer -fsanitize=integer' }, globalenv=globalenv)) - for suite in things_to_test: - for cxx in gnu_5_stds: - result.append(linux_cxx("Ubuntu g++-5 " + cxx + " " + suite, "g++-5", packages="g++-5", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in gnu_6_stds: - result.append(linux_cxx("Ubuntu g++-6 " + cxx + " " + suite, "g++-6", packages="g++-6", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-7 " + cxx + " " + suite, "g++-7", packages="g++-7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-8 " + cxx + " " + suite, "g++-8", packages="g++-8", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-9 " + cxx + " " + suite, "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in clang_6_stds: - result.append(linux_cxx("Ubuntu clang++-6 " + cxx + " " + suite, "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu clang++-7 " + cxx + " " + suite, "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu clang++-8 " + cxx + " " + suite, "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu clang++-9 " + cxx + " " + suite, "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in gnu_9_stds: - result.append(linux_cxx("Ubuntu g++-10 " + cxx + " " + suite, "g++-10", packages="g++-10", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - result.append(linux_cxx("Ubuntu g++-11 " + cxx + " " + suite, "g++-11", packages="g++-11", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-11', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in clang_10_stds: - result.append(linux_cxx("Ubuntu clang++-10 " + cxx + " " + suite, "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in gnu_non_native: - result.append(linux_cxx("Ubuntu g++ s390s " + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="s390x", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in gnu_non_native: - result.append(linux_cxx("Ubuntu g++ ARM64" + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="arm64", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) - for cxx in gnu_non_native: - result.append(osx_cxx("M1 Clang " + cxx + " " + suite, "clang++", buildscript="drone", buildtype="boost", xcode_version="14.1", environment={'TOOLSET': 'clang', 'CXXSTD': cxx, 'TEST_SUITE': suite, 'DEFINE': 'BOOST_MATH_NO_REAL_CONCEPT_TESTS,BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS,BOOST_MATH_MULTI_ARCH_CI_RUN', }, globalenv=globalenv)) + for cxx in gcc13_stds: + result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) return result From ac4605b12df8b11740a54f09831ab2964b2d2a02 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 13 May 2023 19:13:11 +0100 Subject: [PATCH 11/53] Fix Minw-64 C++23 compile failures. --- .../boost/math/differentiation/lanczos_smoothing.hpp | 1 + include/boost/math/tools/luroth_expansion.hpp | 1 + .../boost/math/tools/simple_continued_fraction.hpp | 1 + test/naive_monte_carlo_test.cpp | 6 +++--- test/tanh_sinh_quadrature_test.cpp | 12 ++++++------ test/test_trapezoidal.cpp | 12 ++++++------ 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/boost/math/differentiation/lanczos_smoothing.hpp b/include/boost/math/differentiation/lanczos_smoothing.hpp index 1f18c2f6d5..9406b302d7 100644 --- a/include/boost/math/differentiation/lanczos_smoothing.hpp +++ b/include/boost/math/differentiation/lanczos_smoothing.hpp @@ -10,6 +10,7 @@ #include // to nan initialize #include #include +#include #include #include #include diff --git a/include/boost/math/tools/luroth_expansion.hpp b/include/boost/math/tools/luroth_expansion.hpp index 6cc6f9abdc..f98594251e 100644 --- a/include/boost/math/tools/luroth_expansion.hpp +++ b/include/boost/math/tools/luroth_expansion.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/include/boost/math/tools/simple_continued_fraction.hpp b/include/boost/math/tools/simple_continued_fraction.hpp index 0fe17fc59d..790f98462e 100644 --- a/include/boost/math/tools/simple_continued_fraction.hpp +++ b/include/boost/math/tools/simple_continued_fraction.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/test/naive_monte_carlo_test.cpp b/test/naive_monte_carlo_test.cpp index 47e8f54baf..e9fcbb030f 100644 --- a/test/naive_monte_carlo_test.cpp +++ b/test/naive_monte_carlo_test.cpp @@ -152,9 +152,9 @@ void test_cancel_and_restart() auto task = mc.integrate(); mc.cancel(); - double y = task.get(); + Real y = task.get(); // Super low tolerance; because it got canceled so fast: - BOOST_CHECK_CLOSE_FRACTION(y, exact, 1.0); + BOOST_CHECK_CLOSE_FRACTION(y, exact, static_cast(1.0)); mc.update_target_error((Real) 0.01); task = mc.integrate(); @@ -215,7 +215,7 @@ void test_variance() auto task = mc.integrate(); Real y = task.get(); - BOOST_CHECK_CLOSE_FRACTION(y, 0.5, 0.01); + BOOST_CHECK_CLOSE_FRACTION(y, static_cast(0.5), static_cast(0.01)); BOOST_CHECK_CLOSE_FRACTION(mc.variance(), exact_variance, 0.05); } diff --git a/test/tanh_sinh_quadrature_test.cpp b/test/tanh_sinh_quadrature_test.cpp index 20ce99a97e..ceccb29ebb 100644 --- a/test/tanh_sinh_quadrature_test.cpp +++ b/test/tanh_sinh_quadrature_test.cpp @@ -233,12 +233,12 @@ void test_linear() Real error; Real L1; Real Q = integrator.integrate(f, (Real) 0, (Real) 1, get_convergence_tolerance(), &error, &L1); - BOOST_CHECK_CLOSE_FRACTION(Q, 9.5, tol); - BOOST_CHECK_CLOSE_FRACTION(L1, 9.5, tol); - Q = integrator.integrate(f, (Real) 1, (Real) 0, get_convergence_tolerance(), &error, &L1); - BOOST_CHECK_CLOSE_FRACTION(Q, -9.5, tol); - BOOST_CHECK_CLOSE_FRACTION(L1, 9.5, tol); - Q = integrator.integrate(f, (Real) 1, (Real) 1, get_convergence_tolerance(), &error, &L1); + BOOST_CHECK_CLOSE_FRACTION(Q, static_cast(9.5), tol); + BOOST_CHECK_CLOSE_FRACTION(L1, static_cast(9.5), tol); + Q = integrator.integrate(f, static_cast(1), static_cast(0), get_convergence_tolerance(), &error, &L1); + BOOST_CHECK_CLOSE_FRACTION(Q, static_cast(-9.5), tol); + BOOST_CHECK_CLOSE_FRACTION(L1, static_cast(9.5), tol); + Q = integrator.integrate(f, static_cast(1), static_cast(1), get_convergence_tolerance(), &error, &L1); BOOST_CHECK_EQUAL(Q, Real(0)); } diff --git a/test/test_trapezoidal.cpp b/test/test_trapezoidal.cpp index ed8eeb3dea..236d6d8848 100644 --- a/test/test_trapezoidal.cpp +++ b/test/test_trapezoidal.cpp @@ -135,13 +135,13 @@ void test_constant() std::cout << "Testing constants are integrated correctly by the adaptive trapezoidal routine on type " << boost::typeindex::type_id().pretty_name() << "\n"; auto f = [](Real)->Real { return boost::math::constants::half(); }; - Real Q = trapezoidal(f, (Real) 0.0, (Real) 10.0); - BOOST_CHECK_CLOSE(Q, 5.0, 100*std::numeric_limits::epsilon()); - Q = trapezoidal(f, (Real) 10.0, (Real) 0.0); - BOOST_CHECK_CLOSE(Q, -5.0, 100*std::numeric_limits::epsilon()); + Real Q = trapezoidal(f, static_cast(0.0), static_cast(10.0)); + BOOST_CHECK_CLOSE(Q, static_cast(5.0), 100*std::numeric_limits::epsilon()); + Q = trapezoidal(f, static_cast(10.0), static_cast(0.0)); + BOOST_CHECK_CLOSE(Q, static_cast(-5.0), 100*std::numeric_limits::epsilon()); - Q = trapezoidal(f, (Real) 10.0, (Real) 10.0); - BOOST_CHECK_CLOSE(Q, Real(0), 100*std::numeric_limits::epsilon()); + Q = trapezoidal(f, static_cast(10.0), static_cast(10.0)); + BOOST_CHECK_CLOSE(Q, static_cast(0), 100*std::numeric_limits::epsilon()); } From b3f361c123ae9eef5047edef91bb869b82e18fb1 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 14 May 2023 12:23:06 +0100 Subject: [PATCH 12/53] Fix the promote_args case. Also fixes a lot of warnings. [CI SKIP] --- include/boost/math/tools/promotion.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/math/tools/promotion.hpp b/include/boost/math/tools/promotion.hpp index 701f1927fa..68127efb04 100644 --- a/include/boost/math/tools/promotion.hpp +++ b/include/boost/math/tools/promotion.hpp @@ -222,7 +222,7 @@ namespace boost template <> struct promote_args_2 { using type = std::float32_t; }; #endif - template <> struct promote_args_2 { using type = std::float64_t; }; + template <> struct promote_args_2 { using type = std::float32_t; }; #endif #ifdef __STDCPP_FLOAT16_T__ From 58264c02e1f9efae761f2f9b1ecec760d48eccc9 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 14 May 2023 18:40:01 +0100 Subject: [PATCH 13/53] Add test case for promote_args. --- test/Jamfile.v2 | 1 + test/compile_test/test_promote_args.cpp | 184 ++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 test/compile_test/test_promote_args.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 051e332247..ac4fdfa7cf 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -882,6 +882,7 @@ test-suite distribution_tests : [ run compile_test/dist_arcsine_incl_test.cpp compile_test_main : : : [ check-target-builds ../config//is_ci_sanitizer_run "Sanitizer CI run" : no ] ] [ compile compile_test/dist_empirical_cumulative_dist_func_incl_test.cpp : [ requires cxx17_if_constexpr cxx17_std_apply ] [ check-target-builds ../config//is_ci_sanitizer_run "Sanitizer CI run" : no ] ] [ run compile_test/dist_inv_gaussian_incl_test.cpp compile_test_main : : : [ check-target-builds ../config//is_ci_sanitizer_run "Sanitizer CI run" : no ] ] + [ compile compile_test/test_promote_args.cpp : [ requires cpp_lib_type_trait_variable_templates ] ] [ run test_legacy_nonfinite.cpp ../../test/build//boost_unit_test_framework ] [ run test_basic_nonfinite.cpp ../../test/build//boost_unit_test_framework ] diff --git a/test/compile_test/test_promote_args.cpp b/test/compile_test/test_promote_args.cpp new file mode 100644 index 0000000000..c54117c131 --- /dev/null +++ b/test/compile_test/test_promote_args.cpp @@ -0,0 +1,184 @@ +// Copyright John Maddock 2023. +// 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 +#include +#include + +#if __has_include() +# include +#endif + +int main() +{ + using boost::math::tools::promote_args_t; + +#if defined(__cpp_lib_type_trait_variable_templates) + + static_assert(std::is_same_v, long double>); + static_assert(std::is_same_v, long double>); + static_assert(std::is_same_v, long double>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, long double>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, long double>); +#endif +#ifdef __STDCPP_FLOAT64_T__ +#if LDBL_MANT_DIG > 53 + static_assert(std::is_same_v, long double>); +#else + static_assert(std::is_same_v, std::float64_t>); +#endif +#endif +#ifdef __STDCPP_FLOAT128_T__ +#if LDBL_MANT_DIG > 113 + static_assert(std::is_same_v, long double>); +#else + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + + static_assert(std::is_same_v, double>); + static_assert(std::is_same_v, double>); + static_assert(std::is_same_v, long double>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, double>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, double>); +#endif +#ifdef __STDCPP_FLOAT64_T__ +#if DBL_MANT_DIG > 53 + static_assert(std::is_same_v, double>); +#else + static_assert(std::is_same_v, std::float64_t>); +#endif +#endif +#ifdef __STDCPP_FLOAT128_T__ +#if DBL_MANT_DIG > 113 + static_assert(std::is_same_v, double>); +#else + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + + static_assert(std::is_same_v, float>); + static_assert(std::is_same_v, double>); + static_assert(std::is_same_v, long double>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, float>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float32_t>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif + +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, float>); + static_assert(std::is_same_v, double>); + static_assert(std::is_same_v, long double>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, float>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float32_t>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float32_t>); + static_assert(std::is_same_v, double>); + static_assert(std::is_same_v, long double>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, std::float32_t>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float32_t>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float64_t>); + static_assert(std::is_same_v, std::float64_t>); +#if LDBL_MANT_DIG > 53 + static_assert(std::is_same_v, long double>); +#else + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float64_t>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); + static_assert(std::is_same_v, std::float128_t>); +#if LDBL_MANT_DIG > 113 + static_assert(std::is_same_v, long double>); +#else + static_assert(std::is_same_v, std::float128_t>); +#endif +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, std::float128_t>); +#endif +#endif + + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); +#ifdef __STDCPP_FLOAT16_T__ + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); +#endif +#ifdef __STDCPP_FLOAT32_T__ + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); +#endif +#ifdef __STDCPP_FLOAT64_T__ + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); +#endif +#ifdef __STDCPP_FLOAT128_T__ + static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); +#endif + +#endif + + return 0; +} From c5b4d28e05bd8eecda3ef19cb4ec428042644776 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 15 May 2023 17:08:41 +0100 Subject: [PATCH 14/53] Suppress lots of warnings for std::float32_t. Better configure promote_args test case. --- .../math/distributions/inverse_gaussian.hpp | 4 +- .../boost/math/distributions/skew_normal.hpp | 4 +- .../special_functions/detail/polygamma.hpp | 6 +- .../boost/math/special_functions/digamma.hpp | 2 +- .../boost/math/special_functions/ellint_1.hpp | 328 +++++++++--------- .../boost/math/special_functions/ellint_2.hpp | 288 +++++++-------- .../special_functions/hypergeometric_2F0.hpp | 2 +- .../boost/math/special_functions/legendre.hpp | 2 +- .../boost/math/special_functions/owens_t.hpp | 2 +- include/boost/math/special_functions/zeta.hpp | 4 +- test/compile_test/test_promote_args.cpp | 6 +- 11 files changed, 326 insertions(+), 322 deletions(-) diff --git a/include/boost/math/distributions/inverse_gaussian.hpp b/include/boost/math/distributions/inverse_gaussian.hpp index b057b4469e..c8e46913af 100644 --- a/include/boost/math/distributions/inverse_gaussian.hpp +++ b/include/boost/math/distributions/inverse_gaussian.hpp @@ -382,7 +382,7 @@ inline RealType quantile(const inverse_gaussian_distribution& RealType guess = detail::guess_ig(p, dist.mean(), dist.scale()); using boost::math::tools::max_value; - RealType min = 0.; // Minimum possible value is bottom of range of distribution. + RealType min = static_cast(0); // Minimum possible value is bottom of range of distribution. RealType max = max_value();// Maximum possible value is top of range. // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. // digits used to control how accurate to try to make the result. @@ -454,7 +454,7 @@ inline RealType quantile(const complemented2_type(0); // Minimum possible value is bottom of range of distribution. RealType max = max_value();// Maximum possible value is top of range. // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. // digits used to control how accurate to try to make the result. diff --git a/include/boost/math/distributions/skew_normal.hpp b/include/boost/math/distributions/skew_normal.hpp index 646965995b..c2843fea1c 100644 --- a/include/boost/math/distributions/skew_normal.hpp +++ b/include/boost/math/distributions/skew_normal.hpp @@ -486,7 +486,7 @@ namespace boost{ namespace math{ // 21 elements static const RealType shapes[] = { - 0.0, + static_cast(0.0), static_cast(1.000000000000000e-004), static_cast(2.069138081114790e-004), static_cast(4.281332398719396e-004), @@ -511,7 +511,7 @@ namespace boost{ namespace math{ // 21 elements static const RealType guess[] = { - 0.0, + static_cast(0.0), static_cast(5.000050000525391e-005), static_cast(1.500015000148736e-004), static_cast(3.500035000350010e-004), diff --git a/include/boost/math/special_functions/detail/polygamma.hpp b/include/boost/math/special_functions/detail/polygamma.hpp index 3a7c984edc..00b0b1ec36 100644 --- a/include/boost/math/special_functions/detail/polygamma.hpp +++ b/include/boost/math/special_functions/detail/polygamma.hpp @@ -53,7 +53,7 @@ namespace boost { namespace math { namespace detail{ if(n == 1) return 1 / x; T nlx = n * log(x); if((nlx < tools::log_max_value()) && (n < (int)max_factorial::value)) - return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * pow(x, -n); + return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * static_cast(pow(x, -n)); else return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x)); } @@ -159,7 +159,7 @@ namespace boost { namespace math { namespace detail{ { for(int k = 1; k <= iter; ++k) { - z_plus_k_pow_minus_m_minus_one = pow(z, minus_m_minus_one); + z_plus_k_pow_minus_m_minus_one = static_cast(pow(z, minus_m_minus_one)); sum0 += z_plus_k_pow_minus_m_minus_one; z += 1; } @@ -203,7 +203,7 @@ namespace boost { namespace math { namespace detail{ // be n! / z^(n+1), but since we're scaling by n! it's just // 1 / z^(n+1) for now: // - T prefix = pow(x, n + 1); + T prefix = static_cast(pow(x, n + 1)); // Warning supression: Integer power returns at least a double if(prefix == 0) return boost::math::policies::raise_overflow_error(function, nullptr, pol); prefix = 1 / prefix; diff --git a/include/boost/math/special_functions/digamma.hpp b/include/boost/math/special_functions/digamma.hpp index 92f916e113..363e4cd5ff 100644 --- a/include/boost/math/special_functions/digamma.hpp +++ b/include/boost/math/special_functions/digamma.hpp @@ -379,7 +379,7 @@ inline T digamma_imp_1_2(T x, const std::integral_constant*) -0.61041765350579073e-1f }; static const T Q[] = { - 0.1e1, + 0.1e1f, 0.15890202430554952e1f, 0.65341249856146947e0f, 0.63851690523355715e-1f diff --git a/include/boost/math/special_functions/ellint_1.hpp b/include/boost/math/special_functions/ellint_1.hpp index a47ad76766..d3243c3fa7 100644 --- a/include/boost/math/special_functions/ellint_1.hpp +++ b/include/boost/math/special_functions/ellint_1.hpp @@ -202,20 +202,20 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.591003453790792180, - 0.416000743991786912, - 0.245791514264103415, - 0.179481482914906162, - 0.144556057087555150, - 0.123200993312427711, - 0.108938811574293531, - 0.098853409871592910, - 0.091439629201749751, - 0.085842591595413900, - 0.081541118718303215, - 0.078199656811256481910 + static_cast(1.591003453790792180), + static_cast(0.416000743991786912), + static_cast(0.245791514264103415), + static_cast(0.179481482914906162), + static_cast(0.144556057087555150), + static_cast(0.123200993312427711), + static_cast(0.108938811574293531), + static_cast(0.098853409871592910), + static_cast(0.091439629201749751), + static_cast(0.085842591595413900), + static_cast(0.081541118718303215), + static_cast(0.078199656811256481910) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.05); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.05)); } case 2: case 3: @@ -223,20 +223,20 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.635256732264579992, - 0.471190626148732291, - 0.309728410831499587, - 0.252208311773135699, - 0.226725623219684650, - 0.215774446729585976, - 0.213108771877348910, - 0.216029124605188282, - 0.223255831633057896, - 0.234180501294209925, - 0.248557682972264071, - 0.266363809892617521 + static_cast(1.635256732264579992), + static_cast(0.471190626148732291), + static_cast(0.309728410831499587), + static_cast(0.252208311773135699), + static_cast(0.226725623219684650), + static_cast(0.215774446729585976), + static_cast(0.213108771877348910), + static_cast(0.216029124605188282), + static_cast(0.223255831633057896), + static_cast(0.234180501294209925), + static_cast(0.248557682972264071), + static_cast(0.266363809892617521) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.15); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.15)); } case 4: case 5: @@ -244,20 +244,20 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.685750354812596043, - 0.541731848613280329, - 0.401524438390690257, - 0.369642473420889090, - 0.376060715354583645, - 0.405235887085125919, - 0.453294381753999079, - 0.520518947651184205, - 0.609426039204995055, - 0.724263522282908870, - 0.871013847709812357, - 1.057652872753547036 + static_cast(1.685750354812596043), + static_cast(0.541731848613280329), + static_cast(0.401524438390690257), + static_cast(0.369642473420889090), + static_cast(0.376060715354583645), + static_cast(0.405235887085125919), + static_cast(0.453294381753999079), + static_cast(0.520518947651184205), + static_cast(0.609426039204995055), + static_cast(0.724263522282908870), + static_cast(0.871013847709812357), + static_cast(1.057652872753547036) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.25); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.25)); } case 6: case 7: @@ -265,21 +265,21 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.744350597225613243, - 0.634864275371935304, - 0.539842564164445538, - 0.571892705193787391, - 0.670295136265406100, - 0.832586590010977199, - 1.073857448247933265, - 1.422091460675497751, - 1.920387183402304829, - 2.632552548331654201, - 3.652109747319039160, - 5.115867135558865806, - 7.224080007363877411 + static_cast(1.744350597225613243), + static_cast(0.634864275371935304), + static_cast(0.539842564164445538), + static_cast(0.571892705193787391), + static_cast(0.670295136265406100), + static_cast(0.832586590010977199), + static_cast(1.073857448247933265), + static_cast(1.422091460675497751), + static_cast(1.920387183402304829), + static_cast(2.632552548331654201), + static_cast(3.652109747319039160), + static_cast(5.115867135558865806), + static_cast(7.224080007363877411) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.35); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.35)); } case 8: case 9: @@ -287,22 +287,22 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.813883936816982644, - 0.763163245700557246, - 0.761928605321595831, - 0.951074653668427927, - 1.315180671703161215, - 1.928560693477410941, - 2.937509342531378755, - 4.594894405442878062, - 7.330071221881720772, - 11.87151259742530180, - 19.45851374822937738, - 32.20638657246426863, - 53.73749198700554656, - 90.27388602940998849 + static_cast(1.813883936816982644), + static_cast(0.763163245700557246), + static_cast(0.761928605321595831), + static_cast(0.951074653668427927), + static_cast(1.315180671703161215), + static_cast(1.928560693477410941), + static_cast(2.937509342531378755), + static_cast(4.594894405442878062), + static_cast(7.330071221881720772), + static_cast(11.87151259742530180), + static_cast(19.45851374822937738), + static_cast(32.20638657246426863), + static_cast(53.73749198700554656), + static_cast(90.27388602940998849) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.45); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.45)); } case 10: case 11: @@ -310,23 +310,23 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.898924910271553526, - 0.950521794618244435, - 1.151077589959015808, - 1.750239106986300540, - 2.952676812636875180, - 5.285800396121450889, - 9.832485716659979747, - 18.78714868327559562, - 36.61468615273698145, - 72.45292395127771801, - 145.1079577347069102, - 293.4786396308497026, - 598.3851815055010179, - 1228.420013075863451, - 2536.529755382764488 + static_cast(1.898924910271553526), + static_cast(0.950521794618244435), + static_cast(1.151077589959015808), + static_cast(1.750239106986300540), + static_cast(2.952676812636875180), + static_cast(5.285800396121450889), + static_cast(9.832485716659979747), + static_cast(18.78714868327559562), + static_cast(36.61468615273698145), + static_cast(72.45292395127771801), + static_cast(145.1079577347069102), + static_cast(293.4786396308497026), + static_cast(598.3851815055010179), + static_cast(1228.420013075863451), + static_cast(2536.529755382764488) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.55); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.55)); } case 12: case 13: @@ -334,106 +334,106 @@ BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 2.007598398424376302, - 1.248457231212347337, - 1.926234657076479729, - 3.751289640087587680, - 8.119944554932045802, - 18.66572130873555361, - 44.60392484291437063, - 109.5092054309498377, - 274.2779548232413480, - 697.5598008606326163, - 1795.716014500247129, - 4668.381716790389910, - 12235.76246813664335, - 32290.17809718320818, - 85713.07608195964685, - 228672.1890493117096, - 612757.2711915852774 + static_cast(2.007598398424376302), + static_cast(1.248457231212347337), + static_cast(1.926234657076479729), + static_cast(3.751289640087587680), + static_cast(8.119944554932045802), + static_cast(18.66572130873555361), + static_cast(44.60392484291437063), + static_cast(109.5092054309498377), + static_cast(274.2779548232413480), + static_cast(697.5598008606326163), + static_cast(1795.716014500247129), + static_cast(4668.381716790389910), + static_cast(12235.76246813664335), + static_cast(32290.17809718320818), + static_cast(85713.07608195964685), + static_cast(228672.1890493117096), + static_cast(612757.2711915852774) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.65); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.65)); } case 14: case 15: - //else if (m < 0.8) + //else if (m < static_cast(0.8)) { constexpr T coef[] = { - 2.156515647499643235, - 1.791805641849463243, - 3.826751287465713147, - 10.38672468363797208, - 31.40331405468070290, - 100.9237039498695416, - 337.3268282632272897, - 1158.707930567827917, - 4060.990742193632092, - 14454.00184034344795, - 52076.66107599404803, - 189493.6591462156887, - 695184.5762413896145, - 2567994.048255284686, - 9541921.966748386322, - 35634927.44218076174, - 133669298.4612040871, - 503352186.6866284541, - 1901975729.538660119, - 7208915015.330103756 + static_cast(2.156515647499643235), + static_cast(1.791805641849463243), + static_cast(3.826751287465713147), + static_cast(10.38672468363797208), + static_cast(31.40331405468070290), + static_cast(100.9237039498695416), + static_cast(337.3268282632272897), + static_cast(1158.707930567827917), + static_cast(4060.990742193632092), + static_cast(14454.00184034344795), + static_cast(52076.66107599404803), + static_cast(189493.6591462156887), + static_cast(695184.5762413896145), + static_cast(2567994.048255284686), + static_cast(9541921.966748386322), + static_cast(35634927.44218076174), + static_cast(133669298.4612040871), + static_cast(503352186.6866284541), + static_cast(1901975729.538660119), + static_cast(7208915015.330103756) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.75); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.75)); } case 16: - //else if (m < 0.85) + //else if (m < static_cast(0.85)) { constexpr T coef[] = { - 2.318122621712510589, - 2.616920150291232841, - 7.897935075731355823, - 30.50239715446672327, - 131.4869365523528456, - 602.9847637356491617, - 2877.024617809972641, - 14110.51991915180325, - 70621.44088156540229, - 358977.2665825309926, - 1847238.263723971684, - 9600515.416049214109, - 50307677.08502366879, - 265444188.6527127967, - 1408862325.028702687, - 7515687935.373774627 + static_cast(2.318122621712510589), + static_cast(2.616920150291232841), + static_cast(7.897935075731355823), + static_cast(30.50239715446672327), + static_cast(131.4869365523528456), + static_cast(602.9847637356491617), + static_cast(2877.024617809972641), + static_cast(14110.51991915180325), + static_cast(70621.44088156540229), + static_cast(358977.2665825309926), + static_cast(1847238.263723971684), + static_cast(9600515.416049214109), + static_cast(50307677.08502366879), + static_cast(265444188.6527127967), + static_cast(1408862325.028702687), + static_cast(7515687935.373774627) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.825); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.825)); } case 17: - //else if (m < 0.90) + //else if (m < static_cast(0.90)) { constexpr T coef[] = { - 2.473596173751343912, - 3.727624244118099310, - 15.60739303554930496, - 84.12850842805887747, - 506.9818197040613935, - 3252.277058145123644, - 21713.24241957434256, - 149037.0451890932766, - 1043999.331089990839, - 7427974.817042038995, - 53503839.67558661151, - 389249886.9948708474, - 2855288351.100810619, - 21090077038.76684053, - 156699833947.7902014, - 1170222242422.439893, - 8777948323668.937971, - 66101242752484.95041, - 499488053713388.7989, - 37859743397240299.20 + static_cast(2.473596173751343912), + static_cast(3.727624244118099310), + static_cast(15.60739303554930496), + static_cast(84.12850842805887747), + static_cast(506.9818197040613935), + static_cast(3252.277058145123644), + static_cast(21713.24241957434256), + static_cast(149037.0451890932766), + static_cast(1043999.331089990839), + static_cast(7427974.817042038995), + static_cast(53503839.67558661151), + static_cast(389249886.9948708474), + static_cast(2855288351.100810619), + static_cast(21090077038.76684053), + static_cast(156699833947.7902014), + static_cast(1170222242422.439893), + static_cast(8777948323668.937971), + static_cast(66101242752484.95041), + static_cast(499488053713388.7989), + static_cast(37859743397240299.20) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.875); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.875)); } default: // diff --git a/include/boost/math/special_functions/ellint_2.hpp b/include/boost/math/special_functions/ellint_2.hpp index e135264ccf..023c5cbe4a 100644 --- a/include/boost/math/special_functions/ellint_2.hpp +++ b/include/boost/math/special_functions/ellint_2.hpp @@ -203,19 +203,19 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.550973351780472328, - -0.400301020103198524, - -0.078498619442941939, - -0.034318853117591992, - -0.019718043317365499, - -0.013059507731993309, - -0.009442372874146547, - -0.007246728512402157, - -0.005807424012956090, - -0.004809187786009338, - -0.004086399233255150 + static_cast(1.550973351780472328), + -static_cast(0.400301020103198524), + -static_cast(0.078498619442941939), + -static_cast(0.034318853117591992), + -static_cast(0.019718043317365499), + -static_cast(0.013059507731993309), + -static_cast(0.009442372874146547), + -static_cast(0.007246728512402157), + -static_cast(0.005807424012956090), + -static_cast(0.004809187786009338), + -static_cast(0.004086399233255150) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.05); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.05)); } case 2: case 3: @@ -223,19 +223,19 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.510121832092819728, - -0.417116333905867549, - -0.090123820404774569, - -0.043729944019084312, - -0.027965493064761785, - -0.020644781177568105, - -0.016650786739707238, - -0.014261960828842520, - -0.012759847429264803, - -0.011799303775587354, - -0.011197445703074968 + static_cast(1.510121832092819728), + -static_cast(0.417116333905867549), + -static_cast(0.090123820404774569), + -static_cast(0.043729944019084312), + -static_cast(0.027965493064761785), + -static_cast(0.020644781177568105), + -static_cast(0.016650786739707238), + -static_cast(0.014261960828842520), + -static_cast(0.012759847429264803), + -static_cast(0.011799303775587354), + -static_cast(0.011197445703074968) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.15); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.15)); } case 4: case 5: @@ -243,19 +243,19 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.467462209339427155, - -0.436576290946337775, - -0.105155557666942554, - -0.057371843593241730, - -0.041391627727340220, - -0.034527728505280841, - -0.031495443512532783, - -0.030527000890325277, - -0.030916984019238900, - -0.032371395314758122, - -0.034789960386404158 + static_cast(1.467462209339427155), + -static_cast(0.436576290946337775), + -static_cast(0.105155557666942554), + -static_cast(0.057371843593241730), + -static_cast(0.041391627727340220), + -static_cast(0.034527728505280841), + -static_cast(0.031495443512532783), + -static_cast(0.030527000890325277), + -static_cast(0.030916984019238900), + -static_cast(0.032371395314758122), + -static_cast(0.034789960386404158) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.25); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.25)); } case 6: case 7: @@ -263,20 +263,20 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.422691133490879171, - -0.459513519621048674, - -0.125250539822061878, - -0.078138545094409477, - -0.064714278472050002, - -0.062084339131730311, - -0.065197032815572477, - -0.072793895362578779, - -0.084959075171781003, - -0.102539850131045997, - -0.127053585157696036, - -0.160791120691274606 + static_cast(1.422691133490879171), + -static_cast(0.459513519621048674), + -static_cast(0.125250539822061878), + -static_cast(0.078138545094409477), + -static_cast(0.064714278472050002), + -static_cast(0.062084339131730311), + -static_cast(0.065197032815572477), + -static_cast(0.072793895362578779), + -static_cast(0.084959075171781003), + -static_cast(0.102539850131045997), + -static_cast(0.127053585157696036), + -static_cast(0.160791120691274606) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.35); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.35)); } case 8: case 9: @@ -284,21 +284,21 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.375401971871116291, - -0.487202183273184837, - -0.153311701348540228, - -0.111849444917027833, - -0.108840952523135768, - -0.122954223120269076, - -0.152217163962035047, - -0.200495323642697339, - -0.276174333067751758, - -0.393513114304375851, - -0.575754406027879147, - -0.860523235727239756, - -1.308833205758540162 + static_cast(1.375401971871116291), + -static_cast(0.487202183273184837), + -static_cast(0.153311701348540228), + -static_cast(0.111849444917027833), + -static_cast(0.108840952523135768), + -static_cast(0.122954223120269076), + -static_cast(0.152217163962035047), + -static_cast(0.200495323642697339), + -static_cast(0.276174333067751758), + -static_cast(0.393513114304375851), + -static_cast(0.575754406027879147), + -static_cast(0.860523235727239756), + -static_cast(1.308833205758540162) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.45); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.45)); } case 10: case 11: @@ -306,21 +306,21 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.325024497958230082, - -0.521727647557566767, - -0.194906430482126213, - -0.171623726822011264, - -0.202754652926419141, - -0.278798953118534762, - -0.420698457281005762, - -0.675948400853106021, - -1.136343121839229244, - -1.976721143954398261, - -3.531696773095722506, - -6.446753640156048150, - -11.97703130208884026 + static_cast(1.325024497958230082), + -static_cast(0.521727647557566767), + -static_cast(0.194906430482126213), + -static_cast(0.171623726822011264), + -static_cast(0.202754652926419141), + -static_cast(0.278798953118534762), + -static_cast(0.420698457281005762), + -static_cast(0.675948400853106021), + -static_cast(1.136343121839229244), + -static_cast(1.976721143954398261), + -static_cast(3.531696773095722506), + -static_cast(6.446753640156048150), + -static_cast(11.97703130208884026) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.55); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.55)); } case 12: case 13: @@ -328,23 +328,23 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.270707479650149744, - -0.566839168287866583, - -0.262160793432492598, - -0.292244173533077419, - -0.440397840850423189, - -0.774947641381397458, - -1.498870837987561088, - -3.089708310445186667, - -6.667595903381001064, - -14.89436036517319078, - -34.18120574251449024, - -80.15895841905397306, - -191.3489480762984920, - -463.5938853480342030, - -1137.380822169360061 + static_cast(1.270707479650149744), + -static_cast(0.566839168287866583), + -static_cast(0.262160793432492598), + -static_cast(0.292244173533077419), + -static_cast(0.440397840850423189), + -static_cast(0.774947641381397458), + -static_cast(1.498870837987561088), + -static_cast(3.089708310445186667), + -static_cast(6.667595903381001064), + -static_cast(14.89436036517319078), + -static_cast(34.18120574251449024), + -static_cast(80.15895841905397306), + -static_cast(191.3489480762984920), + -static_cast(463.5938853480342030), + -static_cast(1137.380822169360061) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.65); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.65)); } case 14: case 15: @@ -352,72 +352,72 @@ BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant< { constexpr T coef[] = { - 1.211056027568459525, - -0.630306413287455807, - -0.387166409520669145, - -0.592278235311934603, - -1.237555584513049844, - -3.032056661745247199, - -8.181688221573590762, - -23.55507217389693250, - -71.04099935893064956, - -221.8796853192349888, - -712.1364793277635425, - -2336.125331440396407, - -7801.945954775964673, - -26448.19586059191933, - -90799.48341621365251, - -315126.0406449163424, - -1104011.344311591159 + static_cast(1.211056027568459525), + -static_cast(0.630306413287455807), + -static_cast(0.387166409520669145), + -static_cast(0.592278235311934603), + -static_cast(1.237555584513049844), + -static_cast(3.032056661745247199), + -static_cast(8.181688221573590762), + -static_cast(23.55507217389693250), + -static_cast(71.04099935893064956), + -static_cast(221.8796853192349888), + -static_cast(712.1364793277635425), + -static_cast(2336.125331440396407), + -static_cast(7801.945954775964673), + -static_cast(26448.19586059191933), + -static_cast(90799.48341621365251), + -static_cast(315126.0406449163424), + -static_cast(1104011.344311591159) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.75); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.75)); } case 16: //else if (m < 0.85) { constexpr T coef[] = { - 1.161307152196282836, - -0.701100284555289548, - -0.580551474465437362, - -1.243693061077786614, - -3.679383613496634879, - -12.81590924337895775, - -49.25672530759985272, - -202.1818735434090269, - -869.8602699308701437, - -3877.005847313289571, - -17761.70710170939814, - -83182.69029154232061, - -396650.4505013548170, - -1920033.413682634405 + static_cast(1.161307152196282836), + -static_cast(0.701100284555289548), + -static_cast(0.580551474465437362), + -static_cast(1.243693061077786614), + -static_cast(3.679383613496634879), + -static_cast(12.81590924337895775), + -static_cast(49.25672530759985272), + -static_cast(202.1818735434090269), + -static_cast(869.8602699308701437), + -static_cast(3877.005847313289571), + -static_cast(17761.70710170939814), + -static_cast(83182.69029154232061), + -static_cast(396650.4505013548170), + -static_cast(1920033.413682634405) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.825); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.825)); } case 17: //else if (m < 0.90) { constexpr T coef[] = { - 1.124617325119752213, - -0.770845056360909542, - -0.844794053644911362, - -2.490097309450394453, - -10.23971741154384360, - -49.74900546551479866, - -267.0986675195705196, - -1532.665883825229947, - -9222.313478526091951, - -57502.51612140314030, - -368596.1167416106063, - -2415611.088701091428, - -16120097.81581656797, - -109209938.5203089915, - -749380758.1942496220, - -5198725846.725541393, - -36409256888.12139973 + static_cast(1.124617325119752213), + -static_cast(0.770845056360909542), + -static_cast(0.844794053644911362), + -static_cast(2.490097309450394453), + -static_cast(10.23971741154384360), + -static_cast(49.74900546551479866), + -static_cast(267.0986675195705196), + -static_cast(1532.665883825229947), + -static_cast(9222.313478526091951), + -static_cast(57502.51612140314030), + -static_cast(368596.1167416106063), + -static_cast(2415611.088701091428), + -static_cast(16120097.81581656797), + -static_cast(109209938.5203089915), + -static_cast(749380758.1942496220), + -static_cast(5198725846.725541393), + -static_cast(36409256888.12139973) }; - return boost::math::tools::evaluate_polynomial(coef, m - 0.875); + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.875)); } default: // diff --git a/include/boost/math/special_functions/hypergeometric_2F0.hpp b/include/boost/math/special_functions/hypergeometric_2F0.hpp index a8ebe2162e..5d6e15e271 100644 --- a/include/boost/math/special_functions/hypergeometric_2F0.hpp +++ b/include/boost/math/special_functions/hypergeometric_2F0.hpp @@ -94,7 +94,7 @@ namespace boost { namespace math { namespace detail { // http://functions.wolfram.com/07.31.03.0083.01 int n = static_cast(static_cast(boost::math::lltrunc(-2 * a1))); T smz = sqrt(-z); - return pow(2 / smz, -n) * boost::math::hermite(n, 1 / smz, pol); + return static_cast(pow(2 / smz, -n) * boost::math::hermite(n, 1 / smz, pol)); // Warning suppression: integer power returns at least a double } if (is_a1_integer && is_a2_integer) diff --git a/include/boost/math/special_functions/legendre.hpp b/include/boost/math/special_functions/legendre.hpp index 23f552dc91..6af798e0d9 100644 --- a/include/boost/math/special_functions/legendre.hpp +++ b/include/boost/math/special_functions/legendre.hpp @@ -322,7 +322,7 @@ T legendre_p_imp(int l, int m, T x, T sin_theta_power, const Policy& pol) } if (-m == l) { - return pow((1 - x * x) / 4, T(l) / 2) / boost::math::tgamma(l + 1, pol); + return pow((1 - x * x) / 4, T(l) / 2) / boost::math::tgamma(l + 1, pol); } if(m < 0) { diff --git a/include/boost/math/special_functions/owens_t.hpp b/include/boost/math/special_functions/owens_t.hpp index 152b5cbdda..a3879a71c2 100644 --- a/include/boost/math/special_functions/owens_t.hpp +++ b/include/boost/math/special_functions/owens_t.hpp @@ -993,7 +993,7 @@ namespace boost const RealType fabs_a = fabs(a); const RealType fabs_ah = fabs_a*h; - RealType val = 0.0; // avoid compiler warnings, 0.0 will be overwritten in any case + RealType val = static_cast(0.0f); // avoid compiler warnings, 0.0 will be overwritten in any case if(fabs_a <= 1) { diff --git a/include/boost/math/special_functions/zeta.hpp b/include/boost/math/special_functions/zeta.hpp index 0f3136d00f..c18d2253d4 100644 --- a/include/boost/math/special_functions/zeta.hpp +++ b/include/boost/math/special_functions/zeta.hpp @@ -956,9 +956,9 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) else if((v & 1) == 0) { if(((v / 2) <= (int)boost::math::max_bernoulli_b2n::value) && (v <= (int)boost::math::max_factorial::value)) - return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi(), v) * + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), v)) * boost::math::unchecked_bernoulli_b2n(v / 2) / boost::math::unchecked_factorial(v); - return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi(), v) * + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), v)) * boost::math::bernoulli_b2n(v / 2) / boost::math::factorial(v, pol); } else diff --git a/test/compile_test/test_promote_args.cpp b/test/compile_test/test_promote_args.cpp index c54117c131..2281aa7115 100644 --- a/test/compile_test/test_promote_args.cpp +++ b/test/compile_test/test_promote_args.cpp @@ -5,7 +5,9 @@ // or copy at http://www.boost.org/LICENSE_1_0.txt) #include +#ifndef BOOST_MATH_STANDALONE #include +#endif #include #if __has_include() @@ -16,7 +18,7 @@ int main() { using boost::math::tools::promote_args_t; -#if defined(__cpp_lib_type_trait_variable_templates) +#if defined(__cpp_lib_type_trait_variable_templates) && (__cpp_lib_type_trait_variable_templates >= 201510L) && defined(__cpp_static_assert) && (__cpp_static_assert >= 201411L) static_assert(std::is_same_v, long double>); static_assert(std::is_same_v, long double>); @@ -162,6 +164,7 @@ int main() #endif #endif +#ifndef BOOST_MATH_STANDALONE static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); @@ -177,6 +180,7 @@ int main() #ifdef __STDCPP_FLOAT128_T__ static_assert(std::is_same_v, boost::multiprecision::cpp_bin_float_50>); #endif +#endif // BOOST_MATH_STANDALONE #endif From ac8765b6e2809f01aa29455fbd8f9e69358e69f3 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 15 May 2023 20:24:52 +0200 Subject: [PATCH 15/53] Update drone to use Ubuntu 23.04 for g++13 --- .drone.star | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.star b/.drone.star index fe27f2a106..17877cc2ee 100644 --- a/.drone.star +++ b/.drone.star @@ -30,7 +30,7 @@ def main(ctx): for suite in things_to_test: for cxx in gcc13_stds: - result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2304:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) return result From fa8a83f2fbdbf91b6f501b71a5041c3c46ecadcd Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 15 May 2023 20:42:49 +0200 Subject: [PATCH 16/53] Enable testing of new floats --- .drone.star | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.star b/.drone.star index 17877cc2ee..cd1158e537 100644 --- a/.drone.star +++ b/.drone.star @@ -28,7 +28,7 @@ def main(ctx): result = [] - for suite in things_to_test: + for suite in gcc13_things_to_test: for cxx in gcc13_stds: result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2304:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) From d217813b03a41818460ff0be8f66b108aa880e27 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 11:49:30 +0200 Subject: [PATCH 17/53] Fix stack overflow on test_finite_singular_boundary with _Float64 --- .../math/quadrature/naive_monte_carlo.hpp | 27 ++++++++++++------- test/naive_monte_carlo_test.cpp | 4 ++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/boost/math/quadrature/naive_monte_carlo.hpp b/include/boost/math/quadrature/naive_monte_carlo.hpp index 78c06a02aa..4ad95ad832 100644 --- a/include/boost/math/quadrature/naive_monte_carlo.hpp +++ b/include/boost/math/quadrature/naive_monte_carlo.hpp @@ -21,6 +21,11 @@ #include #include #include +#include + +#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES +# include +#endif namespace boost { namespace math { namespace quadrature { @@ -45,6 +50,8 @@ class naive_monte_carlo { using std::numeric_limits; using std::sqrt; + using boost::math::isinf; + uint64_t n = bounds.size(); m_lbs.resize(n); m_dxs.resize(n); @@ -58,9 +65,9 @@ class naive_monte_carlo boost::math::policies::raise_domain_error(function, "The upper bound is <= the lower bound.\n", bounds[i].second, Policy()); return; } - if (bounds[i].first == -numeric_limits::infinity()) + if (isinf(bounds[i].first)) { - if (bounds[i].second == numeric_limits::infinity()) + if (isinf(bounds[i].second)) { m_limit_types[i] = detail::limit_classification::DOUBLE_INFINITE; } @@ -72,7 +79,7 @@ class naive_monte_carlo m_dxs[i] = numeric_limits::quiet_NaN(); } } - else if (bounds[i].second == numeric_limits::infinity()) + else if (isinf(bounds[i].second)) { m_limit_types[i] = detail::limit_classification::UPPER_BOUND_INFINITE; if (singular) @@ -285,17 +292,17 @@ class naive_monte_carlo m_done = false; #ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES - std::cout << "Failed to achieve required tolerance first time through..\n"; - std::cout << " variance = " << m_variance << std::endl; - std::cout << " average = " << m_avg << std::endl; - std::cout << " total calls = " << m_total_calls << std::endl; + std::cerr << "Failed to achieve required tolerance first time through..\n"; + std::cerr << " variance = " << m_variance << std::endl; + std::cerr << " average = " << m_avg << std::endl; + std::cerr << " total calls = " << m_total_calls << std::endl; for (std::size_t i = 0; i < m_num_threads; ++i) - std::cout << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl; + std::cerr << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl; for (std::size_t i = 0; i < m_num_threads; ++i) - std::cout << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl; + std::cerr << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl; for (std::size_t i = 0; i < m_num_threads; ++i) - std::cout << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl; + std::cerr << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl; #endif } diff --git a/test/naive_monte_carlo_test.cpp b/test/naive_monte_carlo_test.cpp index e9fcbb030f..54f364515f 100644 --- a/test/naive_monte_carlo_test.cpp +++ b/test/naive_monte_carlo_test.cpp @@ -168,11 +168,13 @@ void test_finite_singular_boundary() std::cout << "Testing that finite singular boundaries work on naive Monte-Carlo integration on type " << boost::typeindex::type_id().pretty_name() << "\n"; using std::pow; using std::log; + using std::log1p; + auto g = [](std::vector const & x)->Real { // The first term is singular at x = 0. // The second at x = 1: - return pow(log(1.0/x[0]), 2) + log1p(-x[0]); + return pow(log(Real(1)/x[0]), Real(2)) + log1p(-x[0]); }; vector> bounds{{Real(0), Real(1)}}; naive_monte_carlo mc(g, bounds, (Real) 0.01, true, 1, 1922); From 843363650f557eda72dbff4a915f02f8841e83d0 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 16 May 2023 13:14:08 +0100 Subject: [PATCH 18/53] Fix remaining warnings from float32.cpp. --- include/boost/math/distributions/cauchy.hpp | 2 +- .../boost/math/distributions/detail/hypergeometric_pdf.hpp | 2 +- .../special_functions/detail/hypergeometric_1F1_bessel.hpp | 6 +++--- .../boost/math/special_functions/detail/ibeta_inverse.hpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/math/distributions/cauchy.hpp b/include/boost/math/distributions/cauchy.hpp index 8588686c8f..d914cca77e 100644 --- a/include/boost/math/distributions/cauchy.hpp +++ b/include/boost/math/distributions/cauchy.hpp @@ -81,7 +81,7 @@ RealType cdf_imp(const cauchy_distribution& dist, const RealTy RealType mx = -fabs((x - location) / scale); // scale is > 0 if(mx > -tools::epsilon() / 8) { // special case first: x extremely close to location. - return 0.5; + return static_cast(0.5f); } result = -atan(1 / mx) / constants::pi(); return (((x > location) != complement) ? 1 - result : result); diff --git a/include/boost/math/distributions/detail/hypergeometric_pdf.hpp b/include/boost/math/distributions/detail/hypergeometric_pdf.hpp index 220c8d8e0c..55ec15e7d2 100644 --- a/include/boost/math/distributions/detail/hypergeometric_pdf.hpp +++ b/include/boost/math/distributions/detail/hypergeometric_pdf.hpp @@ -260,7 +260,7 @@ inline T integer_power(const T& x, int ex) #ifdef __SUNPRO_CC return pow(x, T(ex)); #else - return pow(x, ex); + return static_cast(pow(x, ex)); #endif } template diff --git a/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp b/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp index c3febc6208..bc28c5a73d 100644 --- a/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp +++ b/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp @@ -184,7 +184,7 @@ // if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) { - T rescale = pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2; + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2); if (!((boost::math::isfinite)(rescale))) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) @@ -259,7 +259,7 @@ // if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) { - T rescale = pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2; + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2); if (!((boost::math::isfinite)(rescale))) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) @@ -558,7 +558,7 @@ // if((j < cache_size - 2) && (bessel_i_cache[j + 1] != 0) && (tools::max_value() / fabs(64 * bessel_i_cache[j] / bessel_i_cache[j + 1]) < fabs(bessel_i_cache[j]))) { - T rescale = pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), j + 1) * 2; + T rescale = static_cast(pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), j + 1) * 2); if (rescale > tools::max_value()) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) diff --git a/include/boost/math/special_functions/detail/ibeta_inverse.hpp b/include/boost/math/special_functions/detail/ibeta_inverse.hpp index 79eb95c45f..be4bd95399 100644 --- a/include/boost/math/special_functions/detail/ibeta_inverse.hpp +++ b/include/boost/math/special_functions/detail/ibeta_inverse.hpp @@ -115,7 +115,7 @@ T temme_method_1_ibeta_inverse(T a, T b, T z, const Policy& pol) T c = -exp(-eta_2 / 2); T x; if(eta_2 == 0) - x = 0.5; + x = static_cast(0.5f); else x = (1 + eta * sqrt((1 + c) / eta_2)) / 2; // From 61043631b6562a61c39f95913047a67fbf271f21 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 15:02:09 +0200 Subject: [PATCH 19/53] Add float128 testing --- test/Jamfile.v2 | 1 + test/compile_test/float128.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/compile_test/float128.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ac4fdfa7cf..740d5e04d1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -906,6 +906,7 @@ test-suite distribution_tests : test-suite new_floats : [ compile compile_test/float32.cpp ] [ compile compile_test/float64.cpp ] + [ compile compile_test/float128.cpp ] ; test-suite mp : diff --git a/test/compile_test/float128.cpp b/test/compile_test/float128.cpp new file mode 100644 index 0000000000..da32e60793 --- /dev/null +++ b/test/compile_test/float128.cpp @@ -0,0 +1,32 @@ +// Copyright Matt Borland 2023. +// 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) + +#if __has_include() +# include +#endif + +#ifdef __STDCPP_FLOAT128_T__ + +#define TEST_COMPLEX + +#include "instantiate.hpp" + +int main(int argc, char* []) +{ + if(argc > 10000) + { + instantiate(0.0F128); + instantiate_mixed(0.0F128); + } +} + +#else + +int main(int, char*[]) +{ + return 0; +} + +#endif From 5045047bcdd60e6e46fea4cf0453ade0dbf7f25e Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 15:02:31 +0200 Subject: [PATCH 20/53] Use charconv instead of streaming operator for std::float128_t --- include/boost/math/policies/error_handling.hpp | 17 +++++++++++++++++ .../boost/math/special_functions/lambert_w.hpp | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/boost/math/policies/error_handling.hpp b/include/boost/math/policies/error_handling.hpp index a008157df0..c22d300d06 100644 --- a/include/boost/math/policies/error_handling.hpp +++ b/include/boost/math/policies/error_handling.hpp @@ -26,6 +26,13 @@ #include #endif +// TODO: Update as other implmentations become available +#if __GNUC__ >= 13 +# define BOOST_MATH_USE_CHARCONV_FLOAT128_T +# include +# include +#endif + #ifdef _MSC_VER # pragma warning(push) // Quiet warnings in boost/format.hpp # pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE @@ -95,6 +102,16 @@ std::string prec_format(const T& val) return ss.str(); } +#if defined(BOOST_MATH_USE_CHARCONV_FLOAT128_T) && defined(__STDCPP_FLOAT128_T__) +template <> +std::string prec_format(const std::float128_t& val) +{ + char buffer[128] {}; + const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val); + return std::string(buffer, r.ptr); +} +#endif + inline void replace_all_in_string(std::string& result, const char* what, const char* with) { std::string::size_type pos = 0; diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index 9bc5bb29fa..4669df7d21 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -1918,7 +1918,7 @@ T lambert_wm1_imp(const T z, const Policy& pol) using boost::math::policies::digits2; using boost::math::policies::policy; // Compute a 50-bit precision approximate W0 in a double (no Halley refinement). - T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_constructible()), policy>()))); + T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_convertible()), policy>()))); #ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); std::cout << "Lambert_wm1 Argument Type " << typeid(T).name() << " approximation double = " << double_approx << std::endl; From 0c1920b7fb5c06ebfabae7ae3cb41f9b1b9ac0f7 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 15:39:42 +0200 Subject: [PATCH 21/53] Move macro definitions to config --- include/boost/math/policies/error_handling.hpp | 11 +++-------- include/boost/math/tools/config.hpp | 12 +++++++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/boost/math/policies/error_handling.hpp b/include/boost/math/policies/error_handling.hpp index c22d300d06..659c779e66 100644 --- a/include/boost/math/policies/error_handling.hpp +++ b/include/boost/math/policies/error_handling.hpp @@ -26,13 +26,6 @@ #include #endif -// TODO: Update as other implmentations become available -#if __GNUC__ >= 13 -# define BOOST_MATH_USE_CHARCONV_FLOAT128_T -# include -# include -#endif - #ifdef _MSC_VER # pragma warning(push) // Quiet warnings in boost/format.hpp # pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE @@ -102,7 +95,8 @@ std::string prec_format(const T& val) return ss.str(); } -#if defined(BOOST_MATH_USE_CHARCONV_FLOAT128_T) && defined(__STDCPP_FLOAT128_T__) +#ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION + template <> std::string prec_format(const std::float128_t& val) { @@ -110,6 +104,7 @@ std::string prec_format(const std::float128_t& val) const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val); return std::string(buffer, r.ptr); } + #endif inline void replace_all_in_string(std::string& result, const char* what, const char* with) diff --git a/include/boost/math/tools/config.hpp b/include/boost/math/tools/config.hpp index a52393e7bb..ef9134a6a2 100644 --- a/include/boost/math/tools/config.hpp +++ b/include/boost/math/tools/config.hpp @@ -156,13 +156,23 @@ # endif #endif -#endif +#endif // Standalone config // If attributes are not defined make sure we don't have compiler errors #ifndef BOOST_MATH_MAYBE_UNUSED # define BOOST_MATH_MAYBE_UNUSED #endif +// C++23 +#if __cplusplus > 202002L || _MSVC_LANG > 202002L +# if __GNUC__ >= 13 +# include // std::strlen is used with from_chars +# include +# include +# define BOOST_MATH_USE_CHARCONV_FOR_CONVERSION +# endif +#endif + #include // for min and max #include #include From a0360d8f6dcb1ebe71cedcdfd16b346da28cbf89 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 15:40:01 +0200 Subject: [PATCH 22/53] Use charconv in convert_from_string for arithmetic types --- .../boost/math/tools/convert_from_string.hpp | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/include/boost/math/tools/convert_from_string.hpp b/include/boost/math/tools/convert_from_string.hpp index 4a0a25144c..f6fe08aeeb 100644 --- a/include/boost/math/tools/convert_from_string.hpp +++ b/include/boost/math/tools/convert_from_string.hpp @@ -1,4 +1,5 @@ // Copyright John Maddock 2016. +// Copyright Matt Borland 2023. // 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) @@ -10,6 +11,7 @@ #pragma once #endif +#include #include #ifndef BOOST_MATH_STANDALONE #include @@ -26,14 +28,32 @@ namespace boost{ namespace math{ namespace tools{ template Real convert_from_string(const char* p, const std::false_type&) { -#ifdef BOOST_MATH_NO_LEXICAL_CAST + #ifdef BOOST_MATH_NO_LEXICAL_CAST + // This function should not compile, we don't have the necessary functionality to support it: static_assert(sizeof(Real) == 0, "boost.lexical_cast is not supported in standalone mode."); (void)p; // Suppresses -Wunused-parameter return Real(0); -#else + + #elif defined(BOOST_MATH_USE_CHARCONV_FOR_CONVERSION) + + if constexpr (std::is_arithmetic_v) + { + Real v {}; + std::from_chars(p, p + std::strlen(p), v); + + return v; + } + else + { + return boost::lexical_cast(p); + } + + #else + return boost::lexical_cast(p); -#endif + + #endif } template constexpr const char* convert_from_string(const char* p, const std::true_type&) noexcept From edf6597b5b6c5c9c33376ec1d6790af542a998a5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 16:01:48 +0200 Subject: [PATCH 23/53] inline template specialization --- include/boost/math/policies/error_handling.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/math/policies/error_handling.hpp b/include/boost/math/policies/error_handling.hpp index 659c779e66..d5e30c08f3 100644 --- a/include/boost/math/policies/error_handling.hpp +++ b/include/boost/math/policies/error_handling.hpp @@ -82,7 +82,7 @@ namespace detail { template -std::string prec_format(const T& val) +inline std::string prec_format(const T& val) { typedef typename boost::math::policies::precision >::type prec_type; std::stringstream ss; @@ -98,7 +98,7 @@ std::string prec_format(const T& val) #ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION template <> -std::string prec_format(const std::float128_t& val) +inline std::string prec_format(const std::float128_t& val) { char buffer[128] {}; const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val); From 55eaf05b4191381310b6663f3b8243f503723980 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 May 2023 16:02:14 +0200 Subject: [PATCH 24/53] Add additional conversion function for C++23 types --- .../math/special_functions/lambert_w.hpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index 4669df7d21..945a45895c 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -48,6 +48,7 @@ BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS // Show evaluation of //] [/boost_math_instrument_lambert_w_macros] */ +#include #include #include #include @@ -184,7 +185,25 @@ template inline double must_reduce_to_double(const T& z, const std::false_type&) { // try a lexical_cast and hope for the best: #ifndef BOOST_MATH_STANDALONE + + #ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION + + // Catches the C++23 floating point types + if constexpr (std::is_arithmetic_v) + { + return static_cast(z); + } + else + { + return boost::lexical_cast(z); + } + + #else + return boost::lexical_cast(z); + + #endif + #else static_assert(sizeof(T) == 0, "Unsupported in standalone mode: don't know how to cast your number type to a double."); return 0.0; @@ -1918,7 +1937,7 @@ T lambert_wm1_imp(const T z, const Policy& pol) using boost::math::policies::digits2; using boost::math::policies::policy; // Compute a 50-bit precision approximate W0 in a double (no Halley refinement). - T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_convertible()), policy>()))); + T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_constructible()), policy>()))); #ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); std::cout << "Lambert_wm1 Argument Type " << typeid(T).name() << " approximation double = " << double_approx << std::endl; From 00facdc1a9bf0e76ebbb7bfeca3eb24c03ad9025 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 May 2023 18:10:49 +0200 Subject: [PATCH 25/53] Fix cardinal cubic b spline for std::float32_t --- .../detail/cardinal_cubic_b_spline_detail.hpp | 2 +- test/cardinal_cubic_b_spline_test.cpp | 194 ++++++++++-------- 2 files changed, 109 insertions(+), 87 deletions(-) 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 22491a70a4..2064caa515 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 9dcef343b2..90452d6e5d 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(); } From f86ea8e88c6b32c540b4d3a55b362627494c030d Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 May 2023 18:48:37 +0200 Subject: [PATCH 26/53] Begin adding interpolator tests --- test/gegenbauer_test.cpp | 62 +++++++++++++++-------- test/jacobi_test.cpp | 49 +++++++++++++----- test/test_barycentric_rational.cpp | 61 +++++++++++++++------- test/test_vector_barycentric_rational.cpp | 20 ++++++++ 4 files changed, 142 insertions(+), 50 deletions(-) diff --git a/test/gegenbauer_test.cpp b/test/gegenbauer_test.cpp index aa684cea8f..7349bfe675 100644 --- a/test/gegenbauer_test.cpp +++ b/test/gegenbauer_test.cpp @@ -17,6 +17,10 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif + using std::abs; using boost::math::gegenbauer; using boost::math::gegenbauer_derivative; @@ -26,7 +30,7 @@ void test_parity() { std::mt19937 gen(323723); std::uniform_real_distribution xdis(-1, +1); - std::uniform_real_distribution lambdadis(-0.5, 1); + std::uniform_real_distribution lambdadis(Real(-0.5), 1); for(unsigned n = 0; n < 50; ++n) { unsigned calls = 50; @@ -79,7 +83,7 @@ void test_cubic() template void test_derivative() { - Real lambda = 0.5; + Real lambda = Real(0.5); auto c3_prime = [&](Real x) { return 2*lambda*(lambda+1)*(-1 + 2*(lambda+2)*x*x); }; auto c3_double_prime = [&](Real x) { return 8*lambda*(lambda+1)*(lambda+2)*x; }; Real x = -1; @@ -102,33 +106,51 @@ void test_derivative() int main() { - test_parity(); - test_parity(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_parity(); -#endif + #ifdef __STDCPP_FLOAT32_T__ + test_parity(); + test_quadratic(); + test_derivative(); + + #else + + test_parity(); test_quadratic(); - test_quadratic(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_quadratic(); -#endif + test_derivative(); - test_cubic(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_cubic(); -#endif + #endif - test_derivative(); + #ifdef __STDCPP_FLOAT64_T__ + + test_parity(); + test_quadratic(); + test_cubic(); + test_derivative(); + + #else + + test_parity(); + test_quadratic(); + test_cubic(); test_derivative(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + + #endif + + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + + test_parity(); + test_quadratic(); + test_cubic(); test_derivative(); -#endif + + #endif -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 + test_quadratic(); test_cubic(); -#endif + + #endif return boost::math::test::report_errors(); } diff --git a/test/jacobi_test.cpp b/test/jacobi_test.cpp index cb994cd040..e6c85ec98f 100644 --- a/test/jacobi_test.cpp +++ b/test/jacobi_test.cpp @@ -16,6 +16,10 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif + using std::abs; using boost::math::jacobi; using boost::math::jacobi_derivative; @@ -95,28 +99,47 @@ void test_derivative() int main() { - test_to_quadratic(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_to_quadratic(); -#endif + #ifdef __STDCPP_FLOAT32_T__ + + test_symmetry(); + test_derivative(); - test_symmetry(); - test_symmetry(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_symmetry(); -#endif + #else + test_symmetry(); test_derivative(); + + #endif + + #ifdef __STDCPP_FLOAT64_T__ + + test_to_quadratic(); + test_symmetry(); + test_derivative(); + + #else + + test_to_quadratic(); + test_symmetry(); test_derivative(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + + #endif + + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + + test_to_quadratic(); + test_symmetry(); test_derivative(); -#endif + + #endif -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 + test_to_quadratic(); test_symmetry(); test_derivative(); -#endif + + #endif return boost::math::test::report_errors(); } diff --git a/test/test_barycentric_rational.cpp b/test/test_barycentric_rational.cpp index 226877004c..f131f6995b 100644 --- a/test/test_barycentric_rational.cpp +++ b/test/test_barycentric_rational.cpp @@ -19,6 +19,10 @@ #include #endif +#if __has_include() +# include +#endif + using std::sqrt; using std::abs; using std::numeric_limits; @@ -258,30 +262,53 @@ BOOST_AUTO_TEST_CASE(barycentric_rational) // The tests took too long at the higher precisions. // They still pass, but the CI system is starting to time out, // so I figured it'd be polite to comment out the most expensive tests. - test_weights(); - + + #ifdef __STDCPP_FLOAT32_T__ + + test_constant(); + //test_constant_high_order(); + test_interpolation_condition(); + //test_interpolation_condition_high_order(); + + #else + test_constant(); - //test_constant(); - test_constant(); - //test_constant(); - //test_constant_high_order(); - test_constant_high_order(); - //test_constant_high_order(); - //test_constant_high_order(); - test_interpolation_condition(); - test_interpolation_condition(); - //test_interpolation_condition(); - //test_interpolation_condition(); - //test_interpolation_condition_high_order(); + + #endif + + #ifdef __STDCPP_FLOAT64_T__ + + test_weights(); + //test_constant(); + test_constant_high_order(); + test_interpolation_condition(); + test_interpolation_condition_high_order(); + test_runge(); + + #else + + test_weights(); + //test_constant(); + test_constant_high_order(); + test_interpolation_condition(); test_interpolation_condition_high_order(); - //test_interpolation_condition_high_order(); - //test_interpolation_condition_high_order(); - test_runge(); + + #endif + + test_constant(); + //test_constant_high_order(); + //test_interpolation_condition(); + //test_interpolation_condition_high_order(); //test_runge(); + + //test_constant(); + //test_constant_high_order(); + //test_interpolation_condition(); + //test_interpolation_condition_high_order(); //test_runge(); #ifdef BOOST_HAS_FLOAT128 diff --git a/test/test_vector_barycentric_rational.cpp b/test/test_vector_barycentric_rational.cpp index f8050d2427..1a58a454e9 100644 --- a/test/test_vector_barycentric_rational.cpp +++ b/test/test_vector_barycentric_rational.cpp @@ -18,6 +18,10 @@ #include #include +#if __has_include() +# include +#endif + using std::sqrt; using std::abs; using std::numeric_limits; @@ -373,6 +377,20 @@ void test_weights() BOOST_AUTO_TEST_CASE(vector_barycentric_rational) { + #ifdef __STDCPP_FLOAT64_T__ + + test_weights(); + test_constant_eigen(); + test_constant_std_array(); + test_constant_high_order(); + test_interpolation_condition_eigen(); + test_interpolation_condition_ublas(); + test_interpolation_condition_std_array(); + test_interpolation_condition_high_order(); + test_agreement_with_1d(); + + #else + test_weights(); test_constant_eigen(); test_constant_std_array(); @@ -382,4 +400,6 @@ BOOST_AUTO_TEST_CASE(vector_barycentric_rational) test_interpolation_condition_std_array(); test_interpolation_condition_high_order(); test_agreement_with_1d(); + + #endif } From 41be4fb71d5fa1dd7512db8deada49a8501ad351 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 21 May 2023 16:12:58 +0100 Subject: [PATCH 27/53] Improve to/from_chars configuration. --- include/boost/math/tools/config.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/math/tools/config.hpp b/include/boost/math/tools/config.hpp index ef9134a6a2..66e7da52ab 100644 --- a/include/boost/math/tools/config.hpp +++ b/include/boost/math/tools/config.hpp @@ -166,10 +166,14 @@ // C++23 #if __cplusplus > 202002L || _MSVC_LANG > 202002L # if __GNUC__ >= 13 + // libstdc++3 only defines to/from_chars for std::float128_t when one of these defines are set + // otherwise we're right out of luck... +# if defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) || defined(_GLIBCXX_HAVE_FLOAT128_MATH) # include // std::strlen is used with from_chars # include # include # define BOOST_MATH_USE_CHARCONV_FOR_CONVERSION +#endif # endif #endif From 51d7011f25d9c58f1ae91b7de231943053de7a48 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 11:42:39 +0200 Subject: [PATCH 28/53] Fix formatting and missing header --- .../special_functions/daubechies_scaling.hpp | 277 +++++++++--------- 1 file changed, 139 insertions(+), 138 deletions(-) diff --git a/include/boost/math/special_functions/daubechies_scaling.hpp b/include/boost/math/special_functions/daubechies_scaling.hpp index 069b35a0ed..cbf03f092d 100644 --- a/include/boost/math/special_functions/daubechies_scaling.hpp +++ b/include/boost/math/special_functions/daubechies_scaling.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -21,10 +22,10 @@ #include #ifndef BOOST_MATH_STANDALONE -#include -#ifdef BOOST_NO_CXX17_IF_CONSTEXPR -#error "The header can only be used in C++17 and later." -#endif +# include +# ifdef BOOST_NO_CXX17_IF_CONSTEXPR +# error "The header can only be used in C++17 and later." +# endif #endif namespace boost::math { @@ -274,170 +275,170 @@ class linear_interpolation_aos { template struct daubechies_eval_type { - typedef T type; + using type = T; - static const std::vector& vector_cast(const std::vector& v) { return v; } + static const std::vector& vector_cast(const std::vector& v) { return v; } }; template <> struct daubechies_eval_type { - typedef double type; - - inline static std::vector vector_cast(const std::vector& v) - { - std::vector result(v.size()); - for (unsigned i = 0; i < v.size(); ++i) - result[i] = static_cast(v[i]); - return result; - } + using type = double; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } }; template <> struct daubechies_eval_type { - typedef long double type; - - inline static std::vector vector_cast(const std::vector& v) - { - std::vector result(v.size()); - for (unsigned i = 0; i < v.size(); ++i) - result[i] = static_cast(v[i]); - return result; - } + using type = long double; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } }; struct null_interpolator { - template - T operator()(const T&) - { - return 1; - } + template + T operator()(const T&) + { + return 1; + } }; } // namespace detail template class daubechies_scaling { - // - // Some type manipulation so we know the type of the interpolator, and the vector type it requires: - // - typedef std::vector> vector_type; - // - // List our interpolators: - // - typedef std::tuple< - detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, - interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, - interpolators::detail::cardinal_septic_hermite_detail_aos > interpolator_list; - // - // Select the one we need: - // - typedef std::tuple_element_t< - p == 1 ? 0 : - p == 2 ? 1 : - p == 3 ? 2 : - p <= 5 ? 3 : - p <= 9 ? 4 : 5, interpolator_list> interpolator_type; + // + // Some type manipulation so we know the type of the interpolator, and the vector type it requires: + // + using vector_type = std::vector>; + // + // List our interpolators: + // + using interpolator_list = std::tuple< + detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, + interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, + interpolators::detail::cardinal_septic_hermite_detail_aos >; + // + // Select the one we need: + // + using interpolator_type = std::tuple_element_t< + p == 1 ? 0 : + p == 2 ? 1 : + p == 3 ? 2 : + p <= 5 ? 3 : + p <= 9 ? 4 : 5, interpolator_list>; public: - daubechies_scaling(int grid_refinements = -1) - { - static_assert(p < 20, "Daubechies scaling functions are only implemented for p < 20."); - static_assert(p > 0, "Daubechies scaling functions must have at least 1 vanishing moment."); - if constexpr (p == 1) - { - return; - } - else { - if (grid_refinements < 0) - { - if (std::is_same_v) - { - if (grid_refinements == -2) - { - // Control absolute error: - // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 - std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; - grid_refinements = r[p]; - } - else - { - // Control relative error: - // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 - std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; - grid_refinements = r[p]; - } - } - else if (std::is_same_v) - { - // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 - std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; - grid_refinements = r[p]; - } - else + daubechies_scaling(int grid_refinements = -1) + { + static_assert(p < 20, "Daubechies scaling functions are only implemented for p < 20."); + static_assert(p > 0, "Daubechies scaling functions must have at least 1 vanishing moment."); + if constexpr (p == 1) + { + return; + } + else { + if (grid_refinements < 0) { - grid_refinements = 21; + if (std::is_same_v) + { + if (grid_refinements == -2) + { + // Control absolute error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; + grid_refinements = r[p]; + } + else + { + // Control relative error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; + grid_refinements = r[p]; + } + } + else if (std::is_same_v) + { + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; + } + else + { + grid_refinements = 21; + } } - } - - // Compute the refined grid: - // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. - std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { - // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: - auto v = daubechies_scaling_dyadic_grid::type, p, 0>(grid_refinements); - return detail::daubechies_eval_type::vector_cast(v); - }); - // Compute the derivative of the refined grid: - std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { - auto v = daubechies_scaling_dyadic_grid::type, p, 1>(grid_refinements); - return detail::daubechies_eval_type::vector_cast(v); - }); - - // if necessary, compute the second and third derivative: - std::vector d2ydx2; - std::vector d3ydx3; - if constexpr (p >= 6) { - std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { - auto v = daubechies_scaling_dyadic_grid::type, p, 2>(grid_refinements); - return detail::daubechies_eval_type::vector_cast(v); - }); - - if constexpr (p >= 10) { - std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { - auto v = daubechies_scaling_dyadic_grid::type, p, 3>(grid_refinements); - return detail::daubechies_eval_type::vector_cast(v); - }); - d3ydx3 = t4.get(); + + // Compute the refined grid: + // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. + std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { + // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: + auto v = daubechies_scaling_dyadic_grid::type, p, 0>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + // Compute the derivative of the refined grid: + std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 1>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + // if necessary, compute the second and third derivative: + std::vector d2ydx2; + std::vector d3ydx3; + if constexpr (p >= 6) { + std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 2>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + if constexpr (p >= 10) { + std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 3>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + d3ydx3 = t4.get(); + } + d2ydx2 = t3.get(); } - d2ydx2 = t3.get(); - } - auto y = t0.get(); - auto dydx = t1.get(); + auto y = t0.get(); + auto dydx = t1.get(); - if constexpr (p >= 2) - { - vector_type data(y.size()); - for (size_t i = 0; i < y.size(); ++i) + if constexpr (p >= 2) { - data[i][0] = y[i]; - data[i][1] = dydx[i]; - if constexpr (p >= 6) - data[i][2] = d2ydx2[i]; - if constexpr (p >= 10) - data[i][3] = d3ydx3[i]; + vector_type data(y.size()); + for (size_t i = 0; i < y.size(); ++i) + { + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; + } + if constexpr (p <= 3) + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); + else + m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); } - if constexpr (p <= 3) - m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); else - m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); - } - else - m_interpolator = std::make_shared(); - } - } + m_interpolator = std::make_shared(); + } + } inline Real operator()(Real x) const { @@ -475,7 +476,7 @@ class daubechies_scaling { int64_t bytes() const { - return m_interpolator->bytes() + sizeof(m_interpolator); + return m_interpolator->bytes() + sizeof(m_interpolator); } private: From c4c8c6936ada5b2bca00a92bdfd5c4b82cadd173 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 12:59:18 +0200 Subject: [PATCH 29/53] Add wavelet transform test with additional casts --- test/wavelet_transform_test.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/wavelet_transform_test.cpp b/test/wavelet_transform_test.cpp index 7a0fa16480..c49090957a 100644 --- a/test/wavelet_transform_test.cpp +++ b/test/wavelet_transform_test.cpp @@ -19,6 +19,10 @@ #include #include +#if __has_include() +# include +#endif + #ifdef BOOST_HAS_FLOAT128 #include using boost::multiprecision::float128; @@ -118,7 +122,7 @@ void test_wavelet_transform() for (double t = -10; t < 10; t+= 0.1) { Real w = Wg(s, t); - if (!CHECK_LE(abs(w), 10*sqrt(std::numeric_limits::epsilon()))) + if (!CHECK_LE(abs(w), Real(10*sqrt(std::numeric_limits::epsilon())))) { std::cerr << " Wavelet transform of constant with respect to " << p << " vanishing moment Daubechies wavelet is insufficiently small\n"; } @@ -127,7 +131,7 @@ void test_wavelet_transform() } // Wavelet transform of psi evaluated at s = 1, t = 0 is L2 norm of psi: auto Wpsi = daubechies_wavelet_transform(psi, psi); - CHECK_MOLLIFIED_CLOSE(Real(1), Wpsi(1,0), 2*sqrt(std::numeric_limits::epsilon())); + CHECK_MOLLIFIED_CLOSE(Real(1), Wpsi(1,0), Real(2*sqrt(std::numeric_limits::epsilon()))); } } @@ -135,9 +139,15 @@ void test_wavelet_transform() int main() { try{ + #ifdef __STDCPP_FLOAT64_T__ + test_wavelet_transform(); + test_wavelet_transform(); + test_wavelet_transform(); + #else test_wavelet_transform(); test_wavelet_transform(); test_wavelet_transform(); + #endif // All these tests pass, but the compilation takes too long on CI: //boost::hana::for_each(std::make_index_sequence<17>(), [&](auto i) { // test_wavelet_transform(); From aef57135b3bc4fd1136691b2b68e6bf2ba4cb2f7 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 13:08:10 +0200 Subject: [PATCH 30/53] Add rsqrt test and update type traits for control path --- .../boost/math/special_functions/rsqrt.hpp | 10 ++++---- test/rsqrt_test.cpp | 25 +++++++++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/boost/math/special_functions/rsqrt.hpp b/include/boost/math/special_functions/rsqrt.hpp index 438d16fb0c..fec6468e28 100644 --- a/include/boost/math/special_functions/rsqrt.hpp +++ b/include/boost/math/special_functions/rsqrt.hpp @@ -11,10 +11,10 @@ #include #ifndef BOOST_MATH_STANDALONE -#include -#ifdef BOOST_NO_CXX17_IF_CONSTEXPR -#error "The header can only be used in C++17 and later." -#endif +# include +# ifdef BOOST_NO_CXX17_IF_CONSTEXPR +# error "The header can only be used in C++17 and later." +# endif #endif namespace boost::math { @@ -23,7 +23,7 @@ template inline Real rsqrt(Real const & x) { using std::sqrt; - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + if constexpr (std::is_arithmetic_v && !std::is_integral_v) { return 1/sqrt(x); } diff --git a/test/rsqrt_test.cpp b/test/rsqrt_test.cpp index f41402f150..53852289c4 100644 --- a/test/rsqrt_test.cpp +++ b/test/rsqrt_test.cpp @@ -13,6 +13,11 @@ #include #include #include + +#if __has_include() +# include +#endif + #ifdef BOOST_HAS_FLOAT128 #include using boost::multiprecision::float128; @@ -27,7 +32,7 @@ void test_rsqrt() using std::sqrt; Real x = (std::numeric_limits::min)(); while (x < 10000*std::numeric_limits::epsilon()) { - Real expected = 1/sqrt(x); + Real expected = Real(1)/sqrt(x); Real computed = rsqrt(x); if(!CHECK_ULP_CLOSE(expected, computed, 2)) { std::cerr << " 1/sqrt(" << x << ") is computed incorrectly.\n"; @@ -38,7 +43,7 @@ void test_rsqrt() // x ~ 1: x = 1; while (x < 1 + 1000*std::numeric_limits::epsilon()) { - Real expected = 1/sqrt(x); + Real expected = Real(1)/sqrt(x); Real computed = rsqrt(x); if(!CHECK_ULP_CLOSE(expected, computed, 2)) { std::cerr << " 1/sqrt(" << x << ") is computed incorrectly.\n"; @@ -49,7 +54,7 @@ void test_rsqrt() // x ~ 1000: x = 1000; while (x < 1000 + 1000*1000*std::numeric_limits::epsilon()) { - Real expected = 1/sqrt(x); + Real expected = Real(1)/sqrt(x); Real computed = rsqrt(x); if(!CHECK_ULP_CLOSE(expected, computed, 2)) { std::cerr << " 1/sqrt(" << x << ") is computed incorrectly.\n"; @@ -58,14 +63,14 @@ void test_rsqrt() } x = std::numeric_limits::infinity(); - Real expected = 1/sqrt(x); + Real expected = Real(1)/sqrt(x); Real computed = rsqrt(x); if (!CHECK_ULP_CLOSE(expected, computed, 0)) { std::cerr << "Reciprocal square root of infinity not correctly computed.\n"; } x = (std::numeric_limits::max)(); - expected = 1/sqrt(x); + expected = Real(1)/sqrt(x); computed = rsqrt(x); if (!CHECK_EQUAL(expected, computed)) { std::cerr << "Reciprocal square root of std::numeric_limits::max() not correctly computed.\n"; @@ -79,8 +84,18 @@ void test_rsqrt() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_rsqrt(); + #else test_rsqrt(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_rsqrt(); + #else test_rsqrt(); + #endif + test_rsqrt(); test_rsqrt(); test_rsqrt(); From ca31dcfe93efd6d46d578968a28dd4754340612c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 13:43:32 +0200 Subject: [PATCH 31/53] Add AGM test --- .../special_functions/daubechies_scaling.hpp | 34 +++++++++++-------- test/agm_test.cpp | 22 ++++++++++-- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/boost/math/special_functions/daubechies_scaling.hpp b/include/boost/math/special_functions/daubechies_scaling.hpp index cbf03f092d..40de7b5acf 100644 --- a/include/boost/math/special_functions/daubechies_scaling.hpp +++ b/include/boost/math/special_functions/daubechies_scaling.hpp @@ -7,9 +7,12 @@ #ifndef BOOST_MATH_SPECIAL_DAUBECHIES_SCALING_HPP #define BOOST_MATH_SPECIAL_DAUBECHIES_SCALING_HPP + +#include +#include +#include #include #include -#include #include #include #include @@ -208,12 +211,13 @@ class linear_interpolation { inline Real prime(Real x) const { using std::floor; + Real y = x*s_; Real k = floor(y); int64_t kk = static_cast(k); Real t = y - k; - return (1-t)*dydx_[kk] + t*dydx_[kk+1]; + return static_cast((Real(1)-t)*dydx_[kk] + t*dydx_[kk+1]); } int64_t bytes() const @@ -372,13 +376,13 @@ class daubechies_scaling { } else if (std::is_same_v) { - // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 - std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; - grid_refinements = r[p]; + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; } else { - grid_refinements = 21; + grid_refinements = 21; } } @@ -423,17 +427,17 @@ class daubechies_scaling { vector_type data(y.size()); for (size_t i = 0; i < y.size(); ++i) { - data[i][0] = y[i]; - data[i][1] = dydx[i]; - if constexpr (p >= 6) - data[i][2] = d2ydx2[i]; - if constexpr (p >= 10) - data[i][3] = d3ydx3[i]; + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; } if constexpr (p <= 3) - m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); else - m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); + m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); } else m_interpolator = std::make_shared(); @@ -452,7 +456,7 @@ class daubechies_scaling { inline Real prime(Real x) const { static_assert(p > 2, "The 3-vanishing moment Daubechies scaling function is the first which is continuously differentiable."); - if (x <= 0 || x >= 2*p-1) + if (x <= Real(0) || x >= 2*p-1) { return 0; } diff --git a/test/agm_test.cpp b/test/agm_test.cpp index 6013d5cdbf..623a6d88e8 100644 --- a/test/agm_test.cpp +++ b/test/agm_test.cpp @@ -13,6 +13,11 @@ #include #include #include + +#if __has_include() +# include +#endif + #ifdef BOOST_HAS_FLOAT128 #include using boost::multiprecision::float128; @@ -91,13 +96,24 @@ void test_scaling() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_gauss_constant(); + test_scaling(); + #else test_gauss_constant(); - test_gauss_constant(); - test_gauss_constant(); - test_scaling(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_scaling(); + test_gauss_constant(); + #else test_scaling(); + test_gauss_constant(); + #endif + test_scaling(); + test_gauss_constant(); #ifdef BOOST_HAS_FLOAT128 test_gauss_constant(); From faaf4759aca2db615269caf725006695775ff20c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 13:48:33 +0200 Subject: [PATCH 32/53] Fix stack overflow in cohen acceleration from GCC bug --- .../boost/math/tools/cohen_acceleration.hpp | 7 +++--- test/cohen_acceleration_test.cpp | 22 ++++++++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/boost/math/tools/cohen_acceleration.hpp b/include/boost/math/tools/cohen_acceleration.hpp index 716245f724..2e76a75f8b 100644 --- a/include/boost/math/tools/cohen_acceleration.hpp +++ b/include/boost/math/tools/cohen_acceleration.hpp @@ -23,17 +23,18 @@ auto cohen_acceleration(G& generator, std::int64_t n = -1) using std::pow; using std::ceil; using std::sqrt; + auto n_ = static_cast(n); if (n < 0) { // relative error grows as 2*5.828^-n; take 5.828^-n < eps/4 => -nln(5.828) < ln(eps/4) => n > ln(4/eps)/ln(5.828). // Is there a way to do it rapidly with std::log2? (Yes, of course; but for primitive types it's computed at compile-time anyway.) - n_ = static_cast(ceil(log(4/std::numeric_limits::epsilon())*0.5672963285532555)); + n_ = static_cast(ceil(log(Real(4)/std::numeric_limits::epsilon())*Real(0.5672963285532555))); n = static_cast(n_); } // d can get huge and overflow if you pick n too large: - auto d = static_cast(pow(3 + sqrt(Real(8)), n)); - d = (d + 1/d)/2; + auto d = static_cast(pow(Real(3 + sqrt(Real(8))), n_)); + d = (d + Real(1)/d)/2; Real b = -1; Real c = -d; Real s = 0; diff --git a/test/cohen_acceleration_test.cpp b/test/cohen_acceleration_test.cpp index f300bdad6a..ad70c3f825 100644 --- a/test/cohen_acceleration_test.cpp +++ b/test/cohen_acceleration_test.cpp @@ -15,6 +15,10 @@ using boost::multiprecision::float128; #include #include +#if __has_include() +# include +#endif + using boost::math::tools::cohen_acceleration; using boost::multiprecision::cpp_bin_float_100; using boost::math::constants::pi; @@ -72,17 +76,29 @@ void test_divergent() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_pisq_div12(); + test_divergent(); + #else test_pisq_div12(); - test_pisq_div12(); - test_pisq_div12(); - test_divergent(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_pisq_div12(); + test_divergent(); + #else test_divergent(); + test_pisq_div12(); + #endif + test_divergent(); + test_pisq_div12(); #ifdef BOOST_HAS_FLOAT128 test_pisq_div12(); test_divergent(); #endif + return boost::math::test::report_errors(); } From ebcc43091fa4c0191b7a8b95925ee19b96e890fb Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 13:52:25 +0200 Subject: [PATCH 33/53] Add casting to whittaker shannon for conversion rank errors --- test/whittaker_shannon_test.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/test/whittaker_shannon_test.cpp b/test/whittaker_shannon_test.cpp index 605b2694ac..0ca97daaec 100644 --- a/test/whittaker_shannon_test.cpp +++ b/test/whittaker_shannon_test.cpp @@ -12,6 +12,10 @@ #include #include +#if __has_include() +# include +#endif + using boost::math::interpolators::whittaker_shannon; template @@ -19,7 +23,7 @@ void test_trivial() { Real t0 = 0; Real h = Real(1)/Real(16); - std::vector v{1.5}; + std::vector v{Real(1.5)}; std::vector v_copy = v; auto ws = whittaker_shannon(std::move(v), t0, h); @@ -43,7 +47,7 @@ void test_knots() size_t n = 512; std::vector v(n); std::mt19937 gen(323723); - std::uniform_real_distribution dis(1.0, 2.0); + std::uniform_real_distribution dis(Real(1.0), Real(2.0)); for(size_t i = 0; i < n; ++i) { v[i] = static_cast(dis(gen)); @@ -125,21 +129,32 @@ void test_bump() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_trivial(); + test_knots(); + #else + test_trivial(); test_knots(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_trivial(); + test_knots(); + test_bump(); + #else + test_trivial(); test_knots(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_knots(); -#endif - test_bump(); + #endif + + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + test_knots(); #if LDBL_MANT_DIG <= 64 // Anything more precise than this fails for unknown reasons test_bump(); #endif #endif - test_trivial(); - test_trivial(); return boost::math::test::report_errors(); } From d1bd7b6f804533c592ede25ca988b6f914b1e59c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 22 May 2023 14:50:12 +0200 Subject: [PATCH 34/53] Add casting and tests --- test/bezier_polynomial_test.cpp | 57 +++++++++++----- test/bilinear_uniform_test.cpp | 20 +++++- test/cardinal_quadratic_b_spline_test.cpp | 45 ++++++++----- test/cardinal_quintic_b_spline_test.cpp | 79 ++++++++++++----------- test/catmull_rom_test.cpp | 72 ++++++++++++++------- test/cubic_hermite_test.cpp | 55 +++++++++++----- test/makima_test.cpp | 26 ++++++-- test/pchip_test.cpp | 34 +++++++--- test/quintic_hermite_test.cpp | 77 +++++++++++++++------- test/septic_hermite_test.cpp | 65 ++++++++++++------- 10 files changed, 366 insertions(+), 164 deletions(-) diff --git a/test/bezier_polynomial_test.cpp b/test/bezier_polynomial_test.cpp index 4e7a11748c..05ee13ecf8 100644 --- a/test/bezier_polynomial_test.cpp +++ b/test/bezier_polynomial_test.cpp @@ -18,14 +18,18 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif + using boost::math::interpolators::bezier_polynomial; template void test_linear() { std::vector> control_points(2); - control_points[0] = {0.0, 0.0}; - control_points[1] = {1.0, 1.0}; + control_points[0] = {Real(0), Real(0)}; + control_points[1] = {Real(1), Real(1)}; auto control_points_copy = control_points; auto bp = bezier_polynomial(std::move(control_points_copy)); @@ -54,9 +58,9 @@ template void test_quadratic() { std::vector> control_points(3); - control_points[0] = {0.0, 0.0}; - control_points[1] = {1.0, 1.0}; - control_points[2] = {2.0, 2.0}; + control_points[0] = {Real(0), Real(0)}; + control_points[1] = {Real(1), Real(1)}; + control_points[2] = {Real(2), Real(2)}; auto control_points_copy = control_points; auto bp = bezier_polynomial(std::move(control_points_copy)); @@ -79,10 +83,10 @@ template void test_convex_hull() { std::vector> control_points(4); - control_points[0] = {0.0, 0.0}; - control_points[1] = {0.0, 1.0}; - control_points[2] = {1.0, 1.0}; - control_points[3] = {1.0, 0.0}; + control_points[0] = {Real(0), Real(0)}; + control_points[1] = {Real(0), Real(1)}; + control_points[2] = {Real(1), Real(1)}; + control_points[3] = {Real(1), Real(0)}; auto bp = bezier_polynomial(std::move(control_points)); for (Real t = 0; t <= 1; t += Real(1)/32) { @@ -133,9 +137,9 @@ void test_reversal_symmetry() CHECK_ULP_CLOSE(control_points.back()[1], P1[1], 3); CHECK_ULP_CLOSE(control_points.back()[2], P1[2], 3); - for (Real t = 0; t <= 1; t += 1.0) { + for (Real t = 0; t <= 1; t += Real(1.0)) { auto P0 = bp0(t); - auto P1 = bp1(1.0-t); + auto P1 = bp1(Real(1.0)-t); if (!CHECK_ULP_CLOSE(P0[0], P1[0], 3)) { std::cerr << " Error at t = " << t << "\n"; } @@ -184,21 +188,40 @@ void test_linear_precision() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_linear(); + test_quadratic(); + test_convex_hull(); + test_linear_precision(); + test_reversal_symmetry(); + #else test_linear(); - test_linear(); test_quadratic(); - test_quadratic(); test_convex_hull(); - test_convex_hull(); test_linear_precision(); - test_linear_precision(); test_reversal_symmetry(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_linear(); + test_quadratic(); + test_convex_hull(); + test_linear_precision(); + test_reversal_symmetry(); + #else + test_linear(); + test_quadratic(); + test_convex_hull(); + test_linear_precision(); test_reversal_symmetry(); -#ifdef BOOST_HAS_FLOAT128 + #endif + + #ifdef BOOST_HAS_FLOAT128 test_linear(); test_quadratic(); test_convex_hull(); -#endif + #endif + return boost::math::test::report_errors(); } diff --git a/test/bilinear_uniform_test.cpp b/test/bilinear_uniform_test.cpp index fb1d3d502e..f592c1a84a 100644 --- a/test/bilinear_uniform_test.cpp +++ b/test/bilinear_uniform_test.cpp @@ -16,6 +16,10 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif + using boost::math::interpolators::bilinear_uniform; template @@ -25,7 +29,7 @@ void test_four_values() Real y0 = 0; Real dx = 1; Real dy = 1; - Real value = 1.5; + Real value = Real(1.5); std::vector v(2*2, value); auto v_copy = v; auto ub = bilinear_uniform(std::move(v_copy), 2, 2, dx, dy, x0, y0); @@ -101,9 +105,21 @@ void test_linear() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_four_values(); + #else test_four_values(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_four_values(); + test_linear(); + #else test_four_values(); - test_four_values(); test_linear(); + #endif + + test_four_values(); + return boost::math::test::report_errors(); } diff --git a/test/cardinal_quadratic_b_spline_test.cpp b/test/cardinal_quadratic_b_spline_test.cpp index 6f9637d242..3955d4f572 100644 --- a/test/cardinal_quadratic_b_spline_test.cpp +++ b/test/cardinal_quadratic_b_spline_test.cpp @@ -6,15 +6,22 @@ */ #include "math_unit_test.hpp" +#include #include #include +#include +#include #include using boost::math::interpolators::cardinal_quadratic_b_spline; +#if __has_include() +# include +#endif + template void test_constant() { - Real c = 7.2; + Real c = Real(7.2); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 512; @@ -44,8 +51,8 @@ void test_constant() template void test_linear() { - Real m = 8.3; - Real b = 7.2; + Real m = Real(8.3); + Real b = Real(7.2); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 512; @@ -79,9 +86,9 @@ void test_linear() template void test_quadratic() { - Real a = 8.2; - Real b = 7.2; - Real c = -9.2; + Real a = Real(8.2); + Real b = Real(7.2); + Real c = Real(-9.2); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 513; @@ -115,21 +122,29 @@ void test_quadratic() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + #else test_constant(); - test_constant(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_constant(); -#endif - test_linear(); - test_linear(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_linear(); -#endif + #endif + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_quadratic(); + #else + test_constant(); + test_linear(); test_quadratic(); + #endif + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + test_constant(); + test_linear(); test_quadratic(); #endif + return boost::math::test::report_errors(); } diff --git a/test/cardinal_quintic_b_spline_test.cpp b/test/cardinal_quintic_b_spline_test.cpp index de2d87f15d..7ab3a28924 100644 --- a/test/cardinal_quintic_b_spline_test.cpp +++ b/test/cardinal_quintic_b_spline_test.cpp @@ -6,8 +6,11 @@ */ #include "math_unit_test.hpp" +#include #include #include +#include +#include #include #ifdef BOOST_HAS_FLOAT128 #include @@ -15,10 +18,14 @@ using boost::multiprecision::float128; #endif using boost::math::interpolators::cardinal_quintic_b_spline; +#if __has_include() +# include +#endif + template void test_constant() { - Real c = 7.5; + Real c = Real(7.5); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 513; @@ -53,7 +60,7 @@ void test_constant() template void test_constant_estimate_derivatives() { - Real c = 7.5; + Real c = Real(7.5); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 513; @@ -88,8 +95,8 @@ template void test_linear() { using std::abs; - Real m = 8.3; - Real b = 7.2; + Real m = Real(8.3); + Real b = Real(7.2); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 512; @@ -137,8 +144,8 @@ template void test_linear_estimate_derivatives() { using std::abs; - Real m = 8.3; - Real b = 7.2; + Real m = Real(8.3); + Real b = Real(7.2); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 512; @@ -186,8 +193,8 @@ template void test_quadratic() { Real a = Real(1)/Real(16); - Real b = -3.5; - Real c = -9; + Real b = Real(-3.5); + Real c = Real(-9); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 513; @@ -229,8 +236,8 @@ template void test_quadratic_estimate_derivatives() { Real a = Real(1)/Real(16); - Real b = -3.5; - Real c = -9; + Real b = Real(-3.5); + Real c = Real(-9); Real t0 = 0; Real h = Real(1)/Real(16); size_t n = 513; @@ -266,41 +273,41 @@ void test_quadratic_estimate_derivatives() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_linear(); + #else + test_linear(); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_constant_estimate_derivatives(); + test_linear_estimate_derivatives(); + test_quadratic(); + test_quadratic_estimate_derivatives(); + #else test_constant(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_constant(); -#endif - + test_linear(); test_constant_estimate_derivatives(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - test_constant_estimate_derivatives(); -#endif + test_linear_estimate_derivatives(); + test_quadratic(); + test_quadratic_estimate_derivatives(); + #endif - test_linear(); - test_linear(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + test_constant(); + test_constant_estimate_derivatives(); test_linear(); -#endif - - test_linear_estimate_derivatives(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_linear_estimate_derivatives(); -#endif - - test_quadratic(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_quadratic(); -#endif - - test_quadratic_estimate_derivatives(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_quadratic_estimate_derivatives(); -#endif + #endif #ifdef BOOST_HAS_FLOAT128 - test_constant(); - test_linear(); - test_linear_estimate_derivatives(); + test_constant(); + test_linear(); + test_linear_estimate_derivatives(); #endif return boost::math::test::report_errors(); diff --git a/test/catmull_rom_test.cpp b/test/catmull_rom_test.cpp index 8648b16869..71ea96dc43 100644 --- a/test/catmull_rom_test.cpp +++ b/test/catmull_rom_test.cpp @@ -18,6 +18,10 @@ #include #include +#if __has_include() +# include +#endif + using std::abs; using boost::multiprecision::cpp_bin_float_50; using boost::math::catmull_rom; @@ -158,7 +162,7 @@ void test_circle() } Real max_s = circle.max_parameter(); - for(Real s = 0; s < max_s; s += 0.01) + for(Real s = 0; s < max_s; s += Real(0.01)) { auto p = circle(s); Real x = p[0]; @@ -259,11 +263,11 @@ void test_helix() Real y = p[1]; if (abs(x) < tol) { - BOOST_CHECK_SMALL(cos(t), tol); + BOOST_CHECK_SMALL(Real(cos(t)), tol); } if (abs(y) < tol) { - BOOST_CHECK_SMALL(sin(t), tol); + BOOST_CHECK_SMALL(Real(sin(t)), tol); } else { @@ -282,16 +286,16 @@ void test_helix() BOOST_CHECK_CLOSE_FRACTION(x*x+y*y, (Real) 1, (Real) 0.01); if (abs(x) < 0.01) { - BOOST_CHECK_SMALL(cos(t), (Real) 0.05); + BOOST_CHECK_SMALL(Real(cos(t)), (Real) 0.05); } if (abs(y) < 0.01) { - BOOST_CHECK_SMALL(sin(t), (Real) 0.05); + BOOST_CHECK_SMALL(Real(sin(t)), (Real) 0.05); } else { - BOOST_CHECK_CLOSE_FRACTION(x, cos(t), (Real) 0.05); - BOOST_CHECK_CLOSE_FRACTION(y, sin(t), (Real) 0.05); + BOOST_CHECK_CLOSE_FRACTION(x, Real(cos(t)), (Real) 0.05); + BOOST_CHECK_CLOSE_FRACTION(y, Real(sin(t)), (Real) 0.05); } } } @@ -344,18 +348,18 @@ template void test_data_representations() { std::cout << "Testing that the Catmull-Rom spline works with multiple data representations.\n"; - mypoint3d p0(0.1, 0.2, 0.3); - mypoint3d p1(0.2, 0.3, 0.4); - mypoint3d p2(0.3, 0.4, 0.5); - mypoint3d p3(0.4, 0.5, 0.6); - mypoint3d p4(0.5, 0.6, 0.7); - mypoint3d p5(0.6, 0.7, 0.8); + mypoint3d p0(Real(0.1), Real(0.2), Real(0.3)); + mypoint3d p1(Real(0.2), Real(0.3), Real(0.4)); + mypoint3d p2(Real(0.3), Real(0.4), Real(0.5)); + mypoint3d p3(Real(0.4), Real(0.5), Real(0.6)); + mypoint3d p4(Real(0.5), Real(0.6), Real(0.7)); + mypoint3d p5(Real(0.6), Real(0.7), Real(0.8)); // Tests initializer_list: catmull_rom> cat({p0, p1, p2, p3, p4, p5}); - Real tol = 0.001; + Real tol = Real(0.001); auto p = cat(cat.parameter_at_point(0)); BOOST_CHECK_CLOSE_FRACTION(p[0], p0[0], tol); BOOST_CHECK_CLOSE_FRACTION(p[1], p0[1], tol); @@ -388,7 +392,7 @@ void test_random_access_container() // Tests initializer_list: catmull_rom, decltype(u)> cat(std::move(u)); - Real tol = 0.001; + Real tol = Real(0.001); auto p = cat(cat.parameter_at_point(0)); BOOST_CHECK_CLOSE_FRACTION(p[0], p0[0], tol); BOOST_CHECK_CLOSE_FRACTION(p[1], p0[1], tol); @@ -402,27 +406,51 @@ void test_random_access_container() BOOST_AUTO_TEST_CASE(catmull_rom_test) { #if !defined(TEST) || (TEST == 1) + + #ifdef __STDCPP_FLOAT32_T__ + test_circle(); + test_data_representations(); + #else + test_circle(); test_data_representations(); - test_alpha_distance(); + #endif + #ifdef __STDCPP_FLOAT64_T__ + test_alpha_distance(); + test_linear(); + test_circle(); + #else + test_alpha_distance(); test_linear(); -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + test_circle(); + #endif + + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_linear(); -#endif + #endif - test_circle(); - test_circle(); #endif + #if !defined(TEST) || (TEST == 2) - test_helix(); + #ifdef __STDCPP_FLOAT64_T__ + test_helix(); + test_affine_invariance(); + test_affine_invariance(); + test_affine_invariance(); + test_affine_invariance(); + test_random_access_container(); + #else + test_helix(); test_affine_invariance(); test_affine_invariance(); test_affine_invariance(); test_affine_invariance(); - test_random_access_container(); + #endif + #endif + #if !defined(TEST) || (TEST == 3) test_affine_invariance(); #endif diff --git a/test/cubic_hermite_test.cpp b/test/cubic_hermite_test.cpp index a8ded39904..ec515c2914 100644 --- a/test/cubic_hermite_test.cpp +++ b/test/cubic_hermite_test.cpp @@ -19,6 +19,9 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif using boost::math::interpolators::cubic_hermite; using boost::math::interpolators::cardinal_cubic_hermite; @@ -74,7 +77,7 @@ void test_constant() auto circular_hermite_spline = cubic_hermite(std::move(x_buf), std::move(y_buf), std::move(dydx_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), circular_hermite_spline(t), 2); CHECK_ULP_CLOSE(Real(0), circular_hermite_spline.prime(t), 2); } @@ -117,7 +120,7 @@ void test_linear() y_copy = y; dydx_copy = dydx; hermite_spline = cubic_hermite(std::move(x_copy), std::move(y_copy), std::move(dydx_copy)); - for (Real t = 0; t < x.back(); t += 0.5) { + for (Real t = 0; t < x.back(); t += Real(0.5)) { CHECK_ULP_CLOSE(t, hermite_spline(t), 0); CHECK_ULP_CLOSE(Real(1), hermite_spline.prime(t), 0); } @@ -139,7 +142,7 @@ void test_linear() auto circular_hermite_spline = cubic_hermite(std::move(x_buf), std::move(y_buf), std::move(dydx_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(t, circular_hermite_spline(t), 2); CHECK_ULP_CLOSE(Real(1), circular_hermite_spline.prime(t), 2); } @@ -156,7 +159,7 @@ void test_quadratic() { std::vector x(50); std::default_random_engine rd; - std::uniform_real_distribution dis(0.1,1); + std::uniform_real_distribution dis(Real(0.1), Real(1)); Real x0 = dis(rd); x[0] = x0; for (size_t i = 1; i < x.size(); ++i) { @@ -172,7 +175,7 @@ void test_quadratic() } auto s = cubic_hermite(std::move(x), std::move(y), std::move(dydx)); - for (Real t = x0; t <= xmax; t+= 0.0125) + for (Real t = x0; t <= xmax; t+= Real(0.0125)) { CHECK_ULP_CLOSE(t*t/2, s(t), 5); CHECK_ULP_CLOSE(t, s.prime(t), 138); @@ -223,7 +226,7 @@ void test_cardinal_constant() auto hermite_spline = cardinal_cubic_hermite(std::move(y), std::move(dydx), x0, dx); - for (Real t = x0; t <= x0 + 24*dx; t += 0.25) { + for (Real t = x0; t <= x0 + 24*dx; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), hermite_spline(t), 2); CHECK_ULP_CLOSE(Real(0), hermite_spline.prime(t), 2); } @@ -237,7 +240,7 @@ void test_cardinal_constant() } auto hermite_spline_aos = cardinal_cubic_hermite_aos(std::move(data), x0, dx); - for (Real t = x0; t <= x0 + 24*dx; t += 0.25) { + for (Real t = x0; t <= x0 + 24*dx; t += Real(0.25)) { if (!CHECK_ULP_CLOSE(Real(7), hermite_spline_aos(t), 2)) { std::cerr << " Wrong evaluation at t = " << t << "\n"; } @@ -297,7 +300,7 @@ void test_cardinal_linear() } hermite_spline = cardinal_cubic_hermite(std::move(y), std::move(dydx), x0, dx); - for (Real t = 0; t < 44; t += 0.5) { + for (Real t = 0; t < 44; t += Real(0.5)) { CHECK_ULP_CLOSE(t, hermite_spline(t), 0); CHECK_ULP_CLOSE(Real(1), hermite_spline.prime(t), 0); } @@ -309,7 +312,7 @@ void test_cardinal_linear() } auto hermite_spline_aos = cardinal_cubic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t < 44; t += 0.5) { + for (Real t = 0; t < 44; t += Real(0.5)) { CHECK_ULP_CLOSE(t, hermite_spline_aos(t), 0); CHECK_ULP_CLOSE(Real(1), hermite_spline_aos.prime(t), 0); } @@ -352,7 +355,7 @@ void test_cardinal_quadratic() } auto s = cardinal_cubic_hermite(std::move(y), std::move(dydx), x0, dx); - for (Real t = x0; t <= x0 + 49*dx; t+= 0.0125) + for (Real t = x0; t <= x0 + 49*dx; t+= Real(0.0125)) { CHECK_ULP_CLOSE(t*t/2, s(t), 12); CHECK_ULP_CLOSE(t, s.prime(t), 70); @@ -367,7 +370,7 @@ void test_cardinal_quadratic() auto saos = cardinal_cubic_hermite_aos(std::move(data), x0, dx); - for (Real t = x0; t <= x0 + 49*dx; t+= 0.0125) + for (Real t = x0; t <= x0 + 49*dx; t+= Real(0.0125)) { CHECK_ULP_CLOSE(t*t/2, saos(t), 12); CHECK_ULP_CLOSE(t, saos.prime(t), 70); @@ -400,7 +403,7 @@ void test_cardinal_interpolation_condition() std::vector y(n); std::vector dydx(n); std::default_random_engine rd; - std::uniform_real_distribution dis(0.1,1); + std::uniform_real_distribution dis(Real(0.1), Real(1)); Real x0 = Real(2); Real dx = Real(1)/Real(128); for (size_t i = 0; i < n; ++i) { @@ -422,6 +425,16 @@ void test_cardinal_interpolation_condition() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_interpolation_condition(); + test_cardinal_constant(); + test_cardinal_linear(); + test_cardinal_quadratic(); + test_cardinal_interpolation_condition(); + #else test_constant(); test_linear(); test_quadratic(); @@ -430,7 +443,18 @@ int main() test_cardinal_linear(); test_cardinal_quadratic(); test_cardinal_interpolation_condition(); - + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_interpolation_condition(); + test_cardinal_constant(); + test_cardinal_linear(); + test_cardinal_quadratic(); + test_cardinal_interpolation_condition(); + #else test_constant(); test_linear(); test_quadratic(); @@ -439,6 +463,7 @@ int main() test_cardinal_linear(); test_cardinal_quadratic(); test_cardinal_interpolation_condition(); + #endif test_constant(); test_linear(); @@ -450,12 +475,12 @@ int main() test_cardinal_interpolation_condition(); -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 test_constant(); test_linear(); test_cardinal_constant(); test_cardinal_linear(); -#endif + #endif return boost::math::test::report_errors(); } diff --git a/test/makima_test.cpp b/test/makima_test.cpp index dac617eaea..393c15da3a 100644 --- a/test/makima_test.cpp +++ b/test/makima_test.cpp @@ -16,6 +16,9 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif using boost::math::interpolators::makima; @@ -33,7 +36,7 @@ void test_constant() auto y_copy = y; auto akima = makima(std::move(x_copy), std::move(y_copy)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), akima(t), 2); CHECK_ULP_CLOSE(Real(0), akima.prime(t), 2); } @@ -50,7 +53,7 @@ void test_constant() auto circular_akima = makima(std::move(x_buf), std::move(y_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), circular_akima(t), 2); CHECK_ULP_CLOSE(Real(0), akima.prime(t), 2); } @@ -88,7 +91,7 @@ void test_linear() x_copy = x; y_copy = y; akima = makima(std::move(x_copy), std::move(y_copy)); - for (Real t = 0; t < x.back(); t += 0.5) { + for (Real t = 0; t < x.back(); t += Real(0.5)) { CHECK_ULP_CLOSE(t, akima(t), 0); CHECK_ULP_CLOSE(Real(1), akima.prime(t), 0); } @@ -97,7 +100,7 @@ void test_linear() y_copy = y; // Test endpoint derivatives: akima = makima(std::move(x_copy), std::move(y_copy), Real(1), Real(1)); - for (Real t = 0; t < x.back(); t += 0.5) { + for (Real t = 0; t < x.back(); t += Real(0.5)) { CHECK_ULP_CLOSE(t, akima(t), 0); CHECK_ULP_CLOSE(Real(1), akima.prime(t), 0); } @@ -115,7 +118,7 @@ void test_linear() auto circular_akima = makima(std::move(x_buf), std::move(y_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(t, circular_akima(t), 2); CHECK_ULP_CLOSE(Real(1), circular_akima.prime(t), 2); } @@ -166,13 +169,26 @@ void test_interpolation_condition() int main() { #if (__GNUC__ > 7) || defined(_MSC_VER) || defined(__clang__) + + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + test_interpolation_condition(); + #else test_constant(); test_linear(); test_interpolation_condition(); + #endif + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_interpolation_condition(); + #else test_constant(); test_linear(); test_interpolation_condition(); + #endif test_constant(); test_linear(); diff --git a/test/pchip_test.cpp b/test/pchip_test.cpp index 17db19a332..6e8ea235bf 100644 --- a/test/pchip_test.cpp +++ b/test/pchip_test.cpp @@ -17,6 +17,9 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif using boost::math::interpolators::pchip; @@ -35,7 +38,7 @@ void test_constant() auto pchip_spline = pchip(std::move(x_copy), std::move(y_copy)); //std::cout << "Constant value pchip spline = " << pchip_spline << "\n"; - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), pchip_spline(t), 2); CHECK_ULP_CLOSE(Real(0), pchip_spline.prime(t), 2); } @@ -52,7 +55,7 @@ void test_constant() auto circular_pchip_spline = pchip(std::move(x_buf), std::move(y_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), circular_pchip_spline(t), 2); CHECK_ULP_CLOSE(Real(0), pchip_spline.prime(t), 2); } @@ -90,7 +93,7 @@ void test_linear() x_copy = x; y_copy = y; pchip_spline = pchip(std::move(x_copy), std::move(y_copy)); - for (Real t = 0; t < x.back(); t += 0.5) { + for (Real t = 0; t < x.back(); t += Real(0.5)) { CHECK_ULP_CLOSE(t, pchip_spline(t), 0); CHECK_ULP_CLOSE(Real(1), pchip_spline.prime(t), 0); } @@ -99,7 +102,7 @@ void test_linear() y_copy = y; // Test endpoint derivatives: pchip_spline = pchip(std::move(x_copy), std::move(y_copy), Real(1), Real(1)); - for (Real t = 0; t < x.back(); t += 0.5) { + for (Real t = 0; t < x.back(); t += Real(0.5)) { CHECK_ULP_CLOSE(t, pchip_spline(t), 0); CHECK_ULP_CLOSE(Real(1), pchip_spline.prime(t), 0); } @@ -117,7 +120,7 @@ void test_linear() auto circular_pchip_spline = pchip(std::move(x_buf), std::move(y_buf)); - for (Real t = x[0]; t <= x.back(); t += 0.25) { + for (Real t = x[0]; t <= x.back(); t += Real(0.25)) { CHECK_ULP_CLOSE(t, circular_pchip_spline(t), 2); CHECK_ULP_CLOSE(Real(1), circular_pchip_spline.prime(t), 2); } @@ -230,25 +233,40 @@ void test_monotonicity() int main() { #if (__GNUC__ > 7) || defined(_MSC_VER) || defined(__clang__) + + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + test_interpolation_condition(); + test_monotonicity(); + #else test_constant(); test_linear(); test_interpolation_condition(); test_monotonicity(); - + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_interpolation_condition(); + test_monotonicity(); + #else test_constant(); test_linear(); test_interpolation_condition(); test_monotonicity(); + #endif test_constant(); test_linear(); test_interpolation_condition(); test_monotonicity(); -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 test_constant(); test_linear(); -#endif + #endif #endif return boost::math::test::report_errors(); } diff --git a/test/quintic_hermite_test.cpp b/test/quintic_hermite_test.cpp index 5dfb1f5270..d2deec7709 100644 --- a/test/quintic_hermite_test.cpp +++ b/test/quintic_hermite_test.cpp @@ -20,6 +20,9 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif using boost::math::interpolators::quintic_hermite; using boost::math::interpolators::cardinal_quintic_hermite; @@ -38,7 +41,7 @@ void test_constant() } auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = 0; t <= 81; t += 0.25) + for (Real t = 0; t <= 81; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), qh(t), 24); CHECK_ULP_CLOSE(Real(0), qh.prime(t), 24); @@ -57,7 +60,7 @@ void test_linear() auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = 0; t <= 9; t += 0.25) + for (Real t = 0; t <= 9; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(t), qh(t), 2); CHECK_ULP_CLOSE(Real(1), qh.prime(t), 2); @@ -65,7 +68,7 @@ void test_linear() } boost::random::mt19937 rng; - boost::random::uniform_real_distribution dis(0.5,1); + boost::random::uniform_real_distribution dis(Real(0.5), Real(1)); x.resize(512); x[0] = dis(rng); Real xmin = x[0]; @@ -81,7 +84,7 @@ void test_linear() qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = xmin; t <= xmax; t += 0.125) + for (Real t = xmin; t <= xmax; t += Real(0.125)) { CHECK_ULP_CLOSE(t, qh(t), 2); CHECK_ULP_CLOSE(Real(1), qh.prime(t), 100); @@ -109,7 +112,7 @@ void test_quadratic() auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { CHECK_ULP_CLOSE(Real(t*t)/2, qh(t), 2); CHECK_ULP_CLOSE(t, qh.prime(t), 12); @@ -117,7 +120,7 @@ void test_quadratic() } boost::random::mt19937 rng; - boost::random::uniform_real_distribution dis(0.5,1); + boost::random::uniform_real_distribution dis(Real(0.5), Real(1)); x.resize(8); x[0] = dis(rng); Real xmin = x[0]; @@ -143,7 +146,7 @@ void test_quadratic() qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = xmin; t <= xmax; t += 0.125) + for (Real t = xmin; t <= xmax; t += Real(0.125)) { CHECK_ULP_CLOSE(Real(t*t)/2, qh(t), 4); CHECK_ULP_CLOSE(t, qh.prime(t), 53); @@ -175,7 +178,7 @@ void test_cubic() auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t, qh(t), 10); CHECK_ULP_CLOSE(3*t*t, qh.prime(t), 15); @@ -208,7 +211,7 @@ void test_quartic() auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2)); - for (Real t = 1; t <= 11; t += 0.0078125) + for (Real t = 1; t <= 11; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t*t, qh(t), 100); CHECK_ULP_CLOSE(4*t*t*t, qh.prime(t), 100); @@ -266,7 +269,7 @@ void test_cardinal_constant() auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx); - for (Real t = x0; t <= x0 + 24*dx; t += 0.25) + for (Real t = x0; t <= x0 + 24*dx; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), qh(t), 24); CHECK_ULP_CLOSE(Real(0), qh.prime(t), 24); @@ -282,7 +285,7 @@ void test_cardinal_constant() } auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx); - for (Real t = x0; t <= x0 + 24*dx; t += 0.25) + for (Real t = x0; t <= x0 + 24*dx; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), qh_aos(t), 24); CHECK_ULP_CLOSE(Real(0), qh_aos.prime(t), 24); @@ -321,7 +324,7 @@ void test_cardinal_linear() auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx); - for (Real t = 0; t <= 9; t += 0.25) { + for (Real t = 0; t <= 9; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(t), qh(t), 2); CHECK_ULP_CLOSE(Real(1), qh.prime(t), 2); CHECK_ULP_CLOSE(Real(0), qh.double_prime(t), 2); @@ -336,7 +339,7 @@ void test_cardinal_linear() auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= 9; t += 0.25) { + for (Real t = 0; t <= 9; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(t), qh_aos(t), 2); CHECK_ULP_CLOSE(Real(1), qh_aos.prime(t), 2); CHECK_ULP_CLOSE(Real(0), qh_aos.double_prime(t), 2); @@ -382,7 +385,7 @@ void test_cardinal_quadratic() auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx); - for (Real t = 0; t <= 9; t += 0.0078125) { + for (Real t = 0; t <= 9; t += Real(0.0078125)) { Real computed = qh(t); CHECK_ULP_CLOSE(Real(t*t)/2, computed, 2); CHECK_ULP_CLOSE(t, qh.prime(t), 15); @@ -397,7 +400,7 @@ void test_cardinal_quadratic() } auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { Real computed = qh_aos(t); CHECK_ULP_CLOSE(Real(t*t)/2, computed, 2); @@ -448,7 +451,7 @@ void test_cardinal_cubic() auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { Real computed = qh(t); CHECK_ULP_CLOSE(t*t*t, computed, 10); @@ -464,7 +467,7 @@ void test_cardinal_cubic() } auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { Real computed = qh_aos(t); CHECK_ULP_CLOSE(t*t*t, computed, 10); @@ -496,7 +499,7 @@ void test_cardinal_quartic() auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx); - for (Real t = 0; t <= 6; t += 0.0078125) + for (Real t = 0; t <= 6; t += Real(0.0078125)) { CHECK_ULP_CLOSE(Real(t*t*t*t), qh(t), 250); CHECK_ULP_CLOSE(4*t*t*t, qh.prime(t), 250); @@ -511,7 +514,7 @@ void test_cardinal_quartic() } auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= 6; t += 0.0078125) + for (Real t = 0; t <= 6; t += Real(0.0078125)) { Real computed = qh_aos(t); CHECK_ULP_CLOSE(t*t*t*t, computed, 10); @@ -523,6 +526,20 @@ void test_cardinal_quartic() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_cubic(); + test_quartic(); + test_interpolation_condition(); + + test_cardinal_constant(); + test_cardinal_linear(); + test_cardinal_quadratic(); + test_cardinal_cubic(); + test_cardinal_quartic(); + #else test_constant(); test_linear(); test_quadratic(); @@ -535,7 +552,22 @@ int main() test_cardinal_quadratic(); test_cardinal_cubic(); test_cardinal_quartic(); - + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_cubic(); + test_quartic(); + test_interpolation_condition(); + + test_cardinal_constant(); + test_cardinal_linear(); + test_cardinal_quadratic(); + test_cardinal_cubic(); + test_cardinal_quartic(); + #else test_constant(); test_linear(); test_quadratic(); @@ -548,6 +580,7 @@ int main() test_cardinal_quadratic(); test_cardinal_cubic(); test_cardinal_quartic(); + #endif test_constant(); test_linear(); @@ -562,7 +595,7 @@ int main() test_cardinal_cubic(); test_cardinal_quartic(); -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 test_constant(); //test_linear(); test_quadratic(); @@ -574,7 +607,7 @@ int main() test_cardinal_quadratic(); test_cardinal_cubic(); test_cardinal_quartic(); -#endif + #endif return boost::math::test::report_errors(); } diff --git a/test/septic_hermite_test.cpp b/test/septic_hermite_test.cpp index a7bd81f9df..119e626191 100644 --- a/test/septic_hermite_test.cpp +++ b/test/septic_hermite_test.cpp @@ -18,6 +18,9 @@ using boost::multiprecision::float128; #endif +#if __has_include() +# include +#endif using boost::math::interpolators::septic_hermite; using boost::math::interpolators::cardinal_septic_hermite; @@ -39,7 +42,7 @@ void test_constant() auto sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = 0; t <= 81; t += 0.25) + for (Real t = 0; t <= 81; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), sh(t), 24); CHECK_ULP_CLOSE(Real(0), sh.prime(t), 24); @@ -52,7 +55,7 @@ void test_constant() d2ydx2.resize(128, 0); d3ydx3.resize(128, 0); auto csh = cardinal_septic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx); - for (Real t = x0; t <= 127; t += 0.25) + for (Real t = x0; t <= 127; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), csh(t), 24); CHECK_ULP_CLOSE(Real(0), csh.prime(t), 24); @@ -68,7 +71,7 @@ void test_constant() data[i][3] = 0; } auto csh_aos = cardinal_septic_hermite_aos(std::move(data), x0, dx); - for (Real t = x0; t <= 127; t += 0.25) + for (Real t = x0; t <= 127; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(7), csh_aos(t), 24); CHECK_ULP_CLOSE(Real(0), csh_aos.prime(t), 24); @@ -112,14 +115,14 @@ void test_linear() auto sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = 0; t <= 9; t += 0.25) + for (Real t = 0; t <= 9; t += Real(0.25)) { CHECK_ULP_CLOSE(Real(t), sh(t), 2); CHECK_ULP_CLOSE(Real(1), sh.prime(t), 2); } boost::random::mt19937 rng; - boost::random::uniform_real_distribution dis(0.5,1); + boost::random::uniform_real_distribution dis(Real(0.5), Real(1)); x.resize(512); x[0] = dis(rng); Real xmin = x[0]; @@ -136,7 +139,7 @@ void test_linear() sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = xmin; t <= xmax; t += 0.125) + for (Real t = xmin; t <= xmax; t += Real(0.125)) { CHECK_ULP_CLOSE(t, sh(t), 25); CHECK_ULP_CLOSE(Real(1), sh.prime(t), 850); @@ -153,7 +156,7 @@ void test_linear() y[i] = i; } auto csh = cardinal_septic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx); - for (Real t = 0; t <= 9; t += 0.125) + for (Real t = 0; t <= 9; t += Real(0.125)) { CHECK_ULP_CLOSE(t, csh(t), 15); CHECK_ULP_CLOSE(Real(1), csh.prime(t), 15); @@ -169,7 +172,7 @@ void test_linear() data[i][3] = 0; } auto csh_aos = cardinal_septic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= 9; t += 0.125) + for (Real t = 0; t <= 9; t += Real(0.125)) { CHECK_ULP_CLOSE(t, csh_aos(t), 15); CHECK_ULP_CLOSE(Real(1), csh_aos.prime(t), 15); @@ -222,14 +225,14 @@ void test_quadratic() auto sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = 0; t <= 9; t += 0.0078125) + for (Real t = 0; t <= 9; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t/2, sh(t), 100); CHECK_ULP_CLOSE(t, sh.prime(t), 32); } boost::random::mt19937 rng; - boost::random::uniform_real_distribution dis(0.5,1); + boost::random::uniform_real_distribution dis(Real(0.5), Real(1)); x.resize(8); x[0] = dis(rng); Real xmin = x[0]; @@ -256,7 +259,7 @@ void test_quadratic() sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = xmin; t <= xmax; t += 0.125) + for (Real t = xmin; t <= xmax; t += Real(0.125)) { CHECK_ULP_CLOSE(t*t/2, sh(t), 50); CHECK_ULP_CLOSE(t, sh.prime(t), 300); @@ -280,7 +283,7 @@ void test_quadratic() Real x0 = 0; Real dx = 1; auto csh = cardinal_septic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx); - for (Real t = x0; t <= 9; t += 0.125) + for (Real t = x0; t <= 9; t += Real(0.125)) { CHECK_ULP_CLOSE(t*t/2, csh(t), 24); CHECK_ULP_CLOSE(t, csh.prime(t), 24); @@ -296,7 +299,7 @@ void test_quadratic() data[i][3] = 0; } auto csh_aos = cardinal_septic_hermite_aos(std::move(data), x0, dx); - for (Real t = x0; t <= 9; t += 0.125) + for (Real t = x0; t <= 9; t += Real(0.125)) { CHECK_ULP_CLOSE(t*t/2, csh_aos(t), 24); CHECK_ULP_CLOSE(t, csh_aos.prime(t), 24); @@ -333,7 +336,7 @@ void test_cubic() auto sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = 0; t <= xmax; t += 0.0078125) + for (Real t = 0; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t, sh(t), 151); CHECK_ULP_CLOSE(3*t*t, sh.prime(t), 151); @@ -354,7 +357,7 @@ void test_cubic() auto csh = cardinal_septic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx); - for (Real t = 0; t <= xmax; t += 0.0078125) + for (Real t = 0; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t, csh(t), 151); CHECK_ULP_CLOSE(3*t*t, csh.prime(t), 151); @@ -371,7 +374,7 @@ void test_cubic() auto csh_aos = cardinal_septic_hermite_aos(std::move(data), x0, dx); - for (Real t = 0; t <= xmax; t += 0.0078125) + for (Real t = 0; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t, csh_aos(t), 151); CHECK_ULP_CLOSE(3*t*t, csh_aos.prime(t), 151); @@ -411,7 +414,7 @@ void test_quartic() auto sh = septic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3)); - for (Real t = 1; t <= xmax; t += 0.0078125) { + for (Real t = 1; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t*t, sh(t), 117); CHECK_ULP_CLOSE(4*t*t*t, sh.prime(t), 117); } @@ -430,7 +433,7 @@ void test_quartic() auto csh = cardinal_septic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), Real(0), Real(1)); - for (Real t = 1; t <= xmax; t += 0.0078125) + for (Real t = 1; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t*t, csh(t), 117); CHECK_ULP_CLOSE(4*t*t*t, csh.prime(t), 117); @@ -447,7 +450,7 @@ void test_quartic() } auto csh_aos = cardinal_septic_hermite_aos(std::move(data), Real(0), Real(1)); - for (Real t = 1; t <= xmax; t += 0.0078125) + for (Real t = 1; t <= xmax; t += Real(0.0078125)) { CHECK_ULP_CLOSE(t*t*t*t, csh_aos(t), 117); CHECK_ULP_CLOSE(4*t*t*t, csh_aos.prime(t), 117); @@ -496,19 +499,37 @@ void test_interpolation_condition() int main() { + #ifdef __STDCPP_FLOAT32_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_cubic(); + test_quartic(); + test_interpolation_condition(); + #else test_constant(); test_linear(); test_quadratic(); test_cubic(); test_quartic(); test_interpolation_condition(); - + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_constant(); + test_linear(); + test_quadratic(); + test_cubic(); + test_quartic(); + test_interpolation_condition(); + #else test_constant(); test_linear(); test_quadratic(); test_cubic(); test_quartic(); test_interpolation_condition(); + #endif test_constant(); test_linear(); @@ -517,14 +538,14 @@ int main() test_quartic(); test_interpolation_condition(); -#ifdef BOOST_HAS_FLOAT128 + #ifdef BOOST_HAS_FLOAT128 test_constant(); test_linear(); test_quadratic(); test_cubic(); test_quartic(); test_interpolation_condition(); -#endif + #endif return boost::math::test::report_errors(); } From 823fcd4cf27059e7fedc2c08ba04e5d05d01da2c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 30 May 2023 16:46:23 +0200 Subject: [PATCH 35/53] Add test and cast to finite differences --- .../differentiation/finite_difference.hpp | 4 +- test/test_numerical_differentiation.cpp | 53 ++++++++++++------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/include/boost/math/differentiation/finite_difference.hpp b/include/boost/math/differentiation/finite_difference.hpp index 5e4433e000..1375bac7ad 100644 --- a/include/boost/math/differentiation/finite_difference.hpp +++ b/include/boost/math/differentiation/finite_difference.hpp @@ -153,7 +153,7 @@ namespace detail { const Real eps = (numeric_limits::epsilon)(); // Error bound ~eps^4/5 - Real h = pow(11.25*eps, static_cast(1) / static_cast(5)); + Real h = pow(Real(11.25)*eps, static_cast(1) / static_cast(5)); h = detail::make_xph_representable(x, h); Real ymth = f(x - 2 * h); Real yth = f(x + 2 * h); @@ -222,7 +222,7 @@ namespace detail { // Mathematica code to get the error: // Series[(f[x+h]-f[x-h])*(4/5) + (1/5)*(f[x-2*h] - f[x+2*h]) + (4/105)*(f[x+3*h] - f[x-3*h]) + (1/280)*(f[x-4*h] - f[x+4*h]), {h, 0, 9}] // If we used Kahan summation, we could get the max error down to h^8|f^(9)(x)|/630 + |f(x)|eps/h. - Real h = pow(551.25*eps, static_cast(1) / static_cast(9)); + Real h = pow(Real(551.25)*eps, static_cast(1) / static_cast(9)); h = detail::make_xph_representable(x, h); Real yh = f(x + h); diff --git a/test/test_numerical_differentiation.cpp b/test/test_numerical_differentiation.cpp index 1b2f539624..0f2489a61a 100644 --- a/test/test_numerical_differentiation.cpp +++ b/test/test_numerical_differentiation.cpp @@ -16,6 +16,10 @@ #include #include +#if __has_include() +# include +#endif + using std::abs; using std::pow; using boost::math::differentiation::finite_difference_derivative; @@ -31,7 +35,7 @@ void test_order(size_t points_to_test) std::cout << std::setprecision(std::numeric_limits::digits10); //std::cout << std::fixed << std::scientific; auto f = [](Real t) { return boost::math::cyl_bessel_j(1, t); }; - Real min = -100000.0; + Real min = Real(-100000.0); Real max = -min; Real x = min; Real max_error = 0; @@ -95,7 +99,7 @@ void test_bessel() Real computed = finite_difference_derivative(f, x); Real expected = cyl_bessel_j_prime(12, x); - Real error_estimate = 4*abs(f(x))*sqrt(eps); + Real error_estimate = Real(4*abs(f(x))*sqrt(eps)); //std::cout << std::setprecision(std::numeric_limits::digits10); //std::cout << "cyl_bessel_j_prime: " << expected << std::endl; //std::cout << "First order fd : " << computed << std::endl; @@ -218,28 +222,41 @@ void test_complex_step() BOOST_AUTO_TEST_CASE(numerical_differentiation_test) { + constexpr size_t points_to_test = 1000; + + #ifdef __STDCPP_FLOAT32_T__ + test_complex_step(); + test_bessel(); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + #else test_complex_step(); - test_complex_step(); - test_bessel(); - test_bessel(); - - - size_t points_to_test = 1000; test_order(points_to_test); - test_order(points_to_test); - - test_order(points_to_test); - test_order(points_to_test); - test_order(points_to_test); - test_order(points_to_test); - test_order(points_to_test); - test_order(points_to_test); - test_order(points_to_test); + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_complex_step(); + test_bessel(); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + #else + test_complex_step(); + test_bessel(); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); + test_order(points_to_test); test_order(points_to_test); - + #endif } From c249bfebce8b1f4fd7ff14f49cf536a33ef32db1 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 30 May 2023 17:25:29 +0200 Subject: [PATCH 36/53] Fix -Wreturn-type --- include/boost/math/special_functions/lambert_w.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index 945a45895c..5b0fbaf63b 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -1267,10 +1267,8 @@ inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); return -1; } - else // z < 0.05 - { - return lambert_w_negative_rational_float(z, pol); - } + + return lambert_w_negative_rational_float(z, pol); } // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) for 32-bit usually float. template From 6d37555ccc3d35aa0f76d463c373f527662ec083 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 30 May 2023 17:25:48 +0200 Subject: [PATCH 37/53] Collected autodiff fixes --- .../boost/math/differentiation/autodiff.hpp | 2 +- test/test_autodiff.hpp | 8 + test/test_autodiff_1.cpp | 198 +++++++++--------- test/test_autodiff_2.cpp | 84 ++++---- test/test_autodiff_3.cpp | 14 +- test/test_autodiff_4.cpp | 4 +- test/test_autodiff_6.cpp | 16 +- 7 files changed, 166 insertions(+), 160 deletions(-) diff --git a/include/boost/math/differentiation/autodiff.hpp b/include/boost/math/differentiation/autodiff.hpp index 1286326c2e..7cda196852 100644 --- a/include/boost/math/differentiation/autodiff.hpp +++ b/include/boost/math/differentiation/autodiff.hpp @@ -1491,7 +1491,7 @@ fvar sqrt(fvar const& cr) { BOOST_IF_CONSTEXPR (order == 0) return fvar(*derivatives); else { - root_type numerator = 0.5; + root_type numerator = root_type(0.5); root_type powers = 1; #ifndef BOOST_NO_CXX17_IF_CONSTEXPR derivatives[1] = numerator / *derivatives; diff --git a/test/test_autodiff.hpp b/test/test_autodiff.hpp index 7f3c98b203..e522a3daf7 100644 --- a/test/test_autodiff.hpp +++ b/test/test_autodiff.hpp @@ -31,16 +31,24 @@ #include #include +#if __has_include() +# include +#endif + namespace mp11 = boost::mp11; namespace bmp = boost::multiprecision; namespace diff = boost::math::differentiation::autodiff_v1::detail; + #if defined(BOOST_USE_VALGRIND) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) using bin_float_types = mp11::mp_list; +#elif defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__) +using bin_float_types = mp11::mp_list; #else using bin_float_types = mp11::mp_list; #endif + // cpp_dec_float_50 cannot be used with close_at_tolerance /*using multiprecision_float_types = mp_list;*/ diff --git a/test/test_autodiff_1.cpp b/test/test_autodiff_1.cpp index 9417d78bff..144f610516 100644 --- a/test/test_autodiff_1.cpp +++ b/test/test_autodiff_1.cpp @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(constructors, T, all_float_types) { } } // Single variable - const T cx = 10.0; + const T cx = 10; const auto x = make_fvar(cx); for (auto i : boost::irange(m + 1)) { if (i == 0u) { @@ -44,16 +44,16 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(constructors, T, all_float_types) { } } // Second independent variable - const T cy = 100.0; + const T cy = 100; const auto y = make_fvar(cy); for (auto i : boost::irange(m + 1)) { for (auto j : boost::irange(n + 1)) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(y.derivative(i, j), cy); } else if (i == 0 && j == 1) { - BOOST_CHECK_EQUAL(y.derivative(i, j), 1.0); + BOOST_CHECK_EQUAL(y.derivative(i, j), static_cast(1.0)); } else { - BOOST_CHECK_EQUAL(y.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(y.derivative(i, j), static_cast(0.0)); } } } @@ -64,16 +64,16 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(implicit_constructors, T, all_float_types) { const autodiff_fvar x = 3; const autodiff_fvar one = uncast_return(x); const autodiff_fvar two_and_a_half = 2.5; - BOOST_CHECK_EQUAL(static_cast(x), 3.0); - BOOST_CHECK_EQUAL(static_cast(one), 1.0); - BOOST_CHECK_EQUAL(static_cast(two_and_a_half), 2.5); + BOOST_CHECK_EQUAL(static_cast(x), static_cast(3.0)); + BOOST_CHECK_EQUAL(static_cast(one), static_cast(1.0)); + BOOST_CHECK_EQUAL(static_cast(two_and_a_half), static_cast(2.5)); } BOOST_AUTO_TEST_CASE_TEMPLATE(assignment, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; - const T cy = 10.0; + const T cx = 10; + const T cy = 10; autodiff_fvar empty; // Uninitialized variable<> may have non-zero values. // Single variable @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ostream, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(addition_assignment, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; + const T cx = 10; auto sum = autodiff_fvar(); // zero-initialized // Single variable const auto x = make_fvar(cx); @@ -142,14 +142,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(addition_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(sum.derivative(i, j), cx); } else if (i == 1 && j == 0) { - BOOST_CHECK_EQUAL(sum.derivative(i, j), 1.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(1)); } else { - BOOST_CHECK_EQUAL(sum.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(0)); } } } // Arithmetic constant - const T cy = 11.0; + const T cy = 11; sum = 0; sum += cy; for (auto i : boost::irange(m + 1)) { @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(addition_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(sum.derivative(i, j), cy); } else { - BOOST_CHECK_EQUAL(sum.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(0)); } } } @@ -166,7 +166,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(addition_assignment, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(subtraction_assignment, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; + const T cx = 10; auto sum = autodiff_fvar(); // zero-initialized // Single variable const auto x = make_fvar(cx); @@ -176,14 +176,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(subtraction_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(sum.derivative(i, j), -cx); } else if (i == 1 && j == 0) { - BOOST_CHECK_EQUAL(sum.derivative(i, j), -1.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(-1)); } else { - BOOST_CHECK_EQUAL(sum.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(0)); } } } // Arithmetic constant - const T cy = 11.0; + const T cy = 11; sum = 0; sum -= cy; for (auto i : boost::irange(m + 1)) { @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(subtraction_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(sum.derivative(i, j), -cy); } else { - BOOST_CHECK_EQUAL(sum.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(sum.derivative(i, j), T(0)); } } } @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multiplication_assignment, T, all_float_types) { // extra lines. constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; + const T cx = 10; auto product = autodiff_fvar(1); // unit constant // Single variable auto x = make_fvar(cx); @@ -212,14 +212,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multiplication_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(product.derivative(i, j), cx); } else if (i == 1 && j == 0) { - BOOST_CHECK_EQUAL(product.derivative(i, j), 1.0); + BOOST_CHECK_EQUAL(product.derivative(i, j), T(1)); } else { - BOOST_CHECK_EQUAL(product.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(product.derivative(i, j), T(0)); } } } // Arithmetic constant - const T cy = 11.0; + const T cy = 11; product = 1; product *= cy; for (auto i : boost::irange(m + 1)) { @@ -227,12 +227,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multiplication_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(product.derivative(i, j), cy); } else { - BOOST_CHECK_EQUAL(product.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(product.derivative(i, j), T(0)); } } } // 0 * inf = nan - x = make_fvar(0.0); + x = make_fvar(T(0.0)); x *= std::numeric_limits::infinity(); // std::cout << "x = " << x << std::endl; for (auto i : boost::irange(m + 1)) { @@ -251,7 +251,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multiplication_assignment, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(division_assignment, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 16.0; + const T cx = 16; auto quotient = autodiff_fvar(1); // unit constant // Single variable const auto x = make_fvar(cx); @@ -262,11 +262,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(division_assignment, T, all_float_types) { BOOST_CHECK_EQUAL(quotient.derivative(3, 0), -6 / pow(cx, 4)); for (auto i : boost::irange(m + 1)) { for (auto j : boost::irange(std::size_t(1), n + 1)) { - BOOST_CHECK_EQUAL(quotient.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(quotient.derivative(i, j), T(0)); } } // Arithmetic constant - const T cy = 32.0; + const T cy = 32; quotient = 1; quotient /= cy; for (auto i : boost::irange(m + 1)) { @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(division_assignment, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(quotient.derivative(i, j), 1 / cy); } else { - BOOST_CHECK_EQUAL(quotient.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(quotient.derivative(i, j), T(0)); } } } @@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(division_assignment, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(unary_signs, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 16.0; + const T cx = 16; autodiff_fvar lhs; // Single variable const auto x = make_fvar(cx); @@ -293,9 +293,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(unary_signs, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(lhs.derivative(i, j), -cx); } else if (i == 1 && j == 0) { - BOOST_CHECK_EQUAL(lhs.derivative(i, j), -1.0); + BOOST_CHECK_EQUAL(lhs.derivative(i, j), T(-1)); } else { - BOOST_CHECK_EQUAL(lhs.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(lhs.derivative(i, j), T(0)); } } } @@ -305,9 +305,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(unary_signs, T, all_float_types) { if (i == 0 && j == 0) { BOOST_CHECK_EQUAL(lhs.derivative(i, j), cx); } else if (i == 1 && j == 0) { - BOOST_CHECK_EQUAL(lhs.derivative(i, j), 1.0); + BOOST_CHECK_EQUAL(lhs.derivative(i, j), T(1)); } else { - BOOST_CHECK_EQUAL(lhs.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(lhs.derivative(i, j), T(0)); } } } @@ -324,7 +324,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(cast_double, T, all_float_types) { } BOOST_AUTO_TEST_CASE_TEMPLATE(int_double_casting, T, all_float_types) { - const T ca = 3.0; + const T ca = 3; const auto x0 = make_fvar(ca); BOOST_CHECK_EQUAL(static_cast(x0), ca); const auto x1 = make_fvar(ca); @@ -334,8 +334,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(int_double_casting, T, all_float_types) { } BOOST_AUTO_TEST_CASE_TEMPLATE(scalar_addition, T, all_float_types) { - const T ca = 3.0; - const T cb = 4.0; + const T ca = 3; + const T cb = 4; const auto sum0 = autodiff_fvar(ca) + autodiff_fvar(cb); BOOST_CHECK_EQUAL(ca + cb, static_cast(sum0)); const auto sum1 = autodiff_fvar(ca) + cb; @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(scalar_addition, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(power8, T, all_float_types) { constexpr std::size_t n = 8u; - const T ca = 3.0; + const T ca = 3; auto x = make_fvar(ca); // Test operator*=() x *= x; @@ -366,10 +366,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(power8, T, all_float_types) { x = x * x * x * x * x * x * x * x; for (auto i : boost::irange(n + 1)) { BOOST_CHECK_CLOSE( - x.derivative(i), - power_factorial / + static_cast(x.derivative(i)), + static_cast(power_factorial / boost::math::factorial(static_cast(n - i)) * - pow(ca, n - i), + pow(ca, n - i)), std::numeric_limits::epsilon()); } } @@ -377,14 +377,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(power8, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(dim1_multiplication, T, all_float_types) { constexpr std::size_t m = 2; constexpr std::size_t n = 3; - const T cy = 4.0; + const T cy = 4; auto y0 = make_fvar(cy); auto y = make_fvar(cy); y *= y0; BOOST_CHECK_EQUAL(y.derivative(0), cy * cy); BOOST_CHECK_EQUAL(y.derivative(1), 2 * cy); - BOOST_CHECK_EQUAL(y.derivative(2), 2.0); - BOOST_CHECK_EQUAL(y.derivative(3), 0.0); + BOOST_CHECK_EQUAL(y.derivative(2), T(2)); + BOOST_CHECK_EQUAL(y.derivative(3), T(0)); y = y * cy; BOOST_CHECK_EQUAL(y.derivative(0), cy * cy * cy); BOOST_CHECK_EQUAL(y.derivative(1), 2 * cy * cy); @@ -395,21 +395,21 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(dim1_multiplication, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(dim1and2_multiplication, T, all_float_types) { constexpr std::size_t m = 2; constexpr std::size_t n = 3; - const T cx = 3.0; - const T cy = 4.0; + const T cx = 3; + const T cy = 4; auto x = make_fvar(cx); auto y = make_fvar(cy); y *= x; BOOST_CHECK_EQUAL(y.derivative(0, 0), cx * cy); BOOST_CHECK_EQUAL(y.derivative(0, 1), cx); BOOST_CHECK_EQUAL(y.derivative(1, 0), cy); - BOOST_CHECK_EQUAL(y.derivative(1, 1), 1.0); + BOOST_CHECK_EQUAL(y.derivative(1, 1), T(1)); for (auto i : boost::irange(std::size_t(1), m)) { for (auto j : boost::irange(std::size_t(1), n)) { if (i == 1 && j == 1) { - BOOST_CHECK_EQUAL(y.derivative(i, j), 1.0); + BOOST_CHECK_EQUAL(y.derivative(i, j), T(1)); } else { - BOOST_CHECK_EQUAL(y.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(y.derivative(i, j), T(0)); } } } @@ -418,89 +418,89 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(dim1and2_multiplication, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(dim2_addition, T, all_float_types) { constexpr std::size_t m = 2; constexpr std::size_t n = 3; - const T cx = 3.0; + const T cx = 3; const auto x = make_fvar(cx); BOOST_CHECK_EQUAL(x.derivative(0), cx); - BOOST_CHECK_EQUAL(x.derivative(1), 1.0); + BOOST_CHECK_EQUAL(x.derivative(1), T(1)); BOOST_CHECK_EQUAL(x.derivative(2), 0.0); - const T cy = 4.0; + const T cy = 4; const auto y = make_fvar(cy); BOOST_CHECK_EQUAL(static_cast(y.derivative(0)), cy); BOOST_CHECK_EQUAL(static_cast(y.derivative(1)), 0.0); // partial of y w.r.t. x. BOOST_CHECK_EQUAL(y.derivative(0, 0), cy); - BOOST_CHECK_EQUAL(y.derivative(0, 1), 1.0); + BOOST_CHECK_EQUAL(y.derivative(0, 1), T(1)); BOOST_CHECK_EQUAL(y.derivative(1, 0), 0.0); BOOST_CHECK_EQUAL(y.derivative(1, 1), 0.0); const auto z = x + y; BOOST_CHECK_EQUAL(z.derivative(0, 0), cx + cy); - BOOST_CHECK_EQUAL(z.derivative(0, 1), 1.0); - BOOST_CHECK_EQUAL(z.derivative(1, 0), 1.0); + BOOST_CHECK_EQUAL(z.derivative(0, 1), T(1)); + BOOST_CHECK_EQUAL(z.derivative(1, 0), T(1)); BOOST_CHECK_EQUAL(z.derivative(1, 1), 0.0); // The following 4 are unnecessarily more expensive than the previous 4. BOOST_CHECK_EQUAL(z.derivative(0).derivative(0), cx + cy); - BOOST_CHECK_EQUAL(z.derivative(0).derivative(1), 1.0); - BOOST_CHECK_EQUAL(z.derivative(1).derivative(0), 1.0); + BOOST_CHECK_EQUAL(z.derivative(0).derivative(1), T(1)); + BOOST_CHECK_EQUAL(z.derivative(1).derivative(0), T(1)); BOOST_CHECK_EQUAL(z.derivative(1).derivative(1), 0.0); } BOOST_AUTO_TEST_CASE_TEMPLATE(dim2_multiplication, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 6.0; + const T cx = 6; const auto x = make_fvar(cx); - const T cy = 5.0; + const T cy = 5; const auto y = make_fvar(cy); const auto z = x * x * y * y * y; BOOST_CHECK_EQUAL(z.derivative(0, 0), cx * cx * cy * cy * cy); // x^2 * y^3 BOOST_CHECK_EQUAL(z.derivative(0, 1), cx * cx * 3 * cy * cy); // x^2 * 3y^2 BOOST_CHECK_EQUAL(z.derivative(0, 2), cx * cx * 6 * cy); // x^2 * 6y BOOST_CHECK_EQUAL(z.derivative(0, 3), cx * cx * 6); // x^2 * 6 - BOOST_CHECK_EQUAL(z.derivative(0, 4), 0.0); // x^2 * 0 + BOOST_CHECK_EQUAL(z.derivative(0, 4), T(0)); // x^2 * 0 BOOST_CHECK_EQUAL(z.derivative(1, 0), 2 * cx * cy * cy * cy); // 2x * y^3 BOOST_CHECK_EQUAL(z.derivative(1, 1), 2 * cx * 3 * cy * cy); // 2x * 3y^2 BOOST_CHECK_EQUAL(z.derivative(1, 2), 2 * cx * 6 * cy); // 2x * 6y BOOST_CHECK_EQUAL(z.derivative(1, 3), 2 * cx * 6); // 2x * 6 - BOOST_CHECK_EQUAL(z.derivative(1, 4), 0.0); // 2x * 0 + BOOST_CHECK_EQUAL(z.derivative(1, 4), T(0)); // 2x * 0 BOOST_CHECK_EQUAL(z.derivative(2, 0), 2 * cy * cy * cy); // 2 * y^3 BOOST_CHECK_EQUAL(z.derivative(2, 1), 2 * 3 * cy * cy); // 2 * 3y^2 BOOST_CHECK_EQUAL(z.derivative(2, 2), 2 * 6 * cy); // 2 * 6y BOOST_CHECK_EQUAL(z.derivative(2, 3), 2 * 6); // 2 * 6 - BOOST_CHECK_EQUAL(z.derivative(2, 4), 0.0); // 2 * 0 - BOOST_CHECK_EQUAL(z.derivative(3, 0), 0.0); // 0 * y^3 - BOOST_CHECK_EQUAL(z.derivative(3, 1), 0.0); // 0 * 3y^2 - BOOST_CHECK_EQUAL(z.derivative(3, 2), 0.0); // 0 * 6y - BOOST_CHECK_EQUAL(z.derivative(3, 3), 0.0); // 0 * 6 - BOOST_CHECK_EQUAL(z.derivative(3, 4), 0.0); // 0 * 0 + BOOST_CHECK_EQUAL(z.derivative(2, 4), T(0)); // 2 * 0 + BOOST_CHECK_EQUAL(z.derivative(3, 0), T(0)); // 0 * y^3 + BOOST_CHECK_EQUAL(z.derivative(3, 1), T(0)); // 0 * 3y^2 + BOOST_CHECK_EQUAL(z.derivative(3, 2), T(0)); // 0 * 6y + BOOST_CHECK_EQUAL(z.derivative(3, 3), T(0)); // 0 * 6 + BOOST_CHECK_EQUAL(z.derivative(3, 4), T(0)); // 0 * 0 } BOOST_AUTO_TEST_CASE_TEMPLATE(dim2_multiplication_and_subtraction, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 6.0; + const T cx = 6; const auto x = make_fvar(cx); - const T cy = 5.0; + const T cy = 5; const auto y = make_fvar(cy); const auto z = x * x - y * y; BOOST_CHECK_EQUAL(z.derivative(0, 0), cx * cx - cy * cy); BOOST_CHECK_EQUAL(z.derivative(0, 1), -2 * cy); - BOOST_CHECK_EQUAL(z.derivative(0, 2), -2.0); - BOOST_CHECK_EQUAL(z.derivative(0, 3), 0.0); - BOOST_CHECK_EQUAL(z.derivative(0, 4), 0.0); + BOOST_CHECK_EQUAL(z.derivative(0, 2), T(-2)); + BOOST_CHECK_EQUAL(z.derivative(0, 3), T(0)); + BOOST_CHECK_EQUAL(z.derivative(0, 4), T(0)); BOOST_CHECK_EQUAL(z.derivative(1, 0), 2 * cx); - BOOST_CHECK_EQUAL(z.derivative(2, 0), 2.0); + BOOST_CHECK_EQUAL(z.derivative(2, 0), T(2)); for (auto i : boost::irange(std::size_t(1), m + 1)) { for (auto j : boost::irange(std::size_t(1), n + 1)) { - BOOST_CHECK_EQUAL(z.derivative(i, j), 0.0); + BOOST_CHECK_EQUAL(z.derivative(i, j), T(0)); } } } BOOST_AUTO_TEST_CASE_TEMPLATE(inverse, T, all_float_types) { constexpr std::size_t m = 3; - const T cx = 4.0; + const T cx = 4; const auto x = make_fvar(cx); const auto xinv = x.inverse(); BOOST_CHECK_EQUAL(xinv.derivative(0), 1 / cx); @@ -519,9 +519,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(inverse, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(division, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 16.0; + const T cx = 16; auto x = make_fvar(cx); - const T cy = 4.0; + const T cy = 4; auto y = make_fvar(cy); auto z = x * x / (y * y); BOOST_CHECK_EQUAL(z.derivative(0, 0), cx * cx / (cy * cy)); // x^2 * y^-2 @@ -581,8 +581,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(division, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(equality, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; - const T cy = 10.0; + const T cx = 10; + const T cy = 10; const auto x = make_fvar(cx); const auto y = make_fvar(cy); BOOST_CHECK_EQUAL(x, y); @@ -595,8 +595,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(equality, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(inequality, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; - const T cy = 11.0; + const T cx = 10; + const T cy = 11; const auto x = make_fvar(cx); const auto y = make_fvar(cy); BOOST_CHECK_NE(x, y); @@ -609,8 +609,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(inequality, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(less_than_or_equal_to, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 10.0; - const T cy = 11.0; + const T cx = 10; + const T cy = 11; const auto x = make_fvar(cx); const auto y = make_fvar(cy); BOOST_CHECK_LE(x, y); @@ -627,8 +627,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(less_than_or_equal_to, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(greater_than_or_equal_to, T, all_float_types) { constexpr std::size_t m = 3; constexpr std::size_t n = 4; - const T cx = 11.0; - const T cy = 10.0; + const T cx = 11; + const T cy = 10; const auto x = make_fvar(cx); const auto y = make_fvar(cy); BOOST_CHECK_GE(x, y); @@ -647,28 +647,28 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(fabs_test, T, all_float_types) { using detail::fabs; using std::fabs; constexpr std::size_t m = 3; - const T cx = 11.0; + const T cx = 11; const auto x = make_fvar(cx); auto a = fabs(x); BOOST_CHECK_EQUAL(a.derivative(0), fabs(cx)); - BOOST_CHECK_EQUAL(a.derivative(1), 1.0); - BOOST_CHECK_EQUAL(a.derivative(2), 0.0); - BOOST_CHECK_EQUAL(a.derivative(3), 0.0); + BOOST_CHECK_EQUAL(a.derivative(1), T(1)); + BOOST_CHECK_EQUAL(a.derivative(2), T(0)); + BOOST_CHECK_EQUAL(a.derivative(3), T(0)); a = fabs(-x); BOOST_CHECK_EQUAL(a.derivative(0), fabs(cx)); - BOOST_CHECK_EQUAL(a.derivative(1), 1.0); // fabs(-x) = fabs(x) - BOOST_CHECK_EQUAL(a.derivative(2), 0.0); - BOOST_CHECK_EQUAL(a.derivative(3), 0.0); + BOOST_CHECK_EQUAL(a.derivative(1), T(1)); // fabs(-x) = fabs(x) + BOOST_CHECK_EQUAL(a.derivative(2), T(0)); + BOOST_CHECK_EQUAL(a.derivative(3), T(0)); const auto xneg = make_fvar(-cx); a = fabs(xneg); BOOST_CHECK_EQUAL(a.derivative(0), fabs(cx)); - BOOST_CHECK_EQUAL(a.derivative(1), -1.0); - BOOST_CHECK_EQUAL(a.derivative(2), 0.0); - BOOST_CHECK_EQUAL(a.derivative(3), 0.0); + BOOST_CHECK_EQUAL(a.derivative(1), -T(1)); + BOOST_CHECK_EQUAL(a.derivative(2), T(0)); + BOOST_CHECK_EQUAL(a.derivative(3), T(0)); const auto zero = make_fvar(0); a = fabs(zero); for (auto i : boost::irange(m + 1)) { - BOOST_CHECK_EQUAL(a.derivative(i), 0.0); + BOOST_CHECK_EQUAL(a.derivative(i), T(0)); } } @@ -678,7 +678,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ceil_and_floor, T, all_float_types) { using std::ceil; using std::floor; constexpr std::size_t m = 3; - T tests[]{-1.5, 0.0, 1.5}; + T tests[]{T(-1.5), T(0.0), T(1.5)}; for (T &test : tests) { const auto x = make_fvar(test); auto c = ceil(x); @@ -686,8 +686,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ceil_and_floor, T, all_float_types) { BOOST_CHECK_EQUAL(c.derivative(0), ceil(test)); BOOST_CHECK_EQUAL(f.derivative(0), floor(test)); for (auto i : boost::irange(std::size_t(1), m + 1)) { - BOOST_CHECK_EQUAL(c.derivative(i), 0.0); - BOOST_CHECK_EQUAL(f.derivative(i), 0.0); + BOOST_CHECK_EQUAL(c.derivative(i), T(0)); + BOOST_CHECK_EQUAL(f.derivative(i), T(0)); } } } diff --git a/test/test_autodiff_2.cpp b/test/test_autodiff_2.cpp index 30b517fed6..f7700195d2 100644 --- a/test/test_autodiff_2.cpp +++ b/test/test_autodiff_2.cpp @@ -15,9 +15,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(one_over_one_plus_x_squared, T, all_float_types) { f *= f; f += T(1); f = f.inverse(); - BOOST_CHECK_EQUAL(f.derivative(0u), 0.5); - BOOST_CHECK_EQUAL(f.derivative(1u), -0.5); - BOOST_CHECK_EQUAL(f.derivative(2u), 0.5); + BOOST_CHECK_EQUAL(f.derivative(0u), T(0.5)); + BOOST_CHECK_EQUAL(f.derivative(1u), T(-0.5)); + BOOST_CHECK_EQUAL(f.derivative(2u), T(0.5)); BOOST_CHECK_EQUAL(f.derivative(3u), 0); BOOST_CHECK_EQUAL(f.derivative(4u), -3); } @@ -25,14 +25,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(one_over_one_plus_x_squared, T, all_float_types) { BOOST_AUTO_TEST_CASE_TEMPLATE(exp_test, T, all_float_types) { using std::exp; constexpr std::size_t m = 4; - const T cx = 2.0; + const T cx = 2; const auto x = make_fvar(cx); auto y = exp(x); for (auto i : boost::irange(m + 1)) { // std::cout.precision(100); // std::cout << "y.derivative("< 0.5) + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) { m += 1; sign = -1; @@ -261,7 +261,7 @@ T ellint_pi_imp(T v, T phi, T k, T vc, const Policy& pol) t = sphi * sphi; y = 1 - k * k * t; z = 1; - if(v * t < 0.5) + if(v * t < T(0.5)) p = 1 - v * t; else p = x + vc * t; diff --git a/include/boost/math/special_functions/ellint_d.hpp b/include/boost/math/special_functions/ellint_d.hpp index d50029f5f4..67c3702c10 100644 --- a/include/boost/math/special_functions/ellint_d.hpp +++ b/include/boost/math/special_functions/ellint_d.hpp @@ -76,7 +76,7 @@ T ellint_d_imp(T phi, T k, const Policy& pol) T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); T m = boost::math::round((phi - rphi) / constants::half_pi()); int s = 1; - if(boost::math::tools::fmod_workaround(m, T(2)) > 0.5) + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) { m += 1; s = -1; diff --git a/include/boost/math/special_functions/ellint_rc.hpp b/include/boost/math/special_functions/ellint_rc.hpp index 1fa7afc55c..c25f00cc59 100644 --- a/include/boost/math/special_functions/ellint_rc.hpp +++ b/include/boost/math/special_functions/ellint_rc.hpp @@ -74,7 +74,7 @@ T ellint_rc_imp(T x, T y, const Policy& pol) } else { - if(y / x > 0.5) + if(y / x > T(0.5)) { T arg = sqrt((x - y) / x); result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(x - y)); diff --git a/include/boost/math/special_functions/ellint_rd.hpp b/include/boost/math/special_functions/ellint_rd.hpp index d7b9d22799..08cfecb040 100644 --- a/include/boost/math/special_functions/ellint_rd.hpp +++ b/include/boost/math/special_functions/ellint_rd.hpp @@ -74,14 +74,14 @@ T ellint_rd_imp(T x, T y, T z, const Policy& pol) } else { - if((std::min)(x, y) / (std::max)(x, y) > 1.3) + if((std::min)(x, y) / (std::max)(x, y) > T(1.3)) return 3 * (ellint_rc_imp(x, y, pol) - sqrt(x) / y) / (2 * (y - x)); // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) } } if(x == y) { - if((std::min)(x, z) / (std::max)(x, z) > 1.3) + if((std::min)(x, z) / (std::max)(x, z) > T(1.3)) return 3 * (ellint_rc_imp(z, x, pol) - 1 / sqrt(z)) / (z - x); // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) } @@ -100,7 +100,7 @@ T ellint_rd_imp(T x, T y, T z, const Policy& pol) T sum = 0; T sum_pow = 0.25f; - while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) { T t = sqrt(xn * yn); xn = (xn + yn) / 2; diff --git a/include/boost/math/special_functions/ellint_rf.hpp b/include/boost/math/special_functions/ellint_rf.hpp index a8a7b4b217..5d5d73c258 100644 --- a/include/boost/math/special_functions/ellint_rf.hpp +++ b/include/boost/math/special_functions/ellint_rf.hpp @@ -97,7 +97,7 @@ namespace boost { namespace math { namespace detail{ T xn = sqrt(x); T yn = sqrt(y); - while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) { T t = sqrt(xn * yn); xn = (xn + yn) / 2; diff --git a/include/boost/math/special_functions/ellint_rg.hpp b/include/boost/math/special_functions/ellint_rg.hpp index ddeb820586..96accdac02 100644 --- a/include/boost/math/special_functions/ellint_rg.hpp +++ b/include/boost/math/special_functions/ellint_rg.hpp @@ -92,7 +92,7 @@ namespace boost { namespace math { namespace detail{ T sum = 0; T sum_pow = 0.25f; - while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) { T t = sqrt(xn * yn); xn = (xn + yn) / 2; diff --git a/include/boost/math/special_functions/ellint_rj.hpp b/include/boost/math/special_functions/ellint_rj.hpp index fdf1b3efc5..310cfafca6 100644 --- a/include/boost/math/special_functions/ellint_rj.hpp +++ b/include/boost/math/special_functions/ellint_rj.hpp @@ -166,7 +166,7 @@ T ellint_rj_imp(T x, T y, T z, T p, const Policy& pol) { return ellint_rd_imp(x, y, y, pol); } - else if((std::max)(y, p) / (std::min)(y, p) > 1.2) + else if((std::max)(y, p) / (std::min)(y, p) > T(1.2)) { return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); } @@ -218,7 +218,7 @@ T ellint_rj_imp(T x, T y, T z, T p, const Policy& pol) Dn = (rp + rx) * (rp + ry) * (rp + rz); En = delta / Dn; En /= Dn; - if((En < -0.5) && (En > -1.5)) + if((En < T(-0.5)) && (En > T(-1.5))) { // // Occasionally En ~ -1, we then have no means of calculating diff --git a/include/boost/math/special_functions/expint.hpp b/include/boost/math/special_functions/expint.hpp index a2aa83b1d1..59dfcda0fd 100644 --- a/include/boost/math/special_functions/expint.hpp +++ b/include/boost/math/special_functions/expint.hpp @@ -457,7 +457,7 @@ T expint_imp(unsigned n, T z, const Policy& pol, const Tag& tag) bool f; if(n < 3) { - f = z < 0.5; + f = z < T(0.5); } else { diff --git a/include/boost/math/special_functions/gamma.hpp b/include/boost/math/special_functions/gamma.hpp index b84389a340..13da394940 100644 --- a/include/boost/math/special_functions/gamma.hpp +++ b/include/boost/math/special_functions/gamma.hpp @@ -264,7 +264,7 @@ T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = nullptr) else { // regular evaluation: - T zgh = static_cast(z + Lanczos::g() - boost::math::constants::half()); + T zgh = static_cast(z + T(Lanczos::g()) - boost::math::constants::half()); result = log(zgh) - 1; result *= z - 0.5f; // diff --git a/include/boost/math/special_functions/jacobi_elliptic.hpp b/include/boost/math/special_functions/jacobi_elliptic.hpp index 88d8b9dac2..114b991d9c 100644 --- a/include/boost/math/special_functions/jacobi_elliptic.hpp +++ b/include/boost/math/special_functions/jacobi_elliptic.hpp @@ -107,7 +107,7 @@ T jacobi_imp(const T& x, const T& k, T* cn, T* dn, const Policy& pol, const char }*/ T T1; T kc = 1 - k; - T k_prime = k < 0.5 ? T(sqrt(1 - k * k)) : T(sqrt(2 * kc - kc * kc)); + T k_prime = k < T(0.5) ? T(sqrt(1 - k * k)) : T(sqrt(2 * kc - kc * kc)); T T0 = jacobi_recurse(x, k, T(1), k_prime, 0, &T1, pol); *cn = cos(T0); *dn = cos(T0) / cos(T1 - T0); diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index f712206445..b19d889b83 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -398,7 +398,7 @@ T lambert_w_singularity_series(const T p) } #endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS - if (absp < 0.01159) + if (absp < T(0.01159)) { // Only 6 near-singularity series terms are useful. return -1 + @@ -410,7 +410,7 @@ T lambert_w_singularity_series(const T p) p * q[6] ))))); } - else if (absp < 0.0766) // Use 10 near-singularity series terms. + else if (absp < T(0.0766)) // Use 10 near-singularity series terms. { // Use 10 near-singularity series terms. return -1 + @@ -1159,26 +1159,25 @@ T lambert_w_positive_rational_float(T z) T log_w = log(z); return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); } - else // 32 < log(z) < 100 - { - // Max error in interpolated form: 1.491e-08 - static const T Y = -4.012863159e+00f; - static const T P[] = { - 4.431629226e+00f, - 2.756690487e-01f, - -2.992956930e-03f, - -4.912259384e-05f, - }; - static const T Q[] = { - 1.000000000e+00f, - 2.015434591e-01f, - 4.949426142e-03f, - 1.609659944e-05f, - -5.111523436e-09f, - }; - T log_w = log(z); - return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); - } + + // Max error in interpolated form: 1.491e-08 + static const T Y = -4.012863159e+00f; + static const T P[] = { + 4.431629226e+00f, + 2.756690487e-01f, + -2.992956930e-03f, + -4.912259384e-05f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.015434591e-01f, + 4.949426142e-03f, + 1.609659944e-05f, + -5.111523436e-09f, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } template @@ -1255,7 +1254,7 @@ inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant(function, "Expected a finite value but got %1%.", z, pol); } - if (z >= 0.05) // Fukushima switch point. + if (z >= T(0.05)) // Fukushima switch point. // if (z >= 0.045) // 34 terms makes 128-bit 'exact' below 0.045. { // Normal ranges using several rational polynomials. return lambert_w_positive_rational_float(z); @@ -1871,7 +1870,7 @@ T lambert_wm1_imp(const T z, const Policy& pol) // Check that z argument value is not smaller than lookup_table G[64] // std::cout << "(z > wm1zs[63]) = " << std::boolalpha << (z > wm1zs[63]) << std::endl; - if (z >= wm1zs[63]) // wm1zs[63] = -1.0264389699511282259046957018510946438e-26L W = 64.00000000000000000 + if (z >= T(wm1zs[63])) // wm1zs[63] = -1.0264389699511282259046957018510946438e-26L W = 64.00000000000000000 { // z >= -1.0264389699511303e-26 (but z != 0 and z >= std::numeric_limits::min() and so NOT denormalized). // Some info on Lambert W-1 values for extreme values of z. @@ -1956,14 +1955,14 @@ T lambert_wm1_imp(const T z, const Policy& pol) // Bracketing sequence n = (2, 4, 8, 16, 32, 64) for W-1 branch. (0 is -infinity) // Since z is probably quite small, start with lowest n (=2). int n = 2; - if (wm1zs[n - 1] > z) + if (T(wm1zs[n - 1]) > z) { goto bisect; } for (int j = 1; j <= 5; ++j) { n *= 2; - if (wm1zs[n - 1] > z) + if (T(wm1zs[n - 1]) > z) { goto overshot; } @@ -1983,7 +1982,7 @@ T lambert_wm1_imp(const T z, const Policy& pol) { break; // goto bisect; } - if (wm1zs[n - nh - 1] > z) + if (T(wm1zs[n - nh - 1]) > z) { n -= nh; } @@ -2027,7 +2026,7 @@ T lambert_wm1_imp(const T z, const Policy& pol) using calc_type = typename std::conditional::value, lookup_t, T>::type; calc_type w = -static_cast(n); // Equation 25, - calc_type y = static_cast(z * wm1es[n - 1]); // Equation 26, + calc_type y = static_cast(z * T(wm1es[n - 1])); // Equation 26, // Perform the bisections fractional bisections for necessary precision. for (int j = 0; j < bisections; ++j) { // Equation 27. diff --git a/include/boost/math/special_functions/owens_t.hpp b/include/boost/math/special_functions/owens_t.hpp index a3879a71c2..d4fd3290b3 100644 --- a/include/boost/math/special_functions/owens_t.hpp +++ b/include/boost/math/special_functions/owens_t.hpp @@ -949,7 +949,7 @@ namespace boost // Now look back at the results from T1 and T2 and see if either gave better // results than we could get from the 64-bit precision versions. // - if((std::min)(p1.second, p2.second) < 1e-20) + if((std::min)(p1.second, p2.second) < RealType(1e-20)) { return p1.second < p2.second ? p1.first : p2.first; } @@ -1001,7 +1001,7 @@ namespace boost } // if(fabs_a <= 1.0) else { - if( h <= 0.67 ) + if( h <= RealType(0.67) ) { const RealType normh = owens_t_znorm1(h, pol); const RealType normah = owens_t_znorm1(fabs_ah, pol); diff --git a/include/boost/math/special_functions/powm1.hpp b/include/boost/math/special_functions/powm1.hpp index 05b5a5d3fa..e52277b16d 100644 --- a/include/boost/math/special_functions/powm1.hpp +++ b/include/boost/math/special_functions/powm1.hpp @@ -28,12 +28,12 @@ inline T powm1_imp(const T x, const T y, const Policy& pol) static const char* function = "boost::math::powm1<%1%>(%1%, %1%)"; if (x > 0) { - if ((fabs(y * (x - 1)) < 0.5) || (fabs(y) < 0.2)) + if ((fabs(y * (x - 1)) < T(0.5)) || (fabs(y) < T(0.2))) { // We don't have any good/quick approximation for log(x) * y // so just try it and see: T l = y * log(x); - if (l < 0.5) + if (l < T(0.5)) return boost::math::expm1(l, pol); if (l > boost::math::tools::log_max_value()) return boost::math::policies::raise_overflow_error(function, nullptr, pol); diff --git a/include/boost/math/special_functions/round.hpp b/include/boost/math/special_functions/round.hpp index be9d661bae..b32c8e4347 100644 --- a/include/boost/math/special_functions/round.hpp +++ b/include/boost/math/special_functions/round.hpp @@ -44,7 +44,7 @@ inline tools::promote_args_t round(const T& v, const Policy& pol, const std:: // The logic here is rather convoluted, but avoids a number of traps, // see discussion here https://github.com/boostorg/math/pull/8 // - if (-0.5 < v && v < 0.5) + if (T(-0.5) < v && v < T(0.5)) { // special case to avoid rounding error on the direct // predecessor of +0.5 resp. the direct successor of -0.5 in @@ -56,13 +56,13 @@ inline tools::promote_args_t round(const T& v, const Policy& pol, const std:: // subtract v from ceil(v) first in order to avoid rounding // errors on largest representable integer numbers result_type c(ceil(v)); - return 0.5 < c - v ? c - 1 : c; + return T(0.5) < c - v ? c - 1 : c; } else { // see former branch result_type f(floor(v)); - return 0.5 < v - f ? f + 1 : f; + return T(0.5) < v - f ? f + 1 : f; } } template diff --git a/include/boost/math/special_functions/sqrt1pm1.hpp b/include/boost/math/special_functions/sqrt1pm1.hpp index 293a9d97b3..850a6aacea 100644 --- a/include/boost/math/special_functions/sqrt1pm1.hpp +++ b/include/boost/math/special_functions/sqrt1pm1.hpp @@ -26,7 +26,7 @@ inline typename tools::promote_args::type sqrt1pm1(const T& val, const Policy typedef typename tools::promote_args::type result_type; BOOST_MATH_STD_USING - if(fabs(result_type(val)) > 0.75) + if(fabs(result_type(val)) > T(0.75)) return sqrt(1 + result_type(val)) - 1; return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol); } diff --git a/test/test_ibeta_derivative.cpp b/test/test_ibeta_derivative.cpp index 5e600b630f..f722e95198 100644 --- a/test/test_ibeta_derivative.cpp +++ b/test/test_ibeta_derivative.cpp @@ -2,7 +2,7 @@ // 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) -#if defined(__GNUC__) +#if defined(__GNUC__) && __GNUC__ <= 12 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-range" #endif From a7f98dbe003b16c390a25426c37a9ac8aa650828 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 31 May 2023 15:43:23 +0200 Subject: [PATCH 41/53] Add casts to all two argument cmath functions to work around GCC bug [ci skip] --- test/test_autodiff_2.cpp | 124 +++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/test/test_autodiff_2.cpp b/test/test_autodiff_2.cpp index f7700195d2..79ee24ba0d 100644 --- a/test/test_autodiff_2.cpp +++ b/test/test_autodiff_2.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(pow, T, bin_float_types) { auto z1 = pow(cx, y); BOOST_CHECK_CLOSE(z1.derivative(0u, 0u), pow(cx, cy), eps); for (auto j : boost::irange(std::size_t(1), n + 1)) { - BOOST_CHECK_CLOSE(z1.derivative(0u, j), pow(log(cx), j) * pow(cx, cy), eps); + BOOST_CHECK_CLOSE(z1.derivative(0u, j), pow(log(cx), T(j)) * pow(cx, cy), eps); } for (auto i : boost::irange(std::size_t(1), m + 1)) { @@ -70,11 +70,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(pow, T, bin_float_types) { const auto z2 = pow(x, y); for (auto j : boost::irange(n + 1)) { - BOOST_CHECK_CLOSE(z2.derivative(0u, j), pow(cx, cy) * pow(log(cx), j), eps); + BOOST_CHECK_CLOSE(z2.derivative(0u, j), pow(cx, cy) * pow(log(cx), T(j)), eps); } for (auto j : boost::irange(n + 1)) { BOOST_CHECK_CLOSE(z2.derivative(1u, j), - pow(cx, cy - 1) * pow(log(cx), static_cast(j) - 1) * + pow(cx, cy - 1) * pow(log(cx), T(static_cast(j) - 1)) * (cy * log(cx) + j), eps); } @@ -85,15 +85,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(pow, T, bin_float_types) { eps); for (auto j : boost::irange(std::size_t(2u), n + 1)) { BOOST_CHECK_CLOSE(z2.derivative(2u, j), - pow(cx, cy - 2) * pow(log(cx), j - 2) * + pow(cx, cy - 2) * pow(log(cx), T(j - 2)) * (j * (2 * cy - 1) * log(cx) + (j - 1) * j + - (cy - 1) * cy * pow(log(cx), 2)), + (cy - 1) * cy * pow(log(cx), T(2))), eps); } BOOST_CHECK_CLOSE(z2.derivative(2u, 4u), - pow(cx, cy - 2) * pow(log(cx), 2) * + pow(cx, cy - 2) * pow(log(cx), T(2)) * (4 * (2 * cy - 1) * log(cx) + (4 - 1) * 4 + - (cy - 1) * cy * pow(log(cx), 2)), + (cy - 1) * cy * pow(log(cx), T(2))), eps); } @@ -155,80 +155,80 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(pow2, T, bin_float_types) { const T mathematica[]{ static_cast(4 * root_two()), static_cast(4 * root_two() * ln_two()), - static_cast(4 * root_two() * pow(ln_two(), 2)), - static_cast(4 * root_two() * pow(ln_two(), 3)), - static_cast(4 * root_two() * pow(ln_two(), 4)), - static_cast(4 * root_two() * pow(ln_two(), 5)), + static_cast(4 * root_two() * pow(ln_two(), (T)2)), + static_cast(4 * root_two() * pow(ln_two(), (T)3)), + static_cast(4 * root_two() * pow(ln_two(), (T)4)), + static_cast(4 * root_two() * pow(ln_two(), (T)5)), static_cast(5 * root_two()), static_cast(2 * root_two() * (1 + (5 * ln_two()) / 2)), static_cast(2 * root_two() * ln_two() * (2 + (5 * ln_two()) / 2)), - static_cast(2 * root_two() * pow(ln_two(), 2) * + static_cast(2 * root_two() * pow(ln_two(), (T)2) * (3 + (5 * ln_two()) / 2)), - static_cast(2 * root_two() * pow(ln_two(), 3) * + static_cast(2 * root_two() * pow(ln_two(), (T)3) * (4 + (5 * ln_two()) / 2)), - static_cast(2 * root_two() * pow(ln_two(), 4) * + static_cast(2 * root_two() * pow(ln_two(), (T)4) * (5 + (5 * ln_two()) / 2)), static_cast(15 / (2 * root_two())), static_cast(root_two() * (4 + (15 * ln_two()) / 4)), static_cast(root_two() * - (2 + 8 * ln_two() + (15 * pow(ln_two(), 2)) / 4)), + (2 + 8 * ln_two() + (15 * pow(ln_two(), (T)2)) / 4)), static_cast(root_two() * ln_two() * - (6 + 12 * ln_two() + (15 * pow(ln_two(), 2)) / 4)), - static_cast(root_two() * pow(ln_two(), 2) * - (12 + 16 * ln_two() + (15 * pow(ln_two(), 2)) / 4)), - static_cast(root_two() * pow(ln_two(), 3) * - (20 + 20 * ln_two() + (15 * pow(ln_two(), 2)) / 4)), + (6 + 12 * ln_two() + (15 * pow(ln_two(), (T)2)) / 4)), + static_cast(root_two() * pow(ln_two(), (T)2) * + (12 + 16 * ln_two() + (15 * pow(ln_two(), (T)2)) / 4)), + static_cast(root_two() * pow(ln_two(), (T)3) * + (20 + 20 * ln_two() + (15 * pow(ln_two(), (T)2)) / 4)), static_cast(15 / (8 * root_two())), static_cast((23 / 4.0 + (15 * ln_two()) / 8) / root_two()), static_cast( - (9 + (23 * ln_two()) / 2 + (15 * pow(ln_two(), 2)) / 8) / + (9 + (23 * ln_two()) / 2 + (15 * pow(ln_two(), (T)2)) / 8) / root_two()), - static_cast((6 + 27 * ln_two() + (69 * pow(ln_two(), 2)) / 4 + - (15 * pow(ln_two(), 3)) / 8) / + static_cast((6 + 27 * ln_two() + (69 * pow(ln_two(), (T)2)) / 4 + + (15 * pow(ln_two(), (T)3)) / 8) / root_two()), static_cast( - (ln_two() * (24 + 54 * ln_two() + 23 * pow(ln_two(), 2) + - (15 * pow(ln_two(), 3)) / 8)) / + (ln_two() * (24 + 54 * ln_two() + 23 * pow(ln_two(), (T)2) + + (15 * pow(ln_two(), (T)3)) / 8)) / root_two()), - static_cast((pow(ln_two(), 2) * - (60 + 90 * ln_two() + (115 * pow(ln_two(), 2)) / 4 + - (15 * pow(ln_two(), 3)) / 8)) / + static_cast((pow(ln_two(), (T)2) * + (60 + 90 * ln_two() + (115 * pow(ln_two(), (T)2)) / 4 + + (15 * pow(ln_two(), (T)3)) / 8)) / root_two()), static_cast(-15 / (32 * root_two())), static_cast((-1 - (15 * ln_two()) / 16) / (2 * root_two())), - static_cast((7 - 2 * ln_two() - (15 * pow(ln_two(), 2)) / 16) / + static_cast((7 - 2 * ln_two() - (15 * pow(ln_two(), (T)2)) / 16) / (2 * root_two())), - static_cast((24 + 21 * ln_two() - 3 * pow(ln_two(), 2) - - (15 * pow(ln_two(), 3)) / 16) / + static_cast((24 + 21 * ln_two() - 3 * pow(ln_two(), (T)2) - + (15 * pow(ln_two(), (T)3)) / 16) / (2 * root_two())), - static_cast((24 + 96 * ln_two() + 42 * pow(ln_two(), 2) - - 4 * pow(ln_two(), 3) - - (15 * pow(ln_two(), 4)) / 16) / + static_cast((24 + 96 * ln_two() + 42 * pow(ln_two(), (T)2) - + 4 * pow(ln_two(), (T)3) - + (15 * pow(ln_two(), (T)4)) / 16) / (2 * root_two())), static_cast( (ln_two() * - (120 + 240 * ln_two() + 70 * pow(ln_two(), 2) - - 5 * pow(ln_two(), 3) - (15 * pow(ln_two(), 4)) / 16)) / + (120 + 240 * ln_two() + 70 * pow(ln_two(), (T)2) - + 5 * pow(ln_two(), (T)3) - (15 * pow(ln_two(), (T)4)) / 16)) / (2 * root_two())), static_cast(45 / (128 * root_two())), static_cast((9 / 16.0 + (45 * ln_two()) / 32) / (4 * root_two())), static_cast((-25 / 2.0 + (9 * ln_two()) / 8 + - (45 * pow(ln_two(), 2)) / 32) / + (45 * pow(ln_two(), (T)2)) / 32) / (4 * root_two())), static_cast((-15 - (75 * ln_two()) / 2 + - (27 * pow(ln_two(), 2)) / 16 + - (45 * pow(ln_two(), 3)) / 32) / + (27 * pow(ln_two(), (T)2)) / 16 + + (45 * pow(ln_two(), (T)3)) / 32) / (4 * root_two())), - static_cast((60 - 60 * ln_two() - 75 * pow(ln_two(), 2) + - (9 * pow(ln_two(), 3)) / 4 + - (45 * pow(ln_two(), 4)) / 32) / + static_cast((60 - 60 * ln_two() - 75 * pow(ln_two(), (T)2) + + (9 * pow(ln_two(), (T)3)) / 4 + + (45 * pow(ln_two(), (T)4)) / 32) / (4 * root_two())), - static_cast((120 + 300 * ln_two() - 150 * pow(ln_two(), 2) - - 125 * pow(ln_two(), 3) + - (45 * pow(ln_two(), 4)) / 16 + - (45 * pow(ln_two(), 5)) / 32) / + static_cast((120 + 300 * ln_two() - 150 * pow(ln_two(), (T)2) - + 125 * pow(ln_two(), (T)3) + + (45 * pow(ln_two(), (T)4)) / 16 + + (45 * pow(ln_two(), (T)5)) / 32) / (4 * root_two()))}; std::size_t k = 0; for (auto i : boost::irange(m + 1)) { @@ -249,15 +249,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt_test, T, all_float_types) { std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE_FRACTION(y.derivative(1u), static_cast(0.5 * pow(cx, T(-0.5))), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(2u), static_cast(-0.5 * 0.5 * pow(cx, -1.5)), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(2u), static_cast(-0.5 * 0.5 * pow(cx, T(-1.5))), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(3u), static_cast(0.5 * 0.5 * 1.5 * pow(cx, -2.5)), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(3u), static_cast(0.5 * 0.5 * 1.5 * pow(cx, T(-2.5))), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE_FRACTION(y.derivative(4u), - static_cast(-0.5 * 0.5 * 1.5 * 2.5 * pow(cx, -3.5)), + static_cast(-0.5 * 0.5 * 1.5 * 2.5 * pow(cx, T(-3.5))), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE_FRACTION(y.derivative(5u), - static_cast(0.5 * 0.5 * 1.5 * 2.5 * 3.5 * pow(cx, -4.5)), + static_cast(0.5 * 0.5 * 1.5 * 2.5 * 3.5 * pow(cx, T(-4.5))), std::numeric_limits::epsilon()); x = make_fvar(0); y = sqrt(x); @@ -280,13 +280,13 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(log_test, T, all_float_types) { std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE_FRACTION(y.derivative(1u), 1 / cx, std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(2u), -1 / pow(cx, 2), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(2u), -1 / pow(cx, T(2)), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(3u), 2 / pow(cx, 3), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(3u), 2 / pow(cx, T(3)), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(4u), -6 / pow(cx, 4), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(4u), -6 / pow(cx, T(4)), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE_FRACTION(y.derivative(5u), 24 / pow(cx, 5), + BOOST_CHECK_CLOSE_FRACTION(y.derivative(5u), 24 / pow(cx, T(5)), std::numeric_limits::epsilon()); x = make_fvar(0); y = log(x); @@ -317,11 +317,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ylogx, T, all_float_types) { for (auto i : boost::irange(1u, static_cast(m + 1))) { BOOST_CHECK_CLOSE(z.derivative(i, 0u), pow(-1, i - 1) * boost::math::factorial(i - 1) * cy / - pow(cx, i), + pow(cx, T(i)), eps); BOOST_CHECK_CLOSE( z.derivative(i, 1u), - pow(-1, i - 1) * boost::math::factorial(i - 1) / pow(cx, i), eps); + pow(T(-1), T(i - 1)) * boost::math::factorial(i - 1) / pow(cx, T(i)), eps); for (auto j : boost::irange(std::size_t(2), n + 1)) { BOOST_CHECK_EQUAL(z.derivative(i, j), 0u); } @@ -330,9 +330,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ylogx, T, all_float_types) { // RHS is confirmed by // https://www.wolframalpha.com/input/?i=D%5Bx%5Ey,%7Bx,2%7D,%7By,4%7D%5D+%2F.+%7Bx-%3E2.0,+y-%3E3.0%7D BOOST_CHECK_CLOSE(z1.derivative(2u, 4u), - pow(cx, cy - 2) * pow(log(cx), 2) * + pow(cx, cy - 2) * pow(log(cx), T(2)) * (4 * (2 * cy - 1) * log(cx) + (4 - 1) * 4 + - (cy - 1) * cy * pow(log(cx), 2)), + (cy - 1) * cy * pow(log(cx), T(2))), eps); } @@ -404,13 +404,13 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(acos_test, T, bin_float_types) { auto y = acos(x); BOOST_CHECK_CLOSE(y.derivative(0u), acos(cx), eps); BOOST_CHECK_CLOSE(y.derivative(1u), -1 / sqrt(1 - cx * cx), eps); - BOOST_CHECK_CLOSE(y.derivative(2u), static_cast(-cx / pow(1 - cx * cx, 1.5)), eps); + BOOST_CHECK_CLOSE(y.derivative(2u), static_cast(-cx / pow(1 - cx * cx, T(1.5))), eps); BOOST_CHECK_CLOSE(y.derivative(3u), - static_cast(-(2 * cx * cx + 1) / pow(1 - cx * cx, 2.5)), eps); + static_cast(-(2 * cx * cx + 1) / pow(1 - cx * cx, T(2.5))), eps); BOOST_CHECK_CLOSE(y.derivative(4u), - static_cast(-3 * cx * (2 * cx * cx + 3) / pow(1 - cx * cx, 3.5)), eps); + static_cast(-3 * cx * (2 * cx * cx + 3) / pow(1 - cx * cx, T(3.5))), eps); BOOST_CHECK_CLOSE(y.derivative(5u), - static_cast(-(24 * (cx * cx + 3) * cx * cx + 9) / pow(1 - cx * cx, 4.5)), + static_cast(-(24 * (cx * cx + 3) * cx * cx + 9) / pow(1 - cx * cx, T(4.5))), eps); } From ff1a265e45d5ed949cd01c1e1517ead75b2dffb4 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 31 May 2023 17:06:05 +0200 Subject: [PATCH 42/53] Add to test_constants --- test/test_constants.cpp | 263 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) diff --git a/test/test_constants.cpp b/test/test_constants.cpp index 3017722056..c072a9c0f7 100644 --- a/test/test_constants.cpp +++ b/test/test_constants.cpp @@ -27,6 +27,10 @@ #include #include +#if __has_include() +# include +#endif + #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) #include // Check at compile time that the construction method for constants of type float, is "construct from a float", or "construct from a double", ... @@ -347,6 +351,128 @@ void test_float_spots() CHECK_ULP_CLOSE(4.66920160910299067185320382046620161725F, first_feigenbaum, 1); } // template void test_spots(RealType) +#ifdef __STDCPP_FLOAT32_T__ + +void test_f32_spots() +{ + // Basic sanity checks for constants in boost::math::float_constants:: + // for example: boost::math::float_constants::pi + // (rather than boost::math::constants::pi() ). + using namespace boost::math::float_constants; + BOOST_MATH_STD_USING + + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32), pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F32)), root_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F32/2)), root_half_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F32 * 2)), root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F32))), root_ln_four, 2); + CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995F32), e, 2); + CHECK_ULP_CLOSE(static_cast(0.5), half, 2); + CHECK_ULP_CLOSE(static_cast(0.57721566490153286060651209008240243104259335F32), euler, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2.0F32)), root_two, 2); + CHECK_ULP_CLOSE(static_cast(log(2.0F32)), ln_two, 2); + CHECK_ULP_CLOSE(static_cast(log(log(2.0F32))), ln_ln_two, 2); + CHECK_ULP_CLOSE(static_cast(1)/3, third, 2); + CHECK_ULP_CLOSE(static_cast(2)/3, twothirds, 2); + CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510F32), pi_minus_three, 2); + CHECK_ULP_CLOSE(static_cast(4.F32 - 3.14159265358979323846264338327950288419716939937510F32), four_minus_pi, 2); +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F32), 2.71828182845904523536028747135266249775724709369995F32)), pi_pow_e, 2); + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F32), 0.33333333333333333333333333333333333333333333333333F32)), cbrt_pi, 2); + CHECK_ULP_CLOSE(static_cast(exp(-0.5F32)), exp_minus_half, 2); + CHECK_ULP_CLOSE(static_cast(pow(2.71828182845904523536028747135266249775724709369995F32, 3.14159265358979323846264338327950288419716939937510F32)), e_pow_pi, 2); + + +#else // Only double, so no suffix F32. + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333)), cbrt_pi, 2); + CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); +#endif + // Rational fractions. + CHECK_ULP_CLOSE(static_cast(0.333333333333333333333333333333333333333F32), third, 2); + CHECK_ULP_CLOSE(static_cast(0.666666666666666666666666666666666666667F32), two_thirds, 2); + CHECK_ULP_CLOSE(static_cast(0.75F32), three_quarters, 2); + // Two and related. + CHECK_ULP_CLOSE(static_cast(sqrt(2.F32)), root_two, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.F32)), root_three, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2.F32)/2), half_root_two, 2); + CHECK_ULP_CLOSE(static_cast(log(2.F32)), ln_two, 2); + CHECK_ULP_CLOSE(static_cast(log(log(2.0F32))), ln_ln_two, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F32))), root_ln_four, 2); + CHECK_ULP_CLOSE(static_cast(1/sqrt(2.0F32)), one_div_root_two, 2); + + // pi. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32), pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32/2), half_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32/4), quarter_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32/3), third_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32/6), sixth_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 * 3.14159265358979323846264338327950288419716939937510F32), two_pi, 2); + CHECK_ULP_CLOSE(static_cast(3 * 3.14159265358979323846264338327950288419716939937510F32 / 4), three_quarters_pi, 2); + CHECK_ULP_CLOSE(static_cast(4 * 3.14159265358979323846264338327950288419716939937510F32 / 3), four_thirds_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / (3.14159265358979323846264338327950288419716939937510F32)), one_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 / (3.14159265358979323846264338327950288419716939937510F32)), two_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / (2 * 3.14159265358979323846264338327950288419716939937510F32)), one_div_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F32)), root_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F32 / 2)), root_half_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2 * 3.14159265358979323846264338327950288419716939937510F32)), root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / sqrt(3.14159265358979323846264338327950288419716939937510F32)), one_div_root_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 / sqrt(3.14159265358979323846264338327950288419716939937510F32)), two_div_root_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510F32)), one_div_root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(1. / 3.14159265358979323846264338327950288419716939937510F32)), root_one_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L - 3.L), pi_minus_three, 4 * 2 ); // 4 * 2 because of cancellation loss. + CHECK_ULP_CLOSE(static_cast(4.L - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi, 4 ); + // + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F32), 2.71828182845904523536028747135266249775724709369995F32)), pi_pow_e, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32 * 3.14159265358979323846264338327950288419716939937510F32), pi_sqr, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32 * 3.14159265358979323846264338327950288419716939937510F32/6), pi_sqr_div_six, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32 * 3.14159265358979323846264338327950288419716939937510F32 * 3.14159265358979323846264338327950288419716939937510F32), pi_cubed, 2); // See above. + + // CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F32 * 3.14159265358979323846264338327950288419716939937510F32), cbrt_pi, 2); // See above. + CHECK_ULP_CLOSE(cbrt_pi * cbrt_pi * cbrt_pi, pi, 2); + CHECK_ULP_CLOSE((static_cast(1)/cbrt_pi), one_div_cbrt_pi, 2); + + // Euler + CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995F32), e, 2); + + //CHECK_ULP_CLOSE(static_cast(exp(-0.5F32)), exp_minus_half, 2); // See above. + CHECK_ULP_CLOSE(pow(e, pi), e_pow_pi, 2); // See also above. + CHECK_ULP_CLOSE(sqrt(e), root_e, 2); + CHECK_ULP_CLOSE(log10(e), log10_e, 2); + CHECK_ULP_CLOSE(static_cast(1)/log10(e), one_div_log10_e, 2); + + // Trigonometric + CHECK_ULP_CLOSE(pi/180, degree, 2); + CHECK_ULP_CLOSE(180 / pi, radian, 2); + CHECK_ULP_CLOSE(sin(1.F32), sin_one, 2); + CHECK_ULP_CLOSE(cos(1.F32), cos_one, 2); + CHECK_ULP_CLOSE(sinh(1.F32), sinh_one, 2); + CHECK_ULP_CLOSE(cosh(1.F32), cosh_one, 2); + + // Phi + CHECK_ULP_CLOSE((1.F32 + sqrt(5.F32)) /2, phi, 2); + CHECK_ULP_CLOSE(log((1.F32 + sqrt(5.F32)) /2), ln_phi, 2); + CHECK_ULP_CLOSE(1.F32 / log((1.F32 + sqrt(5.F32)) /2), one_div_ln_phi, 2); + + // Euler's Gamma + CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F32, euler, 2); // (sequence A001620 in OEIS). + CHECK_ULP_CLOSE(1.F32/ 0.57721566490153286060651209008240243104215933593992F32, one_div_euler, 2); // (from sequence A001620 in OEIS). + CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F32 * 0.57721566490153286060651209008240243104215933593992F32, euler_sqr, 2); // (from sequence A001620 in OEIS). + + // Misc + CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206F32, zeta_two, 2); // A013661 as a constant (usually base 10) in OEIS. + CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227F32, zeta_three, 2); // (sequence A002117 in OEIS) + CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213F32, catalan, 2); // A006752 as a constant in OEIS. + CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150F32, extreme_value_skewness, 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] + CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067F32, rayleigh_skewness, 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] + CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01F32, rayleigh_kurtosis_excess, 2); + CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515F32, khinchin, 4 ); // A002210 as a constant https://oeis.org/A002210/constant + CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011F32, glaisher, 4 ); // https://oeis.org/A074962/constant + CHECK_ULP_CLOSE(4.66920160910299067185320382046620161725F32, first_feigenbaum, 1); +} // template void test_spots(RealType) + +#endif + void test_double_spots() { // Basic sanity checks for constants in boost::math::double_constants:: @@ -465,6 +591,126 @@ void test_double_spots() } // template void test_spots(RealType) +#ifdef __STDCPP_FLOAT64_T__ +void test_f64_spots() +{ + // Basic sanity checks for constants in boost::math::double_constants:: + // for example: boost::math::double_constants::pi + // (rather than boost::math::constants::pi() ). + using namespace boost::math::double_constants; + BOOST_MATH_STD_USING + + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64), pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F64)), root_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F64/2)), root_half_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F64 * 2)), root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F64))), root_ln_four, 2); + CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995F64), e, 2); + CHECK_ULP_CLOSE(static_cast(0.5F64), half, 2); + CHECK_ULP_CLOSE(static_cast(0.57721566490153286060651209008240243104259335F64), euler, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2.0F64)), root_two, 2); + CHECK_ULP_CLOSE(static_cast(log(2.0F64)), ln_two, 2); + CHECK_ULP_CLOSE(static_cast(log(log(2.0F64))), ln_ln_two, 2); + CHECK_ULP_CLOSE(static_cast(1)/3, third, 2); + CHECK_ULP_CLOSE(static_cast(2)/3, twothirds, 2); + CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510F64), pi_minus_three, 2); + CHECK_ULP_CLOSE(static_cast(4.F64 - 3.14159265358979323846264338327950288419716939937510F64), four_minus_pi, 2); +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F64), 2.71828182845904523536028747135266249775724709369995F64)), pi_pow_e, 2); + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F64), 0.33333333333333333333333333333333333333333333333333F64)), cbrt_pi, 2); + CHECK_ULP_CLOSE(static_cast(exp(-0.5F64)), exp_minus_half, 2); + CHECK_ULP_CLOSE(static_cast(pow(2.71828182845904523536028747135266249775724709369995F64, 3.14159265358979323846264338327950288419716939937510F64)), e_pow_pi, 2); + + +#else // Only double, so no suffix . + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F64), 2.71828182845904523536028747135266249775724709369995F64)), pi_pow_e, 2); + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F64), 0.33333333333333333333333333333333333333333333333333F64)), cbrt_pi, 2); + CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); +#endif + // Rational fractions. + CHECK_ULP_CLOSE(static_cast(0.333333333333333333333333333333333333333F64), third, 2); + CHECK_ULP_CLOSE(static_cast(0.666666666666666666666666666666666666667F64), two_thirds, 2); + CHECK_ULP_CLOSE(static_cast(0.75), three_quarters, 2); + // Two and related. + CHECK_ULP_CLOSE(static_cast(sqrt(2.F64)), root_two, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.F64)), root_three, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2.F64)/2), half_root_two, 2); + CHECK_ULP_CLOSE(static_cast(log(2.F64)), ln_two, 2); + CHECK_ULP_CLOSE(static_cast(log(log(2.0F64))), ln_ln_two, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F64))), root_ln_four, 2); + CHECK_ULP_CLOSE(static_cast(1/sqrt(2.0F64)), one_div_root_two, 2); + + // pi. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64), pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64/2), half_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64/4), quarter_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64/3), third_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64/6), sixth_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 * 3.14159265358979323846264338327950288419716939937510F64), two_pi, 2); + CHECK_ULP_CLOSE(static_cast(3 * 3.14159265358979323846264338327950288419716939937510F64 / 4), three_quarters_pi, 2); + CHECK_ULP_CLOSE(static_cast(4 * 3.14159265358979323846264338327950288419716939937510F64 / 3), four_thirds_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / (3.14159265358979323846264338327950288419716939937510F64)), one_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 / (3.14159265358979323846264338327950288419716939937510F64)), two_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / (2 * 3.14159265358979323846264338327950288419716939937510F64)), one_div_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F64)), root_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F64 / 2)), root_half_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(2 * 3.14159265358979323846264338327950288419716939937510F64)), root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / sqrt(3.14159265358979323846264338327950288419716939937510F64)), one_div_root_pi, 2); + CHECK_ULP_CLOSE(static_cast(2 / sqrt(3.14159265358979323846264338327950288419716939937510F64)), two_div_root_pi, 2); + CHECK_ULP_CLOSE(static_cast(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510F64)), one_div_root_two_pi, 2); + CHECK_ULP_CLOSE(static_cast(sqrt(1. / 3.14159265358979323846264338327950288419716939937510F64)), root_one_div_pi, 2); + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64 - 3.F64), pi_minus_three, 4 * 2 ); // 4 * 2 because of cancellation loss. + CHECK_ULP_CLOSE(static_cast(4.F64 - 3.14159265358979323846264338327950288419716939937510F64), four_minus_pi, 4 ); + // + CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F64), 2.71828182845904523536028747135266249775724709369995F64)), pi_pow_e, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64 * 3.14159265358979323846264338327950288419716939937510F64), pi_sqr, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64 * 3.14159265358979323846264338327950288419716939937510F64/6), pi_sqr_div_six, 2); // See above. + CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F64 * 3.14159265358979323846264338327950288419716939937510F64 * 3.14159265358979323846264338327950288419716939937510F64), pi_cubed, 2); // See above. + + // CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510), cbrt_pi, 2); // See above. + CHECK_ULP_CLOSE(cbrt_pi * cbrt_pi * cbrt_pi, pi, 2); + CHECK_ULP_CLOSE((static_cast(1)/cbrt_pi), one_div_cbrt_pi, 2); + + // Euler + CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995), e, 2); + + //CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); // See above. + CHECK_ULP_CLOSE(pow(e, pi), e_pow_pi, 2); // See also above. + CHECK_ULP_CLOSE(sqrt(e), root_e, 2); + CHECK_ULP_CLOSE(log10(e), log10_e, 2); + CHECK_ULP_CLOSE(static_cast(1)/log10(e), one_div_log10_e, 2); + + // Trigonometric + CHECK_ULP_CLOSE(pi/180, degree, 2); + CHECK_ULP_CLOSE(180 / pi, radian, 2); + CHECK_ULP_CLOSE(sin(1.F64), sin_one, 2); + CHECK_ULP_CLOSE(cos(1.F64), cos_one, 2); + CHECK_ULP_CLOSE(sinh(1.F64), sinh_one, 2); + CHECK_ULP_CLOSE(cosh(1.F64), cosh_one, 2); + + // Phi + CHECK_ULP_CLOSE((1.F64 + sqrt(5.F64)) /2, phi, 2); + CHECK_ULP_CLOSE(log((1.F64 + sqrt(5.F64)) /2), ln_phi, 2); + CHECK_ULP_CLOSE(1.F64 / log((1.F64 + sqrt(5.F64)) /2), one_div_ln_phi, 2); + + //Euler's Gamma + CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F64, euler, 2); // (sequence A001620 in OEIS). + CHECK_ULP_CLOSE(1.F64/ 0.57721566490153286060651209008240243104215933593992F64, one_div_euler, 2); // (from sequence A001620 in OEIS). + CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F64 * 0.57721566490153286060651209008240243104215933593992F64, euler_sqr, 2); // (from sequence A001620 in OEIS). + + // Misc + CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206F64, zeta_two, 2); // A013661 as a constant (usually base 10) in OEIS. + CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227F64, zeta_three, 2); // (sequence A002117 in OEIS) + CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213F64, catalan, 2); // A006752 as a constant in OEIS. + CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150F64, extreme_value_skewness, 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] + CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067F64, rayleigh_skewness, 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] + CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01F64, rayleigh_kurtosis_excess, 2); + CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515F64, khinchin, 4 ); // A002210 as a constant https://oeis.org/A002210/constant + CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011F64, glaisher, 4 ); // https://oeis.org/A074962/constant + +} // template void test_spots(RealType) +#endif + void test_long_double_spots() { // Basic sanity checks for constants in boost::math::long double_constants:: @@ -829,9 +1075,20 @@ void test_laplace_limit() int main() { // Basic sanity-check spot values. + #ifdef __STDCPP_FLOAT32_T__ + test_f32_spots(); + #else test_float_spots(); // Test float_constants, like boost::math::float_constants::pi; + #endif + + #ifdef __STDCPP_FLOAT64_T__ + test_f64_spots(); + #else test_double_spots(); // Test double_constants. + #endif + test_long_double_spots(); // Test long_double_constants. + #ifdef BOOST_MATH_HAS_FLOAT128 test_float128(); #endif @@ -841,6 +1098,12 @@ int main() test_spots(0.0F); // Test float. test_spots(0.0); // Test double. test_spots(0.0L); // Test long double. + #ifdef __STDCPP_FLOAT32_T__ + test_spots(0.0F32); + #endif + #ifdef __STDCPP_FLOAT64_T__ + test_spots(0.0F64); + #endif #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) test_feigenbaum(); From a6bc6c7c8002b6a0dfdc228b5a450f98cb7f44e3 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 5 Jun 2023 14:21:53 +0200 Subject: [PATCH 43/53] Add constructor to real_concept --- include/boost/math/concepts/real_concept.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/boost/math/concepts/real_concept.hpp b/include/boost/math/concepts/real_concept.hpp index 446bfa8d5a..56e4342e6b 100644 --- a/include/boost/math/concepts/real_concept.hpp +++ b/include/boost/math/concepts/real_concept.hpp @@ -45,6 +45,10 @@ # include #endif +#if __has_include() +# include +#endif + namespace boost{ namespace math{ namespace concepts @@ -79,6 +83,12 @@ class real_concept #ifdef BOOST_MATH_USE_FLOAT128 real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){} #endif +#ifdef __STDCPP_FLOAT32_T__ + real_concept(std::float32_t c) : m_value(static_cast(c)){} +#endif +#ifdef __STDCPP_FLOAT64_T__ + real_concept(std::float64_t c) : m_value(static_cast(c)){} +#endif // Assignment: real_concept& operator=(char c) { m_value = c; return *this; } @@ -96,6 +106,12 @@ class real_concept real_concept& operator=(float c) { m_value = c; return *this; } real_concept& operator=(double c) { m_value = c; return *this; } real_concept& operator=(long double c) { m_value = c; return *this; } + #ifdef __STDCPP_FLOAT32_T__ + real_concept& operator=(std::float32_t c) { m_value = c; return *this; } + #endif + #ifdef __STDCPP_FLOAT64_T__ + real_concept& operator=(std::float64_t c) { m_value = c; return *this; } + #endif // Access: real_concept_base_type value()const{ return m_value; } From bc9d4b1218d803cb3687777e7d09ebda5dcaea9b Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 5 Jun 2023 14:25:07 +0200 Subject: [PATCH 44/53] Fix failures and warnings in test_autodiff_6 --- .../detail/igamma_inverse.hpp | 16 ++++---- .../math/special_functions/ellint_rj.hpp | 4 +- include/boost/math/special_functions/erf.hpp | 4 +- .../boost/math/special_functions/expint.hpp | 4 +- .../boost/math/special_functions/gamma.hpp | 38 +++++++++---------- .../math/special_functions/lambert_w.hpp | 7 +--- 6 files changed, 35 insertions(+), 38 deletions(-) diff --git a/include/boost/math/special_functions/detail/igamma_inverse.hpp b/include/boost/math/special_functions/detail/igamma_inverse.hpp index 51c2b1c6c3..f6bbcd72d5 100644 --- a/include/boost/math/special_functions/detail/igamma_inverse.hpp +++ b/include/boost/math/special_functions/detail/igamma_inverse.hpp @@ -33,7 +33,7 @@ T find_inverse_s(T p, T q) // BOOST_MATH_STD_USING T t; - if(p < 0.5) + if(p < T(0.5)) { t = sqrt(-2 * log(p)); } @@ -44,7 +44,7 @@ T find_inverse_s(T p, T q) static const double a[4] = { 3.31125922108741, 11.6616720288968, 4.28342155967104, 0.213623493715853 }; static const double b[5] = { 1, 6.61053765625462, 6.40691597760039, 1.27364489782223, 0.3611708101884203e-1 }; T s = t - tools::evaluate_polynomial(a, t) / tools::evaluate_polynomial(b, t); - if(p < 0.5) + if(p < T(0.5)) s = -s; return s; } @@ -120,7 +120,7 @@ T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) T b = q * g; BOOST_MATH_INSTRUMENT_VARIABLE(g); BOOST_MATH_INSTRUMENT_VARIABLE(b); - if((b > 0.6) || ((b >= 0.45) && (a >= 0.3))) + if((b >T(0.6)) || ((b >= T(0.45)) && (a >= T(0.3)))) { // DiDonato & Morris Eq 21: // @@ -130,7 +130,7 @@ T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) // q. Fortunately the second form works perfectly well in this case. // T u; - if((b * q > 1e-8) && (q > 1e-5)) + if((b * q > T(1e-8)) && (q > T(1e-5))) { u = pow(p * g * a, 1 / a); BOOST_MATH_INSTRUMENT_VARIABLE(u); @@ -236,7 +236,7 @@ T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) T D = (std::max)(T(2), T(a * (a - 1))); T lg = boost::math::lgamma(a, pol); T lb = log(q) + lg; - if(lb < -D * 2.3) + if(lb < -D * T(2.3)) { // DiDonato and Morris Eq 25: T y = -lb; @@ -293,7 +293,7 @@ T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) if((z <= 0.01 * ap1) || (z > 0.7 * ap1)) { result = z; - if(z <= 0.002 * ap1) + if(z <= T(0.002) * ap1) *p_has_10_digits = true; BOOST_MATH_INSTRUMENT_VARIABLE(result); } @@ -326,7 +326,7 @@ struct gamma_p_inverse_func // be inaccurate anyway (because there's not enough information in p) // but at least we will converge on the (inaccurate) answer quickly. // - if(p > 0.9) + if(p > T(0.9)) { p = 1 - p; invert = !invert; @@ -437,7 +437,7 @@ T gamma_p_inv_imp(T a, T p, const Policy& pol) digits /= 2; digits -= 1; } - if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) + if((a < T(0.125)) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) digits = policies::digits() - 2; // // Go ahead and iterate: diff --git a/include/boost/math/special_functions/ellint_rj.hpp b/include/boost/math/special_functions/ellint_rj.hpp index 310cfafca6..7142233219 100644 --- a/include/boost/math/special_functions/ellint_rj.hpp +++ b/include/boost/math/special_functions/ellint_rj.hpp @@ -62,7 +62,7 @@ T ellint_rc1p_imp(T y, const Policy& pol) } else { - if(y > -0.5) + if(y > T(-0.5)) { T arg = sqrt(-y); result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(-y)); @@ -180,7 +180,7 @@ T ellint_rj_imp(T x, T y, T z, T p, const Policy& pol) // y = z = p: return ellint_rd_imp(x, y, y, pol); } - else if((std::max)(y, p) / (std::min)(y, p) > 1.2) + else if((std::max)(y, p) / (std::min)(y, p) > T(1.2)) { // y = z: return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); diff --git a/include/boost/math/special_functions/erf.hpp b/include/boost/math/special_functions/erf.hpp index bcc53d1afc..447e6b61c4 100644 --- a/include/boost/math/special_functions/erf.hpp +++ b/include/boost/math/special_functions/erf.hpp @@ -322,7 +322,7 @@ T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& ta / tools::evaluate_polynomial(Q, t); t = (z - r1) - r2; result *= t; - if(fabs(t) < 0.1) + if(fabs(t) < T(0.1)) { result += boost::math::log1p(t / r, pol); } @@ -791,7 +791,7 @@ T expint_i_imp(T z, const Policy& pol, const std::integral_constant& ta / tools::evaluate_polynomial(Q, t); t = (z - r1) - r2; result *= t; - if(fabs(t) < 0.1) + if(fabs(t) < T(0.1)) { result += boost::math::log1p(t / r, pol); } diff --git a/include/boost/math/special_functions/gamma.hpp b/include/boost/math/special_functions/gamma.hpp index 13da394940..4af2ebdcfc 100644 --- a/include/boost/math/special_functions/gamma.hpp +++ b/include/boost/math/special_functions/gamma.hpp @@ -99,7 +99,7 @@ T sinpx(T z) dist = z - fl; } BOOST_MATH_ASSERT(fl >= 0); - if(dist > 0.5) + if(dist > T(0.5)) dist = 1 - dist; T result = sin(dist*boost::math::constants::pi()); return sign*z*result; @@ -175,7 +175,7 @@ T gamma_imp(T z, const Policy& pol, const Lanczos& l) BOOST_MATH_INSTRUMENT_VARIABLE(zgh); if(lzgh * z / 2 > tools::log_max_value()) return boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); - T hp = pow(zgh, (z / 2) - T(0.25)); + T hp = pow(zgh, T((z / 2) - T(0.25))); BOOST_MATH_INSTRUMENT_VARIABLE(hp); result *= hp / exp(zgh); BOOST_MATH_INSTRUMENT_VARIABLE(result); @@ -187,9 +187,9 @@ T gamma_imp(T z, const Policy& pol, const Lanczos& l) else { BOOST_MATH_INSTRUMENT_VARIABLE(zgh); - BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, z - boost::math::constants::half())); + BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, T(z - boost::math::constants::half()))); BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh)); - result *= pow(zgh, z - boost::math::constants::half()) / exp(zgh); + result *= pow(zgh, T(z - boost::math::constants::half())) / exp(zgh); BOOST_MATH_INSTRUMENT_VARIABLE(result); } } @@ -735,7 +735,7 @@ T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l) T result; if(dz < 0) { - if(dz < -0.5) + if(dz < T(-0.5)) { // Best method is simply to subtract 1 from tgamma: result = boost::math::tgamma(1+dz, pol) - 1; @@ -774,7 +774,7 @@ inline T tgammap1m1_imp(T z, Policy const& pol, { BOOST_MATH_STD_USING // ADL of std names - if(fabs(z) < 0.55) + if(fabs(z) < T(0.55)) { return boost::math::expm1(log_gamma_near_1(z, pol)); } @@ -826,7 +826,7 @@ T full_igamma_prefix(T a, T z, const Policy& pol) } else if(a >= 1) { - prefix = pow(z / exp(z/a), a); + prefix = pow(T(z / exp(z/a)), a); } else { @@ -841,7 +841,7 @@ T full_igamma_prefix(T a, T z, const Policy& pol) } else if(z/a < tools::log_max_value()) { - prefix = pow(z / exp(z/a), a); + prefix = pow(T(z / exp(z/a)), a); } else { @@ -927,7 +927,7 @@ T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l) } else if((amza > tools::log_min_value()) && (amza < tools::log_max_value())) { - prefix = pow((z * exp(amza)) / agh, a); + prefix = pow(T((z * exp(amza)) / agh), a); } else { @@ -936,7 +936,7 @@ T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l) } else { - prefix = pow(z / agh, a) * exp(amz); + prefix = pow(T(z / agh), a) * exp(amz); } } prefix *= sqrt(agh / boost::math::constants::e()) / Lanczos::lanczos_sum_expG_scaled(a); @@ -993,8 +993,8 @@ T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined // as we go. And again recurse down to the result. // T scaled_gamma = scaled_tgamma_no_lanczos(T(a + shift), pol); - T power_term_1 = pow(z / (a + shift), a); - T power_term_2 = pow(a + shift, -shift); + T power_term_1 = pow(T(z / (a + shift)), a); + T power_term_2 = pow(T(a + shift), T(-shift)); T power_term_3 = exp(a + shift - z); if ((0 == power_term_1) || (0 == power_term_2) || (0 == power_term_3) || (fabs(a + shift - z) > tools::log_max_value())) { @@ -1258,12 +1258,12 @@ T gamma_incomplete_imp(T a, T x, bool normalised, bool invert, invert = !invert; eval_method = 7; } - else if(x < 0.5) + else if(x < T(0.5)) { // // Changeover criterion chosen to give a changeover at Q ~ 0.33 // - if(-0.4 / log(x) < a) + if(T(-0.4) / log(x) < a) { eval_method = 2; } @@ -1272,7 +1272,7 @@ T gamma_incomplete_imp(T a, T x, bool normalised, bool invert, eval_method = 3; } } - else if(x < 1.1) + else if(x < T(1.1)) { // // Changeover here occurs when P ~ 0.75 or Q ~ 0.25: @@ -1552,7 +1552,7 @@ T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& return 1 / (z * boost::math::tgamma(z + delta, pol)); } } - T zgh = static_cast(z + Lanczos::g() - constants::half()); + T zgh = static_cast(z + T(Lanczos::g()) - constants::half()); T result; if(z + delta == z) { @@ -1577,12 +1577,12 @@ T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& } else { - result = pow(zgh / (zgh + delta), z - constants::half()); + result = pow(T(zgh / (zgh + delta)), T(z - constants::half())); } // Split the calculation up to avoid spurious overflow: result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta)); } - result *= pow(constants::e() / (zgh + delta), delta); + result *= pow(T(constants::e() / (zgh + delta)), delta); return result; } // @@ -1617,7 +1617,7 @@ T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos: T scaled_tgamma_num = scaled_tgamma_no_lanczos(z, pol); T scaled_tgamma_denom = scaled_tgamma_no_lanczos(T(z + delta), pol); T result = scaled_tgamma_num / scaled_tgamma_denom; - result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow((delta + z) / constants::e(), -delta); + result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow(T((delta + z) / constants::e()), -delta); return result; } // diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index b19d889b83..8638cc75f2 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -1231,11 +1231,8 @@ T lambert_w_negative_rational_float(T z, const Policy& pol) T d = z + 0.367879441171442321595523770161460867445811f; return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); } - else - { - // z is very close (within 0.01) of the singularity at e^-1. - return lambert_w_singularity_series(get_near_singularity_param(z, pol)); - } + + return lambert_w_singularity_series(get_near_singularity_param(z, pol)); } //! Lambert_w0 @b 'float' implementation, selected when T is 32-bit precision. From 677f3b65829607d19bcdb5ae14cf3f54d3a8f7f6 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 5 Jun 2023 15:17:54 +0200 Subject: [PATCH 45/53] Collected fixes for test_autodiff_8 [ci skip] --- include/boost/math/special_functions/erf.hpp | 12 ++++++------ include/boost/math/special_functions/hermite.hpp | 3 ++- include/boost/math/special_functions/lambert_w.hpp | 12 ++++++------ include/boost/math/special_functions/sin_pi.hpp | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/boost/math/special_functions/erf.hpp b/include/boost/math/special_functions/erf.hpp index 447e6b61c4..5cc322ae4e 100644 --- a/include/boost/math/special_functions/erf.hpp +++ b/include/boost/math/special_functions/erf.hpp @@ -204,7 +204,7 @@ T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant inline typename tools::promote_args::type hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1) { - return (2 * x * Hn - 2 * n * Hnm1); + using promoted_type = tools::promote_args_t; + return (2 * promoted_type(x) * promoted_type(Hn) - 2 * n * promoted_type(Hnm1)); } namespace detail{ diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index 8638cc75f2..2c3722db34 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -1043,7 +1043,7 @@ T lambert_w_positive_rational_float(T z) BOOST_MATH_STD_USING if (z < 2) { - if (z < 0.5) + if (z < T(0.5)) { // 0.05 < z < 0.5 // Maximum Deviation Found: 2.993e-08 // Expected Error Term : 2.993e-08 @@ -1119,7 +1119,7 @@ T lambert_w_positive_rational_float(T z) }; return Y + boost::math::tools::evaluate_rational(P, Q, z); } - else if (z < 9897.12905874) // 2.8 < log(z) < 9.2 + else if (z < T(9897.12905874)) // 2.8 < log(z) < 9.2 { // Max error in interpolated form: 1.771e-08 static const T Y = -1.402973175e+00f; @@ -1139,7 +1139,7 @@ T lambert_w_positive_rational_float(T z) T log_w = log(z); return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); } - else if (z < 7.896296e+13) // 9.2 < log(z) <= 32 + else if (z < T(7.896296e+13)) // 9.2 < log(z) <= 32 { // Max error in interpolated form: 5.821e-08 static const T Y = -2.735729218e+00f; @@ -1184,9 +1184,9 @@ template T lambert_w_negative_rational_float(T z, const Policy& pol) { BOOST_MATH_STD_USING - if (z > -0.27) + if (z > T(-0.27)) { - if (z < -0.051) + if (z < T(-0.051)) { // -0.27 < z < -0.051 // Max error in interpolated form: 5.080e-08 @@ -1211,7 +1211,7 @@ T lambert_w_negative_rational_float(T z, const Policy& pol) return lambert_w0_small_z(z, pol); } } - else if (z > -0.3578794411714423215955237701) + else if (z > T(-0.3578794411714423215955237701)) { // Very close to branch singularity. // Max error in interpolated form: 5.269e-08 static const T Y = 1.220928431e-01f; diff --git a/include/boost/math/special_functions/sin_pi.hpp b/include/boost/math/special_functions/sin_pi.hpp index 78e9c4ea07..5b8eb6fcf2 100644 --- a/include/boost/math/special_functions/sin_pi.hpp +++ b/include/boost/math/special_functions/sin_pi.hpp @@ -27,7 +27,7 @@ inline T sin_pi_imp(T x, const Policy& pol) if(x < 0) return -sin_pi_imp(T(-x), pol); // sin of pi*x: - if(x < 0.5) + if(x < T(0.5)) return sin(constants::pi() * x); bool invert; if(x < 1) From 7a0e8e02ed29c7e249dba8b8e0efc86862c13a5c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 16 Jun 2023 10:42:22 +0200 Subject: [PATCH 46/53] More casting of pow --- include/boost/math/special_functions/beta.hpp | 6 +++--- include/boost/math/special_functions/chebyshev.hpp | 2 +- .../math/special_functions/detail/bessel_jy_asym.hpp | 2 +- .../math/special_functions/detail/bessel_jy_series.hpp | 2 +- .../detail/hypergeometric_1F1_bessel.hpp | 8 ++++---- .../detail/hypergeometric_pFq_checked_series.hpp | 2 +- include/boost/math/special_functions/detail/polygamma.hpp | 8 ++++---- .../boost/math/special_functions/hypergeometric_2F0.hpp | 2 +- include/boost/math/special_functions/lambert_w.hpp | 2 +- include/boost/math/special_functions/owens_t.hpp | 4 ++-- include/boost/math/special_functions/zeta.hpp | 4 ++-- include/boost/math/tools/series.hpp | 2 +- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/boost/math/special_functions/beta.hpp b/include/boost/math/special_functions/beta.hpp index f566f2afe1..e2aec27b01 100644 --- a/include/boost/math/special_functions/beta.hpp +++ b/include/boost/math/special_functions/beta.hpp @@ -586,7 +586,7 @@ T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool normalised, T* p_deriva if(a * b < bgh * 10) result *= exp((b - 0.5f) * boost::math::log1p(a / bgh, pol)); else - result *= pow(cgh / bgh, b - 0.5f); + result *= pow(cgh / bgh, T(b - 0.5f)); result *= pow(x * cgh / agh, a); result *= sqrt(agh / boost::math::constants::e()); @@ -963,14 +963,14 @@ T binomial_ccdf(T n, T k, T x, T y, const Policy& pol) int start = itrunc(n * x); if(start <= k + 1) start = itrunc(k + 2); - result = static_cast(pow(x, start) * pow(y, n - start) * boost::math::binomial_coefficient(itrunc(n), itrunc(start), pol)); + result = static_cast(pow(x, T(start)) * pow(y, n - T(start)) * boost::math::binomial_coefficient(itrunc(n), itrunc(start), pol)); if(result == 0) { // OK, starting slightly above the mode didn't work, // we'll have to sum the terms the old fashioned way: for(unsigned i = start - 1; i > k; --i) { - result += static_cast(pow(x, static_cast(i)) * pow(y, n - i) * boost::math::binomial_coefficient(itrunc(n), itrunc(i), pol)); + result += static_cast(pow(x, static_cast(i)) * pow(y, n - i) * boost::math::binomial_coefficient(itrunc(n), itrunc(i), pol)); } } else diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index dc414a37cc..c12d15e17c 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -51,7 +51,7 @@ inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) if (x > 1 || x < -1) { Real t = sqrt(x*x -1); - return static_cast((pow(x+t, static_cast(n+1)) - pow(x-t, static_cast(n+1)))/(2*t)); + return static_cast((pow(x+t, static_cast(n+1)) - pow(x-t, static_cast(n+1)))/(2*t)); } T1 = 2*x; } diff --git a/include/boost/math/special_functions/detail/bessel_jy_asym.hpp b/include/boost/math/special_functions/detail/bessel_jy_asym.hpp index f3198565ff..16b6543f90 100644 --- a/include/boost/math/special_functions/detail/bessel_jy_asym.hpp +++ b/include/boost/math/special_functions/detail/bessel_jy_asym.hpp @@ -175,7 +175,7 @@ void temme_asymptotic_y_small_x(T v, T x, T* Y, T* Y1, const Policy& pol) p /= k - v; q /= k + v; c *= c_mult / k; - T c1 = pow(-x * x / 4, k) / factorial(k, pol); + T c1 = pow(-x * x / 4, T(k)) / factorial(k, pol); g = f + g_prefix * q; h = -k * g + p; y += c * g; diff --git a/include/boost/math/special_functions/detail/bessel_jy_series.hpp b/include/boost/math/special_functions/detail/bessel_jy_series.hpp index 5e9ffea45b..f397105b1b 100644 --- a/include/boost/math/special_functions/detail/bessel_jy_series.hpp +++ b/include/boost/math/special_functions/detail/bessel_jy_series.hpp @@ -236,7 +236,7 @@ T bessel_yn_small_z(int n, T z, T* scale, const Policy& pol) } else { - auto p = static_cast(pow(z / 2, n)); + auto p = static_cast(pow(z / 2, T(n))); T result = -((boost::math::factorial(n - 1, pol) / constants::pi())); if(p * tools::max_value() < result) { diff --git a/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp b/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp index bc28c5a73d..763b2fa1b1 100644 --- a/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp +++ b/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp @@ -184,7 +184,7 @@ // if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) { - T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2); + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), T(j + 1)) * 2); if (!((boost::math::isfinite)(rescale))) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) @@ -259,7 +259,7 @@ // if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) { - T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2); + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), T(j + 1)) * 2); if (!((boost::math::isfinite)(rescale))) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) @@ -558,7 +558,7 @@ // if((j < cache_size - 2) && (bessel_i_cache[j + 1] != 0) && (tools::max_value() / fabs(64 * bessel_i_cache[j] / bessel_i_cache[j + 1]) < fabs(bessel_i_cache[j]))) { - T rescale = static_cast(pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), j + 1) * 2); + T rescale = static_cast(pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), T(j + 1)) * 2); if (rescale > tools::max_value()) rescale = tools::max_value(); for (int k = j; k < cache_size; ++k) @@ -591,7 +591,7 @@ std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_6<%1%>(%1%,%1%,%1%)", max_iter, pol); - result *= boost::math::tgamma(b_minus_a - 0.5f, pol) * pow(z / 4, -b_minus_a + 0.5f); + result *= boost::math::tgamma(b_minus_a - 0.5f, pol) * pow(z / 4, -b_minus_a + T(0.5f)); long long scale = lltrunc(z / 2); log_scaling += scale; log_scaling += s.scaling(); diff --git a/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp b/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp index 03b7af11a4..566dd24a0f 100644 --- a/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp +++ b/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp @@ -146,7 +146,7 @@ return std::make_pair(r, r); } std::pair r = hypergeometric_pFq_checked_series_impl(aj, bj, Real(1 / z), pol, termination, log_scale); - Real mul = pow(-z, -*aj.begin()); + Real mul = pow(-z, Real(-*aj.begin())); r.first *= mul; r.second *= mul; return r; diff --git a/include/boost/math/special_functions/detail/polygamma.hpp b/include/boost/math/special_functions/detail/polygamma.hpp index f950fe2634..8c11f40aed 100644 --- a/include/boost/math/special_functions/detail/polygamma.hpp +++ b/include/boost/math/special_functions/detail/polygamma.hpp @@ -53,7 +53,7 @@ namespace boost { namespace math { namespace detail{ if(n == 1) return 1 / x; T nlx = n * log(x); if((nlx < tools::log_max_value()) && (n < (int)max_factorial::value)) - return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * static_cast(pow(x, -n)); + return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * static_cast(pow(x, T(-n))); else return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x)); } @@ -80,7 +80,7 @@ namespace boost { namespace math { namespace detail{ // know that we have to use logs for the initial terms: // part_term = ((n > (int)boost::math::max_factorial::value) && (T(n) * n > tools::log_max_value())) - ? T(0) : static_cast(boost::math::factorial(n - 1, pol) * pow(x, -n - 1)); + ? T(0) : static_cast(boost::math::factorial(n - 1, pol) * pow(x, T(-n - 1))); if(part_term == 0) { // Either n is very large, or the power term underflows, @@ -159,7 +159,7 @@ namespace boost { namespace math { namespace detail{ { for(int k = 1; k <= iter; ++k) { - z_plus_k_pow_minus_m_minus_one = static_cast(pow(z, minus_m_minus_one)); + z_plus_k_pow_minus_m_minus_one = static_cast(pow(z, T(minus_m_minus_one))); sum0 += z_plus_k_pow_minus_m_minus_one; z += 1; } @@ -203,7 +203,7 @@ namespace boost { namespace math { namespace detail{ // be n! / z^(n+1), but since we're scaling by n! it's just // 1 / z^(n+1) for now: // - T prefix = static_cast(pow(x, n + 1)); // Warning supression: Integer power returns at least a double + T prefix = static_cast(pow(x, T(n + 1))); // Warning supression: Integer power returns at least a double if(prefix == 0) return boost::math::policies::raise_overflow_error(function, nullptr, pol); prefix = 1 / prefix; diff --git a/include/boost/math/special_functions/hypergeometric_2F0.hpp b/include/boost/math/special_functions/hypergeometric_2F0.hpp index 5d6e15e271..d22e6a029d 100644 --- a/include/boost/math/special_functions/hypergeometric_2F0.hpp +++ b/include/boost/math/special_functions/hypergeometric_2F0.hpp @@ -94,7 +94,7 @@ namespace boost { namespace math { namespace detail { // http://functions.wolfram.com/07.31.03.0083.01 int n = static_cast(static_cast(boost::math::lltrunc(-2 * a1))); T smz = sqrt(-z); - return static_cast(pow(2 / smz, -n) * boost::math::hermite(n, 1 / smz, pol)); // Warning suppression: integer power returns at least a double + return static_cast(pow(2 / smz, T(-n)) * boost::math::hermite(n, 1 / smz, pol)); // Warning suppression: integer power returns at least a double } if (is_a1_integer && is_a2_integer) diff --git a/include/boost/math/special_functions/lambert_w.hpp b/include/boost/math/special_functions/lambert_w.hpp index 2c3722db34..c57ce1d5bd 100644 --- a/include/boost/math/special_functions/lambert_w.hpp +++ b/include/boost/math/special_functions/lambert_w.hpp @@ -835,7 +835,7 @@ struct lambert_w0_small_z_series_term ++k; term *= -z / k; //T t = pow(z, k) * pow(T(k), -1 + k) / factorial(k); // (z^k * k(k-1)^k) / k! - T result = term * pow(T(k), -1 + k); // term * k^(k-1) + T result = term * pow(T(k), T(-1 + k)); // term * k^(k-1) // std::cout << " k = " << k << ", term = " << term << ", result = " << result << std::endl; return result; // } diff --git a/include/boost/math/special_functions/owens_t.hpp b/include/boost/math/special_functions/owens_t.hpp index d4fd3290b3..7a93246eee 100644 --- a/include/boost/math/special_functions/owens_t.hpp +++ b/include/boost/math/special_functions/owens_t.hpp @@ -588,7 +588,7 @@ namespace boost } #endif n = (std::min)(n, 1500); - T d = pow(3 + sqrt(T(8)), n); + T d = pow(3 + sqrt(T(8)), T(n)); d = (d + 1 / d) / 2; T b = -1; T c = -d; @@ -706,7 +706,7 @@ namespace boost } #endif n = (std::min)(n, 1500); - RealType d = pow(3 + sqrt(RealType(8)), n); + RealType d = pow(3 + sqrt(RealType(8)), RealType(n)); d = (d + 1 / d) / 2; RealType b = -1; RealType c = -d; diff --git a/include/boost/math/special_functions/zeta.hpp b/include/boost/math/special_functions/zeta.hpp index c18d2253d4..118aa7d352 100644 --- a/include/boost/math/special_functions/zeta.hpp +++ b/include/boost/math/special_functions/zeta.hpp @@ -956,9 +956,9 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) else if((v & 1) == 0) { if(((v / 2) <= (int)boost::math::max_bernoulli_b2n::value) && (v <= (int)boost::math::max_factorial::value)) - return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), v)) * + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), T(v))) * boost::math::unchecked_bernoulli_b2n(v / 2) / boost::math::unchecked_factorial(v); - return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), v)) * + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), T(v))) * boost::math::bernoulli_b2n(v / 2) / boost::math::factorial(v, pol); } else diff --git a/include/boost/math/tools/series.hpp b/include/boost/math/tools/series.hpp index 1809dfab11..a4822fea43 100644 --- a/include/boost/math/tools/series.hpp +++ b/include/boost/math/tools/series.hpp @@ -131,7 +131,7 @@ inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) n typedef typename Functor::result_type result_type; - result_type factor = pow(result_type(2), bits); + result_type factor = pow(result_type(2), result_type(bits)); result_type result = func(); result_type next_term, y, t; result_type carry = 0; From 37df734491774d9b39d5a8b590cbc47574531e6a Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 16 Jun 2023 16:00:30 +0200 Subject: [PATCH 47/53] Add integer exponent function to chebyshev detail --- .../math/special_functions/chebyshev.hpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index c12d15e17c..a0d78eb1cf 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -30,6 +30,24 @@ inline tools::promote_args_t chebyshev_next(T1 const & x, T2 const & namespace detail { +// https://stackoverflow.com/questions/5625431/efficient-way-to-compute-pq-exponentiation-where-q-is-an-integer +template +T expt(T p, unsigned q) +{ + T r(1); + + while (q != 0) { + if (q % 2 == 1) { // q is odd + r *= p; + q--; + } + p *= p; + q /= 2; + } + + return r; +} + template inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) { @@ -51,7 +69,7 @@ inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) if (x > 1 || x < -1) { Real t = sqrt(x*x -1); - return static_cast((pow(x+t, static_cast(n+1)) - pow(x-t, static_cast(n+1)))/(2*t)); + return static_cast((expt(x+t, n+1) - expt(x-t, n+1))/(2*t)); } T1 = 2*x; } From 0117f4a3fc2bd9c504b263ba82ad6ea9a5870090 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 16 Jun 2023 16:40:22 +0200 Subject: [PATCH 48/53] Fix multiprecision concept failure --- include/boost/math/special_functions/chebyshev.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index a0d78eb1cf..6cdf142e67 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -34,7 +34,7 @@ namespace detail { template T expt(T p, unsigned q) { - T r(1); + T r = 1; while (q != 0) { if (q % 2 == 1) { // q is odd From ef423e88f998f92189b36c9bcc04b78681779885 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 16 Jun 2023 16:44:35 +0200 Subject: [PATCH 49/53] Restore drone config --- .drone.star | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.drone.star b/.drone.star index cd1158e537..7b773dda7d 100644 --- a/.drone.star +++ b/.drone.star @@ -28,6 +28,39 @@ def main(ctx): result = [] + for suite in sanitizer_test: + # + # Sanitizers: + # + result.append(linux_cxx("Ubuntu g++-10 C++2a ASAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=address -fsanitize=address -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-10 C++2a USAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=undefined -fsanitize=undefined -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-10 C++2a TSAN" + " " + suite, "g++-10", packages="g++-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=thread -fsanitize=thread -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-10 C++2a ISAN" + " " + suite, "clang++-10", packages="clang-10", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': 'gnu++2a', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=integer -fsanitize=integer' }, globalenv=globalenv)) + + for suite in things_to_test: + for cxx in gnu_5_stds: + result.append(linux_cxx("Ubuntu g++-5 " + cxx + " " + suite, "g++-5", packages="g++-5", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_6_stds: + result.append(linux_cxx("Ubuntu g++-6 " + cxx + " " + suite, "g++-6", packages="g++-6", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-7 " + cxx + " " + suite, "g++-7", packages="g++-7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-8 " + cxx + " " + suite, "g++-8", packages="g++-8", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-9 " + cxx + " " + suite, "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in clang_6_stds: + result.append(linux_cxx("Ubuntu clang++-6 " + cxx + " " + suite, "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-7 " + cxx + " " + suite, "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-8 " + cxx + " " + suite, "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-9 " + cxx + " " + suite, "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_9_stds: + result.append(linux_cxx("Ubuntu g++-10 " + cxx + " " + suite, "g++-10", packages="g++-10", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-11 " + cxx + " " + suite, "g++-11", packages="g++-11", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-11', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in clang_10_stds: + result.append(linux_cxx("Ubuntu clang++-10 " + cxx + " " + suite, "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(linux_cxx("Ubuntu g++ s390s " + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="s390x", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(linux_cxx("Ubuntu g++ ARM64" + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="arm64", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(osx_cxx("M1 Clang " + cxx + " " + suite, "clang++", buildscript="drone", buildtype="boost", xcode_version="14.1", environment={'TOOLSET': 'clang', 'CXXSTD': cxx, 'TEST_SUITE': suite, 'DEFINE': 'BOOST_MATH_NO_REAL_CONCEPT_TESTS,BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS,BOOST_MATH_MULTI_ARCH_CI_RUN', }, globalenv=globalenv)) for suite in gcc13_things_to_test: for cxx in gcc13_stds: result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2304:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) From e62a284b440b9e4d6e8fe2c2b96dacab668df606 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 19 Jun 2023 09:36:29 +0200 Subject: [PATCH 50/53] Fix multiprecision failures --- include/boost/math/special_functions/chebyshev.hpp | 10 +++++++++- include/boost/math/special_functions/sqrt1pm1.hpp | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index 6cdf142e67..adfc6bcfeb 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -6,6 +6,7 @@ #ifndef BOOST_MATH_SPECIAL_CHEBYSHEV_HPP #define BOOST_MATH_SPECIAL_CHEBYSHEV_HPP #include +#include #include #include #include @@ -31,7 +32,7 @@ inline tools::promote_args_t chebyshev_next(T1 const & x, T2 const & namespace detail { // https://stackoverflow.com/questions/5625431/efficient-way-to-compute-pq-exponentiation-where-q-is-an-integer -template +template ::value, bool>::type = true> T expt(T p, unsigned q) { T r = 1; @@ -48,6 +49,13 @@ T expt(T p, unsigned q) return r; } +template ::value, bool>::type = true> +T expt(T p, unsigned q) +{ + using std::pow; + return static_cast(pow(p, q)); +} + template inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) { diff --git a/include/boost/math/special_functions/sqrt1pm1.hpp b/include/boost/math/special_functions/sqrt1pm1.hpp index 850a6aacea..293a9d97b3 100644 --- a/include/boost/math/special_functions/sqrt1pm1.hpp +++ b/include/boost/math/special_functions/sqrt1pm1.hpp @@ -26,7 +26,7 @@ inline typename tools::promote_args::type sqrt1pm1(const T& val, const Policy typedef typename tools::promote_args::type result_type; BOOST_MATH_STD_USING - if(fabs(result_type(val)) > T(0.75)) + if(fabs(result_type(val)) > 0.75) return sqrt(1 + result_type(val)) - 1; return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol); } From b57749d9c3cedfd37f9440913fa2704e853f5f18 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Jun 2023 12:01:47 +0200 Subject: [PATCH 51/53] Fix casting errors --- include/boost/math/special_functions/chebyshev.hpp | 2 +- include/boost/math/special_functions/sqrt1pm1.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index adfc6bcfeb..f6139220cf 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -53,7 +53,7 @@ template ::value, boo T expt(T p, unsigned q) { using std::pow; - return static_cast(pow(p, q)); + return pow(p, static_cast(q)); } template diff --git a/include/boost/math/special_functions/sqrt1pm1.hpp b/include/boost/math/special_functions/sqrt1pm1.hpp index 293a9d97b3..041916a53f 100644 --- a/include/boost/math/special_functions/sqrt1pm1.hpp +++ b/include/boost/math/special_functions/sqrt1pm1.hpp @@ -26,7 +26,7 @@ inline typename tools::promote_args::type sqrt1pm1(const T& val, const Policy typedef typename tools::promote_args::type result_type; BOOST_MATH_STD_USING - if(fabs(result_type(val)) > 0.75) + if(fabs(result_type(val)) > result_type(0.75)) return sqrt(1 + result_type(val)) - 1; return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol); } From 0a014fd5ca01429c05cf3145d7697eec49ae23cd Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 21 Jun 2023 08:56:02 +0100 Subject: [PATCH 52/53] Fix for expression template use in chebyshev.hpp. --- include/boost/math/special_functions/chebyshev.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/math/special_functions/chebyshev.hpp b/include/boost/math/special_functions/chebyshev.hpp index f6139220cf..2c6695446b 100644 --- a/include/boost/math/special_functions/chebyshev.hpp +++ b/include/boost/math/special_functions/chebyshev.hpp @@ -77,7 +77,7 @@ inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) if (x > 1 || x < -1) { Real t = sqrt(x*x -1); - return static_cast((expt(x+t, n+1) - expt(x-t, n+1))/(2*t)); + return static_cast((expt(static_cast(x+t), n+1) - expt(static_cast(x-t), n+1))/(2*t)); } T1 = 2*x; } From 851b3576155f02e1ba540fa9afaa3419d6b8bd4a Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 27 Jun 2023 16:03:43 +0200 Subject: [PATCH 53/53] Fix pessimization on unaffected platforms --- include/boost/math/special_functions/beta.hpp | 2 +- .../math/special_functions/detail/bessel_jy_series.hpp | 5 +++++ .../detail/hypergeometric_pFq_checked_series.hpp | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/boost/math/special_functions/beta.hpp b/include/boost/math/special_functions/beta.hpp index e2aec27b01..ec824daf72 100644 --- a/include/boost/math/special_functions/beta.hpp +++ b/include/boost/math/special_functions/beta.hpp @@ -586,7 +586,7 @@ T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool normalised, T* p_deriva if(a * b < bgh * 10) result *= exp((b - 0.5f) * boost::math::log1p(a / bgh, pol)); else - result *= pow(cgh / bgh, T(b - 0.5f)); + result *= pow(cgh / bgh, T(b - T(0.5))); result *= pow(x * cgh / agh, a); result *= sqrt(agh / boost::math::constants::e()); diff --git a/include/boost/math/special_functions/detail/bessel_jy_series.hpp b/include/boost/math/special_functions/detail/bessel_jy_series.hpp index f397105b1b..a5fc7b832e 100644 --- a/include/boost/math/special_functions/detail/bessel_jy_series.hpp +++ b/include/boost/math/special_functions/detail/bessel_jy_series.hpp @@ -236,7 +236,12 @@ T bessel_yn_small_z(int n, T z, T* scale, const Policy& pol) } else { + #if (defined(__GNUC__) && __GNUC__ == 13) auto p = static_cast(pow(z / 2, T(n))); + #else + auto p = static_cast(pow(z / 2, n)); + #endif + T result = -((boost::math::factorial(n - 1, pol) / constants::pi())); if(p * tools::max_value() < result) { diff --git a/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp b/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp index 566dd24a0f..861d981a17 100644 --- a/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp +++ b/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp @@ -146,7 +146,13 @@ return std::make_pair(r, r); } std::pair r = hypergeometric_pFq_checked_series_impl(aj, bj, Real(1 / z), pol, termination, log_scale); + + #if (defined(__GNUC__) && __GNUC__ == 13) Real mul = pow(-z, Real(-*aj.begin())); + #else + Real mul = pow(-z, -*aj.begin()); + #endif + r.first *= mul; r.second *= mul; return r;