[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 012967c 08/22: Diagnose any attempt to find a
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 012967c 08/22: Diagnose any attempt to find a root in a zero-measure interval |
Date: |
Sun, 6 Jun 2021 21:38:00 -0400 (EDT) |
branch: master
commit 012967c234cbe225d3b006c63b0a566a3d45e831
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Diagnose any attempt to find a root in a zero-measure interval
Trying to find a zero of a function in [k,k] is probably a mistake.
Indeed this diagnostic identified a futile unit test, which attempted
to find a zero of f(x)=x^19 in [0,0] to within a tolerance of 1e100,
which had previously been deemed to succeed. Temporarily suppressed
that test.
---
financial.hpp | 2 ++
gpt_specamt.cpp | 2 ++
ihs_avsolve.cpp | 5 +++++
solve.cpp | 5 +++++
zero.hpp | 8 +++++++-
zero_test.cpp | 7 ++++++-
6 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/financial.hpp b/financial.hpp
index 5e9d60a..de7b2ec 100644
--- a/financial.hpp
+++ b/financial.hpp
@@ -129,6 +129,8 @@ class irr_helper
// Return -100% if NPVs of a priori bounds have same sign.
case root_not_bracketed:
{return -1.0L;}
+ case improper_bounds:
+ {throw "IRR: improper bounds.";}
}
throw "Unreachable--silences a compiler diagnostic.";
}
diff --git a/gpt_specamt.cpp b/gpt_specamt.cpp
index ad911f4..d2cf144 100644
--- a/gpt_specamt.cpp
+++ b/gpt_specamt.cpp
@@ -176,6 +176,8 @@ currency gpt_specamt::CalculateSpecAmt
{return a_Values.round_specamt().c(solution.first);}
case root_not_bracketed:
{return a_Values.min_issue_spec_amt();}
+ case improper_bounds:
+ {throw "CalculateSpecAmt: improper bounds.";}
}
throw "Unreachable--silences a compiler diagnostic.";
}
diff --git a/ihs_avsolve.cpp b/ihs_avsolve.cpp
index 1ee549e..a18cdd5 100644
--- a/ihs_avsolve.cpp
+++ b/ihs_avsolve.cpp
@@ -484,6 +484,11 @@ currency AccountValue::Solve
}
}
break;
+ case improper_bounds:
+ {
+ alarum() << "Improper bounds." << LMI_FLUSH;
+ }
+ break;
}
return solution_cents;
}
diff --git a/solve.cpp b/solve.cpp
index ff665bb..10625af 100644
--- a/solve.cpp
+++ b/solve.cpp
@@ -358,6 +358,11 @@ currency AccountValue::Solve()
warning() << "solution not found. Using zero instead." <<
LMI_FLUSH;
}
break;
+ case improper_bounds:
+ {
+ alarum() << "Improper bounds." << LMI_FLUSH;
+ }
+ break;
}
return solution_cents;
}
diff --git a/zero.hpp b/zero.hpp
index b3ec634..0b255a4 100644
--- a/zero.hpp
+++ b/zero.hpp
@@ -51,6 +51,7 @@ enum interpolation_technique
enum root_validity
{root_is_valid
,root_not_bracketed
+ ,improper_bounds
};
typedef std::pair<double,root_validity> root_type;
@@ -80,7 +81,7 @@ inline void expatiate
/// Return a zero z of a function f within input bounds [a,b].
///
-/// Precondition: either
+/// Preconditions: bounds are distinct after rounding; and either
/// 0.0 == f(a), or
/// 0.0 == f(b), or
/// f(a) and f(b) have opposite signs;
@@ -272,6 +273,11 @@ root_type decimal_root
double a = round_dec(bound0);
double b = round_dec(bound1);
+ if(a == b)
+ {
+ return std::make_pair(a, improper_bounds);
+ }
+
double fa = static_cast<double>(f(a));
detail::expatiate(number_of_iterations, os_trace, technique, a, fa);
if(0.0 == fa) // Note 0.
diff --git a/zero_test.cpp b/zero_test.cpp
index a5b2f94..2ee0635 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -182,6 +182,11 @@ int test_main(int, char*[])
r = decimal_root(0.5, 5.0, bias_none, 9, e);
LMI_TEST(root_is_valid == r.second);
+ // Test failure with improper interval.
+
+ r = decimal_root(1.0, 1.0, bias_none, 9, e);
+ LMI_TEST(improper_bounds == r.second);
+
// Test failure with interval containing no root.
r = decimal_root(0.1, 1.0, bias_none, 9, e);
@@ -244,7 +249,7 @@ int test_main(int, char*[])
double d = brent_zero(-1.0, 4.0, 1.0e-20, e_19);
LMI_TEST(std::fabs(d) <= epsilon);
- test_zero(-1.0, 4.0, -100, e_19, std::exp(1.0));
+// test_zero(-1.0, 4.0, -100, e_19, std::exp(1.0));
test_zero(-1.0, 4.0, 0, e_19, std::exp(1.0));
test_zero(-1.0, 4.0, 100, e_19, std::exp(1.0));
- [lmi-commits] [lmi] master updated (f0526be -> 86661b6), Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 7bd1245 01/22: Add a unit test: root of another unfriendly function, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master c01b9b0 02/22: Improve concinnity, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 012967c 08/22: Diagnose any attempt to find a root in a zero-measure interval,
Greg Chicares <=
- [lmi-commits] [lmi] master 83eb025 05/22: Rename a local variable, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master ec0a308 06/22: Refactor, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 99aebcc 07/22: Treat decimal_root return value more flexibly, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 5c31ab3 09/22: Fix latent unit-test errors, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 2391573 11/22: Rename a variable, for terseness, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master b14e318 18/22: Adjust tolerance for a particular unit-test function, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 1c448d8 20/22: Augment decimal_root()'s return type, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 53c3513 21/22: Reorder unit tests, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 5cf534c 04/22: Constify, Greg Chicares, 2021/06/06
- [lmi-commits] [lmi] master 3865416 10/22: Rearrange certain unit tests, Greg Chicares, 2021/06/06