lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 04c58eb 09/23: Count iterations and evaluatio


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 04c58eb 09/23: Count iterations and evaluations separately
Date: Tue, 27 Jul 2021 21:59:51 -0400 (EDT)

branch: master
commit 04c58ebfe8d6d8bfa87f0e6efe294f75a1404ad9
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Count iterations and evaluations separately
    
    Define
     - an "iteration" as a pass through the main loop
     - an "evaluation" as a call to the objective function
    It is useful to count both. In some experimental work, an iteration
    has been seen with no evaluation; that makes separate counts useful
    at least for debugging. Other uses have been imagined though not yet
    committed.
---
 zero.hpp      |  44 +++++++++-------
 zero_test.cpp | 160 +++++++++++++++++++++++++++++-----------------------------
 2 files changed, 105 insertions(+), 99 deletions(-)

diff --git a/zero.hpp b/zero.hpp
index 1f26878..1efb47f 100644
--- a/zero.hpp
+++ b/zero.hpp
@@ -81,6 +81,7 @@ struct root_type
     double        root     {0.0};
     root_validity validity {improper_bounds};
     int           n_iter   {0};
+    int           n_eval   {0};
 };
 
 /// Specialized binary64 midpoint for root finding.
@@ -392,10 +393,11 @@ root_type lmi_root
     constexpr double epsilon {std::numeric_limits<double>::epsilon()};
 
     int              n_iter  {0};
+    int              n_eval  {0};
     root_impetus     impetus {evaluate_bounds};
 
     os_trace
-        << "#eval"
+        << "#it #eval"
         << "            a           fa"
         << "            b           fb"
         << "            c           fc"
