Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84951 - trunk/boost/math/special_functions/detail
From: john_at_[hidden]
Date: 2013-07-04 11:31:32


Author: johnmaddock
Date: 2013-07-04 11:31:32 EDT (Thu, 04 Jul 2013)
New Revision: 84951
URL: http://svn.boost.org/trac/boost/changeset/84951

Log:
Fix overflow/underflow errors when x is very close to 2.

Text files modified:
   trunk/boost/math/special_functions/detail/bessel_ik.hpp | 17 +++++++++++++++++
   1 files changed, 17 insertions(+), 0 deletions(-)

Modified: trunk/boost/math/special_functions/detail/bessel_ik.hpp
==============================================================================
--- trunk/boost/math/special_functions/detail/bessel_ik.hpp Thu Jul 4 05:13:23 2013 (r84950)
+++ trunk/boost/math/special_functions/detail/bessel_ik.hpp 2013-07-04 11:31:32 EDT (Thu, 04 Jul 2013) (r84951)
@@ -234,6 +234,7 @@
     BOOST_MATH_INSTRUMENT_VARIABLE(b);
     BOOST_MATH_INSTRUMENT_VARIABLE(D);
     BOOST_MATH_INSTRUMENT_VARIABLE(f);
+
     for (k = 2; k < policies::get_max_series_iterations<Policy>(); k++) // starting from 2
     {
         // continued fraction f = z1 / z0
@@ -250,6 +251,22 @@
         C *= -a / k;
         Q += C * q;
         S += Q * delta;
+ //
+ // Under some circumstances q can grow very small and C very
+ // large, leading to under/overflow. This is particularly an
+ // issue for types which have many digits precision but a narrow
+ // exponent range. A typical example being a "double double" type.
+ // To avoid this situation we can normalise q (and related prev/current)
+ // and C. All other variables remain unchanged in value. A typical
+ // test case occurs when x is close to 2, for example cyl_bessel_k(9.125, 2.125).
+ //
+ if(q < tools::epsilon<T>())
+ {
+ C *= q;
+ prev /= q;
+ current /= q;
+ q = 1;
+ }
 
         // S converges slower than f
         BOOST_MATH_INSTRUMENT_VARIABLE(Q * delta);


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk