From 4fa7d1cb09fb7bc61215748f8cbf999a92eddf5d Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 26 Aug 2024 15:48:15 -0400 Subject: [PATCH] Remove STL usage from gamma --- .../boost/math/special_functions/gamma.hpp | 78 ++++++++++--------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/include/boost/math/special_functions/gamma.hpp b/include/boost/math/special_functions/gamma.hpp index 9268ba415..e5990ca4f 100644 --- a/include/boost/math/special_functions/gamma.hpp +++ b/include/boost/math/special_functions/gamma.hpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,12 +38,12 @@ #include #include #include + +// Only needed for types larger than double +#ifndef BOOST_MATH_HAS_GPU_SUPPORT #include #include - -#include -#include -#include +#endif #ifdef _MSC_VER # pragma warning(push) @@ -60,13 +62,13 @@ namespace boost{ namespace math{ namespace detail{ template -BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const std::true_type&) +BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const boost::math::true_type&) { int i = static_cast(v); return i&1; } template -BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const std::false_type&) +BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const boost::math::false_type&) { // Oh dear can't cast T to int! BOOST_MATH_STD_USING @@ -76,7 +78,7 @@ BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const std::false_type&) template BOOST_MATH_GPU_ENABLED inline bool is_odd(T v) { - return is_odd(v, ::std::is_convertible()); + return is_odd(v, ::boost::math::is_convertible()); } template @@ -259,7 +261,7 @@ BOOST_MATH_GPU_ENABLED T lgamma_imp_final(T z, const Policy& pol, const Lanczos& else if(z < 15) { typedef typename policies::precision::type precision_type; - typedef std::integral_constant(z, T(z - 1), T(z - 2), tag_type(), pol, l); } - else if((z >= 3) && (z < 100) && (std::numeric_limits::max_exponent >= 1024)) + else if((z >= 3) && (z < 100) && (boost::math::numeric_limits::max_exponent >= 1024)) { // taking the log of tgamma reduces the error, no danger of overflow here: result = log(gamma_imp(z, pol, l)); @@ -349,7 +351,7 @@ struct upper_incomplete_gamma_fract T z, a; int k; public: - typedef std::pair result_type; + typedef boost::math::pair result_type; BOOST_MATH_GPU_ENABLED upper_incomplete_gamma_fract(T a1, T z1) : z(z1-a1+1), a(a1), k(0) @@ -399,7 +401,7 @@ BOOST_MATH_GPU_ENABLED inline T lower_gamma_series(T a, T z, const Policy& pol, // lower incomplete integral. Then divide by tgamma(a) // to get the normalised value. lower_incomplete_gamma_series s(a, z); - std::uintmax_t max_iter = policies::get_max_series_iterations(); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); T factor = policies::get_epsilon(); T result = boost::math::tools::sum_series(s, factor, max_iter, init_value); policies::check_series_iterations("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol); @@ -411,14 +413,14 @@ BOOST_MATH_GPU_ENABLED inline T lower_gamma_series(T a, T z, const Policy& pol, // with Bernoulli numbers. // template -std::size_t highest_bernoulli_index() +boost::math::size_t highest_bernoulli_index() { - const float digits10_of_type = (std::numeric_limits::is_specialized - ? static_cast(std::numeric_limits::digits10) + const float digits10_of_type = (boost::math::numeric_limits::is_specialized + ? static_cast(boost::math::numeric_limits::digits10) : static_cast(boost::math::tools::digits() * 0.301F)); // Find the high index n for Bn to produce the desired precision in Stirling's calculation. - return static_cast(18.0F + (0.6F * digits10_of_type)); + return static_cast(18.0F + (0.6F * digits10_of_type)); } template @@ -426,8 +428,8 @@ int minimum_argument_for_bernoulli_recursion() { BOOST_MATH_STD_USING - const float digits10_of_type = (std::numeric_limits::is_specialized - ? (float) std::numeric_limits::digits10 + const float digits10_of_type = (boost::math::numeric_limits::is_specialized + ? (float) boost::math::numeric_limits::digits10 : (float) (boost::math::tools::digits() * 0.301F)); int min_arg = (int) (digits10_of_type * 1.7F); @@ -449,7 +451,7 @@ int minimum_argument_for_bernoulli_recursion() const float d2_minus_one = ((digits10_of_type / 0.301F) - 1.0F); const float limit = ceil(exp((d2_minus_one * log(2.0F)) / 20.0F)); - min_arg = (int) ((std::min)(digits10_of_type * 1.7F, limit)); + min_arg = (int) (BOOST_MATH_GPU_SAFE_MIN(digits10_of_type * 1.7F, limit)); } return min_arg; @@ -468,7 +470,7 @@ T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false) // Perform the Bernoulli series expansion of Stirling's approximation. - const std::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations(); + const boost::math::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations(); T one_over_x_pow_two_n_minus_one = 1 / z; const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one; @@ -477,11 +479,11 @@ T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false) const T half_ln_two_pi_over_z = sqrt(boost::math::constants::two_pi() / z); T last_term = 2 * sum; - for (std::size_t n = 2U;; ++n) + for (boost::math::size_t n = 2U;; ++n) { one_over_x_pow_two_n_minus_one *= one_over_x2; - const std::size_t n2 = static_cast(n * 2U); + const boost::math::size_t n2 = static_cast(n * 2U); const T term = (boost::math::bernoulli_b2n(static_cast(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U)); @@ -786,7 +788,7 @@ BOOST_MATH_GPU_ENABLED T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& typedef typename policies::precision::type precision_type; - typedef std::integral_constant()) || ((std::max)(alz, amz) >= tools::log_max_value())) + if((BOOST_MATH_GPU_SAFE_MIN(alz, amz) <= tools::log_min_value()) || (BOOST_MATH_GPU_SAFE_MAX(alz, amz) >= tools::log_max_value())) { T amza = amz / a; - if(((std::min)(alz, amz)/2 > tools::log_min_value()) && ((std::max)(alz, amz)/2 < tools::log_max_value())) + if((BOOST_MATH_GPU_SAFE_MIN(alz, amz)/2 > tools::log_min_value()) && (BOOST_MATH_GPU_SAFE_MAX(alz, amz)/2 < tools::log_max_value())) { // compute square root of the result and then square it: T sq = pow(z / agh, a / 2) * exp(amz / 2); prefix = sq * sq; } - else if(((std::min)(alz, amz)/4 > tools::log_min_value()) && ((std::max)(alz, amz)/4 < tools::log_max_value()) && (z > a)) + else if((BOOST_MATH_GPU_SAFE_MIN(alz, amz)/4 > tools::log_min_value()) && (BOOST_MATH_GPU_SAFE_MAX(alz, amz)/4 < tools::log_max_value()) && (z > a)) { // compute the 4th root of the result then square it twice: T sq = pow(z / agh, a / 4) * exp(amz / 4); @@ -1092,7 +1094,7 @@ BOOST_MATH_GPU_ENABLED inline T tgamma_small_upper_part(T a, T x, const Policy& result -= p; result /= a; detail::small_gamma2_series s(a, x); - std::uintmax_t max_iter = policies::get_max_series_iterations() - 10; + boost::math::uintmax_t max_iter = policies::get_max_series_iterations() - 10; p += 1; if(pderivative) *pderivative = p / (*pgam * exp(x)); @@ -1192,7 +1194,7 @@ BOOST_MATH_GPU_ENABLED T incomplete_tgamma_large_x(const T& a, const T& x, const { BOOST_MATH_STD_USING incomplete_tgamma_large_x_series s(a, x); - std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::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::tgamma<%1%>(%1%,%1%)", max_iter, pol); return result; @@ -1357,7 +1359,7 @@ BOOST_MATH_GPU_ENABLED T gamma_incomplete_imp(T a, T x, bool normalised, bool in // series and continued fractions are slow to converge: // bool use_temme = false; - if(normalised && std::numeric_limits::is_specialized && (a > 20)) + if(normalised && boost::math::numeric_limits::is_specialized && (a > 20)) { T sigma = fabs((x-a)/a); if((a > 200) && (policies::digits() <= 113)) @@ -1507,7 +1509,7 @@ BOOST_MATH_GPU_ENABLED T gamma_incomplete_imp(T a, T x, bool normalised, bool in // typedef typename policies::precision::type precision_type; - typedef std::integral_constant::type precision_type; - typedef std::integral_constant - BOOST_MATH_GPU_ENABLED static void do_init(const std::integral_constant&) + BOOST_MATH_GPU_ENABLED static void do_init(const boost::math::integral_constant&) { // If std::numeric_limits::digits is zero, we must not call // our initialization code here as the precision presumably // varies at runtime, and will not have been set yet. Plus the // code requiring initialization isn't called when digits == 0. - if (std::numeric_limits::digits) + if (boost::math::numeric_limits::digits) { boost::math::gamma_p(static_cast(400), static_cast(400), Policy()); } } - BOOST_MATH_GPU_ENABLED static void do_init(const std::integral_constant&){} + BOOST_MATH_GPU_ENABLED static void do_init(const boost::math::integral_constant&){} void force_instantiate()const{} }; BOOST_MATH_STATIC const init initializer; @@ -1945,7 +1947,7 @@ struct lgamma_initializer BOOST_MATH_GPU_ENABLED init() { typedef typename policies::precision::type precision_type; - typedef std::integral_constant&) + BOOST_MATH_GPU_ENABLED static void do_init(const boost::math::integral_constant&) { boost::math::lgamma(static_cast(2.5), Policy()); boost::math::lgamma(static_cast(1.25), Policy()); boost::math::lgamma(static_cast(1.75), Policy()); } - BOOST_MATH_GPU_ENABLED static void do_init(const std::integral_constant&) + BOOST_MATH_GPU_ENABLED static void do_init(const boost::math::integral_constant&) { boost::math::lgamma(static_cast(2.5), Policy()); boost::math::lgamma(static_cast(1.25), Policy()); boost::math::lgamma(static_cast(1.5), Policy()); boost::math::lgamma(static_cast(1.75), Policy()); } - BOOST_MATH_GPU_ENABLED static void do_init(const std::integral_constant&) + BOOST_MATH_GPU_ENABLED static void do_init(const boost::math::integral_constant&) { } BOOST_MATH_GPU_ENABLED void force_instantiate()const{} @@ -2079,7 +2081,7 @@ BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - return policies::checked_narrowing_cast::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)"); + return policies::checked_narrowing_cast::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)"); } template