@@ -414,6 +416,7 @@ root_type lmi_root
         {
         os_trace
             <<        std::setw(3)  << n_iter
+            << ' ' << std::setw(3)  << n_eval
             << ' '                  << impetus
             << ' ' << std::setw(12) << a << ' ' << std::setw(12) << fa
             << ' ' << std::setw(12) << b << ' ' << std::setw(12) << fb
@@ -425,8 +428,8 @@ root_type lmi_root
     auto recapitulate = [&]()
         {
         os_trace
-            << n_iter
-            << " iterations; final interval:\n"
+            << n_iter << " iterations, "
+            << n_eval << " evaluations; final interval:\n"
             << std::setprecision(DECIMAL_DIG)
             << std::showpos
             << " b "  << std::setw(12) << b
@@ -445,31 +448,31 @@ root_type lmi_root
     if(a == b)
         {
         recapitulate();
-        return {a, improper_bounds, n_iter};
+        return {a, improper_bounds, n_iter, n_eval};
         }
 
     fa = static_cast<double>(f(a));
-    ++n_iter;
+    ++n_eval;
     if(0.0 == fa) // Note 0.
         {
         recapitulate();
-        return {a, root_is_valid, n_iter};
+        return {a, root_is_valid, n_iter, n_eval};
         }
 
     fb = static_cast<double>(f(b));
-    ++n_iter;
+    ++n_eval;
     expatiate();
     if(0.0 == fb) // Note 0 [bis].
         {
         recapitulate();
-        return {b, root_is_valid, n_iter};
+        return {b, root_is_valid, n_iter, n_eval};
         }
 
     // f(a) and f(b) must have different signs; neither may be a NaN.
     if(std::isnan(fa) || std::isnan(fb) || (0.0 < fa) == (0.0 < fb))
         {
         recapitulate();
-        return {0.0, root_not_bracketed, n_iter};
+        return {0.0, root_not_bracketed, n_iter, n_eval};
         }
 
     fc = fb; // Note 1.
@@ -477,7 +480,7 @@ root_type lmi_root
     double d = b - a;
     double e = d;
 
-    for(;;)
+    for(;; ++n_iter)
         {
         if((0.0 < fb) == (0.0 < fc))
             {
@@ -507,12 +510,12 @@ root_type lmi_root
                 )
                 {
                 recapitulate();
-                return {b, root_is_valid, n_iter};
+                return {b, root_is_valid, n_iter, n_eval};
                 }
             else if(std::fabs(m) <= 2.0 * epsilon * std::fabs(c) + t)
                 {
                 recapitulate();
-                return {c, root_is_valid, n_iter};
+                return {c, root_is_valid, n_iter, n_eval};
                 }
             else
                 {
@@ -617,7 +620,7 @@ root_type lmi_root
         else
             {
             fb = static_cast<double>(f(b));
-            ++n_iter;
+            ++n_eval;
             expatiate();
             }
         }
@@ -678,10 +681,11 @@ double brent_zero
     // that f(a) and f(b) have different signs.
 
     int          n_iter  {0};
+    int          n_eval  {0};
     root_impetus impetus {evaluate_bounds};
 
     os_trace
-        << "#eval"
+        << "#it #eval"
         << "            a           fa"
         << "            b           fb"
         << "            c           fc"
@@ -694,6 +698,7 @@ double brent_zero
         {
         os_trace
             <<        std::setw(3)  << n_iter
+            << ' ' << std::setw(3)  << n_eval
             << ' '                  << impetus
             << ' ' << std::setw(12) << a << ' ' << std::setw(12) << fa
             << ' ' << std::setw(12) << b << ' ' << std::setw(12) << fb
@@ -705,8 +710,8 @@ double brent_zero
     auto recapitulate = [&]()
         {
         os_trace
-            << n_iter
-            << " iterations; final interval:\n"
+            << n_iter << " iterations, "
+            << n_eval << " evaluations; final interval:\n"
             << std::setprecision(DECIMAL_DIG)
             << std::showpos
             << " b "  << std::setw(12) << b
@@ -718,9 +723,9 @@ double brent_zero
         };
 
     fa = f(a);
-    ++n_iter;
+    ++n_eval;
     fb = f(b);
-    ++n_iter;
+    ++n_eval;
     c = fc = 0.0; // Zero-initialize before calling expatiate().
     expatiate();
   interpolate:
@@ -809,8 +814,9 @@ double brent_zero
             b -= tol;
             }
         fb = f(b);
-        ++n_iter;
+        ++n_eval;
         expatiate();
+        ++n_iter;
         if((0.0 < fb) == (0.0 < fc))
             {goto interpolate;}
         else
diff --git a/zero_test.cpp b/zero_test.cpp
index b6fec8b..a13b60e 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -51,13 +51,13 @@ double max_err(double zeta, double tol)
     return 6.0 * epsilon * std::fabs(zeta) + 2.0 * tol;
 }
 
-/// AfMWD eq. 3.3: maximum number of iterations for bisection.
+/// AfMWD eq. 3.3: maximum number of evaluations for bisection.
 ///
 /// The return value, k+1, is the exact number of function
 /// evaluations unless f vanishes early, as Brent explains in the
 /// paragraph following eq. 3.3 .
 ///
-/// static_cast<int> is exact for any number of iterations that
+/// static_cast<int> is exact for any number of evaluations that
 /// can be counted by an 'int'.
 ///
 /// The greatest possible number of bisection steps is:
@@ -76,20 +76,20 @@ double max_err(double zeta, double tol)
 ///    denormals, so this shorthand isn't merely a convenience).
 /// Such defects in a unit-testing TU needn't be fixed.
 
-int max_n_iter_bolzano(double a, double b, double tol, double zeta)
+int max_n_eval_bolzano(double a, double b, double tol, double zeta)
 {
     double delta = 2.0 * epsilon * std::fabs(zeta) + tol;
     double k = std::ceil(std::log2(std::fabs(b - a) / delta));
     return 1 + static_cast<int>(k);
 }
 
-/// AfMWD eq. 3.3: maximum number of iterations for Brent's method.
+/// AfMWD eq. 3.3: maximum number of evaluations for Brent's method.
 ///
 /// The greatest possible number of steps is 2099^2 = 4405801.
 
-int max_n_iter_brent(double a, double b, double tol, double zeta)
+int max_n_eval_brent(double a, double b, double tol, double zeta)
 {
-    int k_plus_one = max_n_iter_bolzano(a, b, tol, zeta);
+    int k_plus_one = max_n_eval_bolzano(a, b, tol, zeta);
     return k_plus_one * k_plus_one - 2;
 }
 } // Unnamed namespace.
@@ -103,7 +103,7 @@ int max_n_iter_brent(double a, double b, double tol, double 
zeta)
 /// Verify that
 ///  - the result is within the max_err() tolerance (ignoring Brent's
 ///      warning about roundoff in the computed function)
-///  - the number of iterations doesn't exceed max_n_iter_brent()
+///  - the number of evaluations doesn't exceed max_n_eval_brent()
 ///  - maximum-precision instrumented traces are identical
 /// Identical traces are strong architecture-independent evidence
 /// that both implementations behave the same way at every step.
@@ -137,7 +137,7 @@ void test_a_function
     // Otherwise silly alias for compatibility with test_a_decimal_function().
     double const tol = tolerance;
     double const maximum_error = max_err(exact_root, tol);
-    int const max_n_iter = max_n_iter_brent(bound0, bound1, tol, exact_root);
+    int const max_n_eval = max_n_eval_brent(bound0, bound1, tol, exact_root);
 
     std::ostringstream os0;
     os0.precision(DECIMAL_DIG);
@@ -151,7 +151,7 @@ void test_a_function
     INVOKE_LMI_TEST(root_is_valid == r.validity, file, line);
     error = r.root - exact_root;
     INVOKE_LMI_TEST_RELATION(std::fabs(error),<=,maximum_error,file,line);
-    INVOKE_LMI_TEST_RELATION(r.n_iter,<=,max_n_iter,file,line);
+    INVOKE_LMI_TEST_RELATION(r.n_eval,<=,max_n_eval,file,line);
 
 #if !defined LMI_X87
     INVOKE_LMI_TEST_EQUAL(os0.str(),os1.str(),file,line);
@@ -167,11 +167,11 @@ void test_a_function
 /// Verify that
 ///  - the result is within the max_err() tolerance (ignoring Brent's
 ///      warning about roundoff in the computed function)
-///  - the number of iterations doesn't exceed max_n_iter_brent()
+///  - the number of evaluations doesn't exceed max_n_eval_brent()
 ///
-/// Also verify that the number of iterations matches the 'n_iter'
+/// Also verify that the number of evaluations matches the 'n_eval'
 /// argument, to make it easier to detect mistaken refactorings.
-/// Do this only if 'n_iter' is not zero (the default), and only for
+/// Do this only if 'n_eval' is not zero (the default), and only for
 /// a single architecture (here, x86_64-pc-linux-gnu), because the
 /// outcome depends on architecture.
 
@@ -183,13 +183,13 @@ void test_a_decimal_function
     ,double      bound1
     ,int         decimals
     ,int         line
-    ,int         n_iter = 0
+    ,int         n_eval = 0
     ,char const* file   = __FILE__
     )
 {
     double const tol = 0.5 * std::pow(10.0, -decimals);
     double const maximum_error = max_err(exact_root, tol);
-    int const max_n_iter = max_n_iter_brent(bound0, bound1, tol, exact_root);
+    int const max_n_eval = max_n_eval_brent(bound0, bound1, tol, exact_root);
 
     double d = brent_zero(f, bound0, bound1, tol);
     double error = d - exact_root;
@@ -199,15 +199,15 @@ void test_a_decimal_function
     INVOKE_LMI_TEST(root_is_valid == r.validity, file, line);
     error = r.root - exact_root;
     INVOKE_LMI_TEST_RELATION(std::fabs(error),<=,maximum_error,file,line);
-    INVOKE_LMI_TEST_RELATION(r.n_iter,<=,max_n_iter,file,line);
+    INVOKE_LMI_TEST_RELATION(r.n_eval,<=,max_n_eval,file,line);
 
 #if defined LMI_X86_64 && defined LMI_POSIX
-    if(0 != n_iter)
+    if(0 != n_eval)
         {
-        INVOKE_LMI_TEST_EQUAL(n_iter, r.n_iter, file, line);
+        INVOKE_LMI_TEST_EQUAL(n_eval, r.n_eval, file, line);
         }
 #endif // defined LMI_X86_64 && defined LMI_POSIX
-    stifle_warning_for_unused_variable(n_iter);
+    stifle_warning_for_unused_variable(n_eval);
 }
 
 /// Test with all biases, asserting obvious invariants.
