[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master a041329 08/23: Consider bounds not to bracket
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master a041329 08/23: Consider bounds not to bracket a root if value at either is NaN |
Date: |
Tue, 27 Jul 2021 21:59:51 -0400 (EDT) |
branch: master
commit a041329f6a59fb130b6f31ead07abe66ca659fa2
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Consider bounds not to bracket a root if value at either is NaN
---
zero.hpp | 6 +++---
zero_test.cpp | 35 ++++++++++++++++++++++++-----------
2 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/zero.hpp b/zero.hpp
index f602b1b..1f26878 100644
--- a/zero.hpp
+++ b/zero.hpp
@@ -29,7 +29,7 @@
#include "round_to.hpp"
#include <cfloat> // DBL_EPSILON, DECIMAL_DIG
-#include <cmath> // fabs(), isfinite(), pow()
+#include <cmath> // fabs(), isfinite(), isnan(), pow()
#include <cstdint> // uint64_t
#include <cstring> // memcpy()
#include <functional> // function(), identity()
@@ -465,8 +465,8 @@ root_type lmi_root
return {b, root_is_valid, n_iter};
}
- // f(a) and f(b) must have different signs.
- if((0.0 < fa) == (0.0 < fb))
+ // 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};
diff --git a/zero_test.cpp b/zero_test.cpp
index 1350fed..b6fec8b 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -517,6 +517,15 @@ void test_NaNs()
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);
LMI_TEST(materially_equal(1.0e100, std::fabs(r.root)));
+
+ // If the function's value is a NaN at either input bound, then
+ // no root is bracketed.
+ r = lmi_root(NaN_signed, -1.0e100, 2.0 * pi, 5.0e-1);
+ LMI_TEST_EQUAL(root_not_bracketed, r.validity);
+ r = lmi_root(NaN_signed, -2.0 * pi, 1.0e100, 5.0e-1);
+ LMI_TEST_EQUAL(root_not_bracketed, r.validity);
+ r = lmi_root(NaN_signed, -2.0 * pi, 2.0 * pi, 5.0e-1);
+ LMI_TEST_EQUAL(root_not_bracketed, r.validity);
}
/// Find a root that coincides with one or both bounds.
@@ -658,17 +667,21 @@ void test_biases()
// Various tests--see function-template definition.
- test_bias(-1.0e100, 4.0e100, -100, e, std::exp(1.0));
- test_bias(-1.0 , 4.0 , 0, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 1, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 2, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 3, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 4, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 5, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 6, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 7, e, std::exp(1.0));
- test_bias( 0.5 , 5.0 , 8, e, std::exp(1.0));
- test_bias(-1.0 , 4.0 , 100, e, std::exp(1.0));
+ // Rounding to -100 decimals makes the maximum error 1e+100,
+ // which probably isn't useful in practice.
+ test_bias(0.0, 4.0e100, -100, e, std::exp(1.0));
+ test_bias(0.0, 4.0 , 0, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 1, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 2, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 3, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 4, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 5, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 6, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 7, e, std::exp(1.0));
+ test_bias(0.5, 5.0 , 8, e, std::exp(1.0));
+ // Rounding to 100 decimals shouldn't round at all; the
+ // effective maximum error is 6ϵ × e = 3.62148e-15 .
+ test_bias(0.0, 4.0 , 100, e, std::exp(1.0));
}
/// Test the worked-out example given here:
- [lmi-commits] [lmi] master updated (d6bd802 -> 028b454), Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master eea9469 02/23: Ignore an immaterial i686 deviation, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master a041329 08/23: Consider bounds not to bracket a root if value at either is NaN,
Greg Chicares <=
- [lmi-commits] [lmi] master c9c50dc 07/23: Add a specialized midpoint function for root finding, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master f576a4b 11/23: Augment unit test, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master dc63e62 16/23: Cache evaluations for rounded decimal solves, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master cecc91f 21/23: Avoid a unit-test false negative, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master 4b26bf8 01/23: Add a parenthetical comment to a unit test, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master 86ae65d 18/23: Revert "Demonstration, for immediate reversion", Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master e59df26 14/23: Refactor, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master 8f2f355 19/23: Augment unit tests; record some observations, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master a259cb6 05/23: Calculate maximum possible number of iterations, Greg Chicares, 2021/07/27
- [lmi-commits] [lmi] master d0a65c2 04/23: Demonstrate that Brent's δ can be almost arbitrarily small, Greg Chicares, 2021/07/27