aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/sf_mod_bessel.tcc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits/sf_mod_bessel.tcc')
-rw-r--r--libstdc++-v3/include/bits/sf_mod_bessel.tcc14
1 files changed, 12 insertions, 2 deletions
diff --git a/libstdc++-v3/include/bits/sf_mod_bessel.tcc b/libstdc++-v3/include/bits/sf_mod_bessel.tcc
index e4371d4a5ce..e0004df009a 100644
--- a/libstdc++-v3/include/bits/sf_mod_bessel.tcc
+++ b/libstdc++-v3/include/bits/sf_mod_bessel.tcc
@@ -90,12 +90,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto _Rsum = __bk_xk;
auto __ak_xk = _Tp{1};
auto _Psum = __ak_xk;
+ auto __convP = false;
++__k;
auto __2km1 = 1;
__bk_xk *= (__4nu2 + __2km1 * (__2km1 + 2)) / __8x;
auto _Ssum = __bk_xk;
__ak_xk *= (__2nu - __2km1) * (__2nu + __2km1) / __8x;
auto _Qsum = __ak_xk;
+ auto __convQ = false;
+ auto __ak_xk_prev = std::abs(__ak_xk);
do
{
++__k;
@@ -104,15 +107,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Rsum += __bk_xk;
__ak_xk *= (__2nu - __2km1) * (__2nu + __2km1) / (__k * __8x);
_Psum += __ak_xk;
- const auto __convP = std::abs(__ak_xk) < _S_eps * std::abs(_Psum);
+ if (std::abs(__ak_xk) > __ak_xk_prev)
+ break;
+ __ak_xk_prev = std::abs(__ak_xk);
+ __convP = std::abs(__ak_xk) < _S_eps * std::abs(_Psum);
++__k;
__2km1 += 2;
__bk_xk = (__4nu2 + __2km1 * (__2km1 + 2)) * __ak_xk / (__k * __8x);
_Ssum += __bk_xk;
__ak_xk *= (__2nu - __2km1) * (__2nu + __2km1) / (__k * __8x);
+ if (std::abs(__ak_xk) > __ak_xk_prev)
+ break;
+ __ak_xk_prev = std::abs(__ak_xk);
_Qsum += __ak_xk;
- const auto __convQ = std::abs(__ak_xk) < _S_eps * std::abs(_Qsum);
+ __convQ = std::abs(__ak_xk) < _S_eps * std::abs(_Qsum);
if (__convP && __convQ && __k > (__nu / _Tp{2}))
break;
@@ -147,6 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __bess_t = __gnu_cxx::__cyl_mod_bessel_t<_Tp, _Tp, _Tp>;
const auto _S_inf = __gnu_cxx::__infinity(__x);
const auto _S_eps = __gnu_cxx::__epsilon(__x);
+ const auto _S_tiny = __gnu_cxx::__min(__x);
const auto _S_pi = __gnu_cxx::__const_pi(__x);
const auto _S_fp_min = _Tp{10} * _S_eps;
constexpr int _S_max_iter = 15000;