@@ -268,7 +268,7 @@ struct e_nineteenth
 ///
 /// Following section 3 of that chapter, define
 ///   k = [log2((b-a)/t)], [x] being the greatest-integer function
-/// Then bisection takes exactly k+1 iterations unless it finds a root
+/// Bisection takes exactly k+1 evaluations unless it finds a root
 /// earlier by serendipity; and the number of function evaluations
 /// required by Brent's method (counting the endpoint evaluations) is
 ///   (k+1)^2 - 2 [Brent's eq. 3.4]
@@ -278,8 +278,8 @@ struct e_nineteenth
 ///
 /// The parameters hardcoded here were chosen to prevent overflow.
 /// This is not a dramatic illustration of the superiority to Dekker's
-/// method, which would move by a step of 1.0 at each iteration, thus
-/// taking about 200 iterations. Brent provides an extended-exponent
+/// method, which would move by a step of 1.0 at each evaluation, thus
+/// taking about 200 evaluations. Brent provides an extended-exponent
 /// version for which he says the difference would be 1600 evaluations
 /// versus 1.0e12 for a tolerance of 1.0e-12.
 
@@ -356,13 +356,13 @@ void test_fundamentals()
     r = decimal_root(e, 0.1, 1.0, bias_none, 9);
     LMI_TEST(root_not_bracketed == r.validity);
 
