diff DEPENDENCIES/generic/include/boost/math/tools/toms748_solve.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/math/tools/toms748_solve.hpp	Fri Sep 04 12:01:02 2015 +0100
+++ b/DEPENDENCIES/generic/include/boost/math/tools/toms748_solve.hpp	Mon Sep 07 11:12:49 2015 +0100
@@ -17,6 +17,14 @@
 #include <boost/cstdint.hpp>
 #include <limits>
 
+#ifdef BOOST_MATH_LOG_ROOT_ITERATIONS
+#  define BOOST_MATH_LOGGER_INCLUDE <boost/math/tools/iteration_logger.hpp>
+#  include BOOST_MATH_LOGGER_INCLUDE
+#  undef BOOST_MATH_LOGGER_INCLUDE
+#else
+#  define BOOST_MATH_LOG_COUNT(count)
+#endif
+
 namespace boost{ namespace math{ namespace tools{
 
 template <class T>
@@ -298,9 +306,9 @@
    a = ax;
    b = bx;
    if(a >= b)
-      policies::raise_domain_error(
+      return boost::math::detail::pair_from_single(policies::raise_domain_error(
          function, 
-         "Parameters a and b out of order: a=%1%", a, pol);
+         "Parameters a and b out of order: a=%1%", a, pol));
    fa = fax;
    fb = fbx;
 
@@ -315,9 +323,9 @@
    }
 
    if(boost::math::sign(fa) * boost::math::sign(fb) > 0)
-      policies::raise_domain_error(
+      return boost::math::detail::pair_from_single(policies::raise_domain_error(
          function, 
-         "Parameters a and b do not bracket the root: a=%1%", a, pol);
+         "Parameters a and b do not bracket the root: a=%1%", a, pol));
    // dummy value for fd, e and fe:
    fe = e = fd = 1e5F;
 
@@ -452,6 +460,7 @@
    {
       a = b;
    }
+   BOOST_MATH_LOG_COUNT(max_iter)
    return std::make_pair(a, b);
 }
 
@@ -493,6 +502,8 @@
    //
    boost::uintmax_t count = max_iter - 1;
 
+   int step = 32;
+
    if((fa < 0) == (guess < 0 ? !rising : rising))
    {
       //
@@ -502,13 +513,19 @@
       while((boost::math::sign)(fb) == (boost::math::sign)(fa))
       {
          if(count == 0)
-            policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol);
+            return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol));
          //
-         // Heuristic: every 20 iterations we double the growth factor in case the
-         // initial guess was *really* bad !
+         // Heuristic: normally it's best not to increase the step sizes as we'll just end up
+         // with a really wide range to search for the root.  However, if the initial guess was *really*
+         // bad then we need to speed up the search otherwise we'll take forever if we're orders of
+         // magnitude out.  This happens most often if the guess is a small value (say 1) and the result
+         // we're looking for is close to std::numeric_limits<T>::min().
          //
-         if((max_iter - count) % 20 == 0)
+         if((max_iter - count) % step == 0)
+         {
             factor *= 2;
+            if(step > 1) step /= 2;
+         }
          //
          // Now go ahead and move our guess by "factor":
          //
@@ -536,13 +553,19 @@
             return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); 
          }
          if(count == 0)
-            policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol);
+            return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol));
          //
-         // Heuristic: every 20 iterations we double the growth factor in case the
-         // initial guess was *really* bad !
+         // Heuristic: normally it's best not to increase the step sizes as we'll just end up
+         // with a really wide range to search for the root.  However, if the initial guess was *really*
+         // bad then we need to speed up the search otherwise we'll take forever if we're orders of
+         // magnitude out.  This happens most often if the guess is a small value (say 1) and the result
+         // we're looking for is close to std::numeric_limits<T>::min().
          //
-         if((max_iter - count) % 20 == 0)
+         if((max_iter - count) % step == 0)
+         {
             factor *= 2;
+            if(step > 1) step /= 2;
+         }
          //
          // Now go ahead and move are guess by "factor":
          //
@@ -567,6 +590,7 @@
       pol);
    max_iter += count;
    BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count);
+   BOOST_MATH_LOG_COUNT(max_iter)
    return r;
 }