[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] odd/eraseme_error dfd50b1 07/10: Find a root that co
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] odd/eraseme_error dfd50b1 07/10: Find a root that coincides with an input bound |
Date: |
Wed, 7 Jul 2021 06:22:14 -0400 (EDT) |
branch: odd/eraseme_error
commit dfd50b16aa6573c8d263588d5533ea3327691ec9
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Find a root that coincides with an input bound
---
zero_test.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/zero_test.cpp b/zero_test.cpp
index 2441887..938a31c 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -339,6 +339,107 @@ void test_fundamentals()
LMI_TEST(root_not_bracketed == r.validity);
}
+/// Find a root that coincides with one or both bounds.
+///
+/// In this special case, lmi_root() returns the root as soon as
+/// possible. The reference implementation does not.
+
+void test_root_at_a_bound()
+{
+ auto f = [](double x) {return x;};
+ double tol = 1.0e-15;
+ double zeta = 0.0;
+ root_type r;
+
+ // No root in bounding interval.
+ r = lmi_root(f, -1.0, -1.0, tol);
+ LMI_TEST(improper_bounds == r.validity);
+
+ // Root is second bound: found on second evaluation.
+ 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);
+
+ // 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);
+
+ // 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);
+
+ // Returns an error status, even though the root coincides with
+ // both bounds. Attempting to find a root between identical bounds
+ // is presumably an error, which should be reported immediately
+ // 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ r = lmi_root(f, 1.0, 1.0, tol);
+ LMI_TEST(improper_bounds == r.validity);
+
+ // Repeat representative cases with decimal rounding.
+
+ // No root in bounding interval.
+ r = decimal_root(f, -0.96, -1.04, bias_none, 1);
+ LMI_TEST(improper_bounds == r.validity);
+
+ // Root is rounded second bound: found on second evaluation.
+ 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);
+
+ // 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);
+
+ // 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);
+
+ // 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);
+
+ // A curious effect of rounding the input bounds.
+
+ // Literal bounds [0.04, 0.09] bracket no root.
+ // Effective bounds [0.0 , 0.1 ] bracket a root.
+ // The exact true root, 0.0, is returned, because the literal
+ // input bounds are replaced by the rounded effective bounds.
+ 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);
+}
+
void test_biases()
{
// Test different biases.
@@ -716,6 +817,7 @@ void test_former_rounding_problem()
int test_main(int, char*[])
{
test_fundamentals();
+ test_root_at_a_bound();
test_biases();
test_celebrated_equation();
test_wikipedia_example();
- [lmi-commits] [lmi] branch odd/eraseme_error created (now 69d06e9), Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error dd8fb62 01/10: Postpone consideration of NaN-valued objective functions, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error 1dbe0b4 02/10: Refactor, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error a3f38b5 03/10: Refactor instrumented reference implementation, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error 4d0358c 04/10: Rename an enumeration, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error 2870f56 05/10: Reenumerate root-finding techniques, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error b19754f 06/10: Show shifts in optional trace, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error dfd50b1 07/10: Find a root that coincides with an input bound,
Greg Chicares <=
- [lmi-commits] [lmi] odd/eraseme_error dec4d54 09/10: Rename operations, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error 69d06e9 10/10: Attempt to find a problem, Greg Chicares, 2021/07/07
- [lmi-commits] [lmi] odd/eraseme_error b862db3 08/10: Uniformly test two functions in parallel, Greg Chicares, 2021/07/07