-    // Calculate maximum possible number of iterations according to
-    // the documentation for max_n_iter_bolzano(). This calculation
+    // Calculate maximum possible number of evaluations according to
+    // the documentation for max_n_eval_bolzano(). This calculation
     // would overflow in double precision.
     //
     // log2(DBL_MAX) is 1024, so log2(DBL_MAX - -DBL_MAX) is 1025;
     // and log2(DBL_TRUE_MIN) is 1074; so the maximum number of
-    // iterations is
+    // evaluations is
     //   log2(DBL_MAX - -DBL_MAX) / DBL_TRUE_MIN
     //   = 1 + 1024 + 1074 = 2099
     // for bisection, and 2099^2 = 4405801 for Brent's method with
@@ -514,8 +514,8 @@ void test_NaNs()
     root_type r = lmi_root(NaN_signed, -1.0e100, 1.0e100, 5.0e-1);
     LMI_TEST_EQUAL(root_is_valid, r.validity);
 
-    int const max_n_iter = max_n_iter_brent(-1.0e100, 1.0e100, 5.0e-1, pi);
-    LMI_TEST_RELATION(r.n_iter,<=,max_n_iter);
+    int const max_n_eval = max_n_eval_brent(-1.0e100, 1.0e100, 5.0e-1, pi);
+    LMI_TEST_RELATION(r.n_eval,<=,max_n_eval);
     LMI_TEST(materially_equal(1.0e100, std::fabs(r.root)));
 
     // If the function's value is a NaN at either input bound, then
@@ -548,19 +548,19 @@ void test_root_at_a_bound()
     r = lmi_root(f, -1.0,  0.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 2);
+    LMI_TEST_EQUAL(r.n_eval, 2);
 
     // Root found on third evaluation of a monomial.
     r = lmi_root(f, -1.0,  1.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 3);
+    LMI_TEST_EQUAL(r.n_eval, 3);
 
     // Root is first bound: found on first evaluation.
     r = lmi_root(f,  0.0, -1.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 1);
+    LMI_TEST_EQUAL(r.n_eval, 1);
 
     // Returns an error status, even though the root coincides with
     // both bounds. Attempting to find a root between identical bounds
@@ -568,22 +568,22 @@ void test_root_at_a_bound()
     // without evaluating the objective function even once.
     r = lmi_root(f,  0.0,  0.0, tol);
     LMI_TEST(improper_bounds == r.validity);
-    LMI_TEST_EQUAL(r.n_iter, 0);
+    LMI_TEST_EQUAL(r.n_eval, 0);
 
     r = lmi_root(f,  0.0,  1.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 1);
+    LMI_TEST_EQUAL(r.n_eval, 1);
 
     r = lmi_root(f,  1.0, -1.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 3);
+    LMI_TEST_EQUAL(r.n_eval, 3);
 
     r = lmi_root(f,  1.0,  0.0, tol);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 2);
+    LMI_TEST_EQUAL(r.n_eval, 2);
 
     r = lmi_root(f,  1.0,  1.0, tol);
     LMI_TEST(improper_bounds == r.validity);
@@ -598,24 +598,24 @@ void test_root_at_a_bound()
     r = decimal_root(f, -1.03,  0.04, bias_none, 1);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 2);
+    LMI_TEST_EQUAL(r.n_eval, 2);
 
     // Root found on third evaluation of a monomial.
     r = decimal_root(f, -1.04,  0.96, bias_none, 1);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 3);
+    LMI_TEST_EQUAL(r.n_eval, 3);
 
     // Root is rounded first bound: found on first evaluation.
     r = decimal_root(f,  0.04, -1.01, bias_none, 1);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 1);
