From 00dfd444705029c6ce792377aabfcc2b7dcefef2 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 16 Feb 2019 12:11:49 +0000 Subject: [PATCH] 1F1, asymptotic-z region: don't use logs unless we really have to. Also don't take this branch when |a| is really small. --- .../detail/hypergeometric_asym.hpp | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/include/boost/math/special_functions/detail/hypergeometric_asym.hpp b/include/boost/math/special_functions/detail/hypergeometric_asym.hpp index 69fe685ab..c1a68ffa7 100644 --- a/include/boost/math/special_functions/detail/hypergeometric_asym.hpp +++ b/include/boost/math/special_functions/detail/hypergeometric_asym.hpp @@ -47,20 +47,27 @@ log_scaling += e; prefix = exp(z - e); } - T t = log(z) * (a - b); - e = itrunc(t, pol); - log_scaling += e; - prefix *= exp(t - e); + if ((fabs(a) < 10) && (fabs(b) < 10)) + { + prefix *= pow(z, a) * pow(z, -b) * boost::math::tgamma(b, pol) / boost::math::tgamma(a, pol); + } + else + { + T t = log(z) * (a - b); + e = itrunc(t, pol); + log_scaling += e; + prefix *= exp(t - e); - t = boost::math::lgamma(b, &s, pol); - e = itrunc(t, pol); - log_scaling += e; - prefix *= s * exp(t - e); + t = boost::math::lgamma(b, &s, pol); + e = itrunc(t, pol); + log_scaling += e; + prefix *= s * exp(t - e); - t = boost::math::lgamma(a, &s, pol); - e = itrunc(t, pol); - log_scaling -= e; - prefix /= s * exp(t - e); + t = boost::math::lgamma(a, &s, pol); + e = itrunc(t, pol); + log_scaling -= e; + prefix /= s * exp(t - e); + } // // Checked 2F0: // @@ -105,6 +112,9 @@ int half_digits = policies::digits() / 2; bool in_region = false; + if (fabs(a) < 0.001f) + return false; // Haven't been able to make this work, why not? TODO! + // // We use the following heuristic, if after we have had half_digits terms // of the 2F0 series, we require terms to be decreasing in size by a factor