lmi-commits
[Top][All Lists]

## [lmi-commits] [lmi] master e73bc36 01/11: Use mathematical symbols in co

 From: Greg Chicares Subject: [lmi-commits] [lmi] master e73bc36 01/11: Use mathematical symbols in comments Date: Thu, 1 Jul 2021 20:19:03 -0400 (EDT)

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

---
zero.hpp      | 24 ++++++++++++------------
zero_test.cpp | 18 +++++++++---------
2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/zero.hpp b/zero.hpp
index 91578b3..e954768 100644
--- a/zero.hpp
+++ b/zero.hpp
@@ -92,7 +92,7 @@ inline void expatiate
/// that is, the input bounds include or bracket a root.
///
/// Postcondition: z is within a tolerance
-///   6 * epsilon * |z| + 10^-decimals
+///   6ϵ|z| + 10^(-decimals)
/// of a true zero.
///
/// Brent's algorithm with GWC modifications described below. See:
@@ -155,14 +155,14 @@ inline void expatiate
/// The original algorithm returns a zero z of the function f in
///   [bound0 bound1]
/// (a,b) to within a tolerance
-///   6 * epsilon * |z| + 2 * t
+///   6ϵ|z| + 2t
/// where t is an argument. For life insurance illustrations, the
/// tolerance is often one-sided, so that f(z) must be strictly greater
/// than or less than zero, and the tolerance is more conveniently
/// expressed as a number of decimals. An adjustment is made for the
/// constant factor in Brent's t term, so that this implementation's
/// tolerance becomes
-///   6 * epsilon * |z| + 10^-decimals
+///   6ϵ|z| + 10^(-decimals)
///
/// The original algorithm returns unrounded values. For life insurance
/// illustrations, rounded values are more often wanted, so iterands
@@ -220,16 +220,16 @@ inline void expatiate
///
/// However, Brent calculates tol in terms of b, guaranteeing a maximum
/// error of
-///   6 * epsilon * |b| + 2 * t
+///   6ϵ|b| + 2t
/// when returning b. Unconditionally returning c would give an error
/// bound in terms of the local variable b, whose value is unknown to
/// the caller, and |b| might exceed |c|. It is irrelevant that the
-/// return value is multiplied by epsilon, which might often be so
-/// small as to make the first part of the error term vanish, because
-/// the return value might far exceed the reciprocal of epsilon. To
-/// preserve the algorithm's rigorous guarantees, c is returned, when
-/// bias so dictates, only if Brent's termination criterion is still
-/// met when reevaluated in terms of c instead of b.
+/// return value is multiplied by ϵ, which might often be so small as
+/// to make the first part of the error term vanish, because the
+/// return value might far exceed the reciprocal of ϵ. To preserve
+/// the algorithm's rigorous guarantees, c is returned, when bias so
+/// dictates, only if Brent's termination criterion is still met when
+/// reevaluated in terms of c instead of b.
///
/// It might appear that the code could be simplified, say, by defining
/// tol in terms of max(|b|,|c|), but that would be dangerous: tol is
@@ -435,8 +435,8 @@ double brent_zero
constexpr double epsilon {std::numeric_limits<double>::epsilon()};

// Returns a zero of the function f in [a,b] to within a tolerance
-    //   6 * epsilon * |z| + 2 * t
-    // f(a) and f(b) must have different signs.
+    //   6ϵ|ζ| + 2t
+    // Precondition: f(a) and f(b) have different signs.
double fa = f(a);
double fb = f(b);
double fc = fb;
diff --git a/zero_test.cpp b/zero_test.cpp
index ff59be8..e68b94a 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -39,8 +39,8 @@ static double const epsilon =
std::numeric_limits<double>::epsilon();
///
/// As the paragraph following that equation emphasizes, "the effect
/// of rounding errors in the computation of f" must be considered,
-/// as Brent's method can "only guarantee to find a zero 'zeta' of the
-/// computed function f to an accuracy given by (2.18), and 'zeta' may be
+/// as Brent's method can "only guarantee to find a zero ζ of the
+/// computed function f to an accuracy given by (2.18), and ζ may be
/// nowhere near a root of the mathematically defined function that
/// the user is really interested in!".

@@ -331,7 +331,7 @@ void test_various_functions()
// that doesn't matter, because a term involving machine epsilon
// is always added to the effective tolerance. An excessively
// low input tolerance makes the effective tolerance simply
-    //   6 * epsilon * |iterand|
+    //   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.
@@ -355,10 +355,10 @@ void test_various_functions()
// because the RHS might be 9.99999999999999945153e-21, e.g.)
//
// Brent's equation 2.18 gives the guaranteed maximum error as
-    //   6.0 * epsilon * std::fabs(zeta) + 2.0 * t;
-    // where, because 'zeta' is exactly zero, the epsilon term
-    // vanishes. However, the result (for x86_64-pc-linux-gnu) is
-    // 5.89e-18, which exceeds that guaranteed maximum error. Why?
+    //   6ϵ|ζ| + 2t
+    // where, because ζ is exactly zero, the ϵ term vanishes.
+    // However, the result (for x86_64-pc-linux-gnu) is 5.89e-18,
+    // which exceeds that guaranteed maximum error. Why?
//  LMI_TEST(std::fabs(r.root) <= max_err(zeta, t)); // fails
// Because 5.89e-18^19 is just slightly less than DBL_TRUE_MIN,
// so the computed function becomes zero: see the documentation
@@ -412,11 +412,11 @@ void test_various_functions()
//    -99.9999999999999147349   1
//   -100                      -6.41168279659337119941e+62
// in whose vicinity the error term in Brent's equation 2.18
-    //   6.0 * epsilon * std::fabs(zeta) + 2.0 * t;
+    //   |ζ′-ζ| ≤ 6ϵ|ζ| + 2t
// with t=0.5*10^-20 becomes
//   600e 1.33226762955018784851e-13
//   + 2t 0.00000010000000000000e-13 (same as 1.0e-20)
-    // where the 'epsilon' term overwhelms the 't' term.
+    // where the ϵ term overwhelms the t term.
t = 0.5 * std::pow(10.0, -20.0);
LMI_TEST(-100.0 <= r.root && r.root <= zeta + max_err(zeta, t));

```