+    LMI_TEST_EQUAL(r.n_eval, 1);
 
     // Bounds identical after rounding: presumptive error.
     r = decimal_root(f, -0.04,  0.04, bias_none, 1);
     LMI_TEST(improper_bounds == r.validity);
-    LMI_TEST_EQUAL(r.n_iter, 0);
+    LMI_TEST_EQUAL(r.n_eval, 0);
 
     // A curious effect of rounding the input bounds.
 
@@ -626,7 +626,7 @@ void test_root_at_a_bound()
     r = decimal_root(f,  0.04,  0.09, bias_none, 1);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST_EQUAL(r.root, zeta);
-    LMI_TEST_EQUAL(r.n_iter, 1);
+    LMI_TEST_EQUAL(r.n_eval, 1);
 }
 
 void test_biases()
@@ -726,27 +726,27 @@ void test_celebrated_equation()
 
     // "1 + " skips the newline:
     std::string const verified = 1 + R"--cut-here--(
-#eval            a           fa            b           fb            c         
  fc
-  2 i -2.5600000000000001 -16.657216000000002 2.5600000000000001 
6.6572160000000018            0            0
-  2 j -2.5600000000000001 -16.657216000000002 2.5600000000000001 
6.6572160000000018 -2.5600000000000001 -16.657216000000002
-  3 L 2.5600000000000001 6.6572160000000018 1.0980323260716793 
-5.8721945393772152 -2.5600000000000001 -16.657216000000002
-  3 j 2.5600000000000001 6.6572160000000018 1.0980323260716793 
-5.8721945393772152 2.5600000000000001 6.6572160000000018
-  4 L 1.0980323260716793 -5.8721945393772152 1.783216881610604 
-2.8960493667789873 2.5600000000000001 6.6572160000000018
-  5 Q 1.783216881610604 -2.8960493667789873 2.2478393639958036 
1.8621631139566732 2.5600000000000001 6.6572160000000018
-  5 j 1.783216881610604 -2.8960493667789873 2.2478393639958036 
1.8621631139566732 1.783216881610604 -2.8960493667789873
-  6 L 2.2478393639958036 1.8621631139566732 2.0660057758331045 
-0.3135140955237814 1.783216881610604 -2.8960493667789873
-  6 j 2.2478393639958036 1.8621631139566732 2.0660057758331045 
-0.3135140955237814 2.2478393639958036 1.8621631139566732
-  7 L 2.0660057758331045 -0.3135140955237814 2.0922079131171945 
-0.026123094109737011 2.2478393639958036 1.8621631139566732
-  8 Q 2.0922079131171945 -0.026123094109737011 2.0945566700001779 
5.7910818359374616e-05 2.2478393639958036 1.8621631139566732
-  8 j 2.0922079131171945 -0.026123094109737011 2.0945566700001779 
5.7910818359374616e-05 2.0922079131171945 -0.026123094109737011
-  9 L 2.0945566700001779 5.7910818359374616e-05 2.0945514746903111 
-7.6478343657981895e-08 2.0922079131171945 -0.026123094109737011
-  9 j 2.0945566700001779 5.7910818359374616e-05 2.0945514746903111 
-7.6478343657981895e-08 2.0945566700001779 5.7910818359374616e-05
- 10 L 2.0945514746903111 -7.6478343657981895e-08 2.0945514815423065 
-2.2382096176443156e-13 2.0945566700001779 5.7910818359374616e-05
- 11 Q 2.0945514815423065 -2.2382096176443156e-13 2.0945514815423265 
-8.8817841970012523e-16 2.0945566700001779 5.7910818359374616e-05
- 12 Q 2.0945514815423265 -8.8817841970012523e-16 2.0945514815423274 
9.7699626167013776e-15 2.0945566700001779 5.7910818359374616e-05
- 12 j 2.0945514815423265 -8.8817841970012523e-16 2.0945514815423274 
9.7699626167013776e-15 2.0945514815423265 -8.8817841970012523e-16
- 12 k 2.0945514815423274 9.7699626167013776e-15 2.0945514815423265 
-8.8817841970012523e-16 2.0945514815423274 9.7699626167013776e-15
-12 iterations; final interval:
+#it #eval            a           fa            b           fb            c     
      fc
+  0   2 i -2.5600000000000001 -16.657216000000002 2.5600000000000001 
6.6572160000000018            0            0
+  0   2 j -2.5600000000000001 -16.657216000000002 2.5600000000000001 
6.6572160000000018 -2.5600000000000001 -16.657216000000002
+  0   3 L 2.5600000000000001 6.6572160000000018 1.0980323260716793 
-5.8721945393772152 -2.5600000000000001 -16.657216000000002
+  1   3 j 2.5600000000000001 6.6572160000000018 1.0980323260716793 
-5.8721945393772152 2.5600000000000001 6.6572160000000018
+  1   4 L 1.0980323260716793 -5.8721945393772152 1.783216881610604 
-2.8960493667789873 2.5600000000000001 6.6572160000000018
+  2   5 Q 1.783216881610604 -2.8960493667789873 2.2478393639958036 
1.8621631139566732 2.5600000000000001 6.6572160000000018
+  3   5 j 1.783216881610604 -2.8960493667789873 2.2478393639958036 
1.8621631139566732 1.783216881610604 -2.8960493667789873
+  3   6 L 2.2478393639958036 1.8621631139566732 2.0660057758331045 
-0.3135140955237814 1.783216881610604 -2.8960493667789873
+  4   6 j 2.2478393639958036 1.8621631139566732 2.0660057758331045 
-0.3135140955237814 2.2478393639958036 1.8621631139566732
+  4   7 L 2.0660057758331045 -0.3135140955237814 2.0922079131171945 
-0.026123094109737011 2.2478393639958036 1.8621631139566732
+  5   8 Q 2.0922079131171945 -0.026123094109737011 2.0945566700001779 
5.7910818359374616e-05 2.2478393639958036 1.8621631139566732
+  6   8 j 2.0922079131171945 -0.026123094109737011 2.0945566700001779 
5.7910818359374616e-05 2.0922079131171945 -0.026123094109737011
+  6   9 L 2.0945566700001779 5.7910818359374616e-05 2.0945514746903111 
-7.6478343657981895e-08 2.0922079131171945 -0.026123094109737011
+  7   9 j 2.0945566700001779 5.7910818359374616e-05 2.0945514746903111 
-7.6478343657981895e-08 2.0945566700001779 5.7910818359374616e-05
+  7  10 L 2.0945514746903111 -7.6478343657981895e-08 2.0945514815423065 
-2.2382096176443156e-13 2.0945566700001779 5.7910818359374616e-05
+  8  11 Q 2.0945514815423065 -2.2382096176443156e-13 2.0945514815423265 
-8.8817841970012523e-16 2.0945566700001779 5.7910818359374616e-05
+  9  12 Q 2.0945514815423265 -8.8817841970012523e-16 2.0945514815423274 
9.7699626167013776e-15 2.0945566700001779 5.7910818359374616e-05
+ 10  12 j 2.0945514815423265 -8.8817841970012523e-16 2.0945514815423274 
9.7699626167013776e-15 2.0945514815423265 -8.8817841970012523e-16
+ 10  12 k 2.0945514815423274 9.7699626167013776e-15 2.0945514815423265 
-8.8817841970012523e-16 2.0945514815423274 9.7699626167013776e-15
+10 iterations, 12 evaluations; final interval:
  b +2.09455148154232650981 fb -8.88178419700125232339e-16
  c +2.09455148154232739799 fc +9.76996261670137755573e-15
 )--cut-here--";
@@ -881,11 +881,11 @@ void test_hodgepodge()
     //   6ϵ|iterand|
     // because the other term vanishes--it does not give more
     // precision than the hardware is capable of, though it's a
-    // chasing after wind that costs many iterations.
+    // chasing after wind that costs many evaluations.
 
     e_nineteenth e_19;
 
-    // Number of iterations:
+    // Number of evaluations:
     //   195 Brent's table 4.1 (IBM 360)
     //   171 x86_64 brent_zero (IEEE 754)
     //   169 x86_64 decimal_root (differs slightly due to rounding)
@@ -911,12 +911,12 @@ void test_hodgepodge()
     // so the computed function becomes zero: see the documentation
     // for max_err().
 
-    // Assertions labelled 'weak' test the number of iterations
+    // Assertions labelled 'weak' test the number of evaluations
     // against empirical measurements (with various architectures)
     // rather than a theoretical maximum. Perhaps they'll always
     // succeed, because floating-point behavior is determinate;
     // but small variations betoken no catastrophe.
-    LMI_TEST(169 <= r.n_iter && r.n_iter <= 173); // weak
+    LMI_TEST(169 <= r.n_eval && r.n_eval <= 173); // weak
 
     d = brent_zero(eq_2_1, -100.0, 100.0, 0.5);
     zeta = -100.0;
@@ -926,11 +926,11 @@ void test_hodgepodge()
     r = decimal_root(eq_2_1, -100.0, 100.0, bias_none, 0);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST(-100.0 <= r.root && r.root <= eq_2_1_upper);
-    LMI_TEST(10 == max_n_iter_bolzano(-100.0, 100.0, 0.5, -100.0));
-    LMI_TEST(98 == max_n_iter_brent  (-100.0, 100.0, 0.5, -100.0));
-    LMI_TEST(r.n_iter <= 98);
-    LMI_TEST_EQUAL(20, r.n_iter); // weak
-    // Number of iterations required:
+    LMI_TEST(10 == max_n_eval_bolzano(-100.0, 100.0, 0.5, -100.0));
+    LMI_TEST(98 == max_n_eval_brent  (-100.0, 100.0, 0.5, -100.0));
+    LMI_TEST(r.n_eval <= 98);
+    LMI_TEST_EQUAL(20, r.n_eval); // weak
+    // Number of evaluations required:
     //   23 for brent_zero() [above]
     //   20 for decimal_root()
     // Presumably the difference is due to rounding.
@@ -952,31 +952,31 @@ void test_hodgepodge()
     t = 0.5 * std::pow(10.0, -20.0);
     LMI_TEST(-100.0 <= r.root && r.root <= zeta + max_err(zeta, t));
 
-    LMI_TEST(  53 == max_n_iter_bolzano(-100.0, 100.0, 0.0, -100.0));
-    LMI_TEST(2807 == max_n_iter_brent  (-100.0, 100.0, 0.0, -100.0));
-    LMI_TEST(r.n_iter <= 2807);
-    LMI_TEST_EQUAL(66, r.n_iter); // weak
+    LMI_TEST(  53 == max_n_eval_bolzano(-100.0, 100.0, 0.0, -100.0));
+    LMI_TEST(2807 == max_n_eval_brent  (-100.0, 100.0, 0.0, -100.0));
+    LMI_TEST(r.n_eval <= 2807);
+    LMI_TEST_EQUAL(66, r.n_eval); // weak
 
     r = decimal_root(signum_offset, -1.0, 1.0, bias_none, 13);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST(materially_equal(-1.0 / 3.0, r.root));
     zeta = 1.0 / 3.0;
     double tol = 0.5 * 1.0e-13;
-    LMI_TEST_EQUAL(  47, max_n_iter_bolzano(-1.0, 1.0, tol, zeta));
-    LMI_TEST_EQUAL(2207, max_n_iter_brent  (-1.0, 1.0, tol, zeta));
-    LMI_TEST(r.n_iter <= 2207);
+    LMI_TEST_EQUAL(  47, max_n_eval_bolzano(-1.0, 1.0, tol, zeta));
+    LMI_TEST_EQUAL(2207, max_n_eval_brent  (-1.0, 1.0, tol, zeta));
+    LMI_TEST(r.n_eval <= 2207);
     // Here, decimal_root() always chooses the bisection technique.
-    LMI_TEST(46 <= r.n_iter && r.n_iter <= 47); // weak
+    LMI_TEST(46 <= r.n_eval && r.n_eval <= 47); // weak
 
     r = decimal_root(signum_offset, -1.0, 1.0, bias_none, 16);
     LMI_TEST(root_is_valid == r.validity);
     LMI_TEST(materially_equal(-1.0 / 3.0, r.root));
     tol = 0.5 * 1.0e-16;
-    LMI_TEST_EQUAL(  55, max_n_iter_bolzano(-1.0, 1.0, tol, zeta));
-    LMI_TEST_EQUAL(3023, max_n_iter_brent  (-1.0, 1.0, tol, zeta));
-    LMI_TEST(r.n_iter <= 3023);
+    LMI_TEST_EQUAL(  55, max_n_eval_bolzano(-1.0, 1.0, tol, zeta));
+    LMI_TEST_EQUAL(3023, max_n_eval_brent  (-1.0, 1.0, tol, zeta));
+    LMI_TEST(r.n_eval <= 3023);
     // Here, decimal_root() always chooses the bisection technique.
-    LMI_TEST_EQUAL(55, r.n_iter); // weak
+    LMI_TEST_EQUAL(55, r.n_eval); // weak
 }
 
 void test_former_rounding_problem()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]