lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 6cea04a 4/5: Revert "Experimental quasi-branc


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 6cea04a 4/5: Revert "Experimental quasi-branch: TOMS 748"
Date: Mon, 16 Aug 2021 13:35:44 -0400 (EDT)

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

    Revert "Experimental quasi-branch: TOMS 748"
    
    This reverts commit 8a94c7832f5d35a5428bf2b05ba2f857bdc980c3.
    
    Reversion was the original intention.
    
    Updated preliminary comments about TOMS 748 with actual measurements.
---
 zero.hpp      | 526 ++--------------------------------------------------------
 zero_test.cpp | 117 -------------
 2 files changed, 11 insertions(+), 632 deletions(-)

diff --git a/zero.hpp b/zero.hpp
index d79ae9c..e1afc92 100644
--- a/zero.hpp
+++ b/zero.hpp
@@ -247,10 +247,17 @@ inline double binary64_midpoint(double d0, double d1)
 /// best is ACM Algorithm 748 (Transactions on Mathematical Software):
 ///   
https://na.math.kit.edu/alefeld/download/1995_Algorithm_748_Enclosing_Zeros_of_Continuous_Functions.pdf
 /// whose Table II compares Brent's algorithm to TOMS748 for fifteen
-/// test problems, claiming an advantage of 4-6%. A typical lmi solve
-/// takes ten or twenty iterations, so that would represent saving
-/// less than one iteration on average. It would be interesting to
-/// test TOMS758 with lmi, but there's little hope of any real gain.
+/// test problems, claiming an advantage of 4-6%. Chandrupatla
+/// proposed a more stringent criterion for accepting IQI iterates,
+/// and a simplified root-finding method that uses it. However, actual
+/// measurements show that, for the 388 solves in lmi's regression
+/// test, the number of evaluations (i.e., account-value projections)
+/// required is:
+///   7332 Brent
+///   7622 TOMS748
+///   9149 Chandrupatla's method
+///   8545 Brent, with Chandrupatla's IQI acceptance criterion
+/// so Brent's method is favored for lmi.
 ///
 /// Newton's method has quadratic convergence, in the vicinity of a
 /// root, for well-behaved functions (though its performance in the
@@ -1031,515 +1038,4 @@ double brent_zero_reference
     return b;
 }
 
-// Source:
-//  https://www.netlib.org/toms-2014-06-10/748
-// separated into '.f' files manually, and translated thus:
-//   f2c -a *.f
-// Compiled thus, with minimal editing, for validation:
-//   gcc driver.c enclofx.c -lf2c -lm 2>&1 |less
-// excluding 'exdrive.c' because it is apparently an alternative
-// to 'driver.c'. The code here is a combination of 'driver.c'
-// and 'enclofx.c', edited extensively to make it work with lmi.
-
-/* Table of constant values */
-
-static int c2 = 2;
-static int c3 = 3;
-
-int tole_(double* b, double* tol, int* neps, double* eps);
-int func_(int* /* nprob */, double* x, double* fx);
-template<typename FunctionalType>
-int rroot_(FunctionalType& f, int* nprob, int* neps, double* eps,
-        double* a, double* b, double* root, int* n_eval);
-template<typename FunctionalType>
-int brackt_(FunctionalType& f, int* nprob, double* a, double* b,
-        double* c0, double* fa, double* fb, double* tol,
-        int* neps, double* eps, double* d_0, double* fd);
-int isign_(double* x);
-int newqua_(double* a, double* b, double* d_0,
-        double* fa, double* fb, double* fd, double* c0,
-        int* k);
-int pzero_(double* a, double* b, double* d_0,
-        double* e, double* fa, double* fb, double* fd,
-        double* fe, double* c0);
-int rmp_(double* rel);
-
-inline int tole_(double* b, double* tol, int* neps, double* eps)
-{
-    /* System generated locals */
-    int i1;
-
-    /* Local variables */
-    int i0;
-
-/* DETERMINES THE TERMINATION CRITERION. */
-/*  B    -- DOUBLE PRECISION. */
-/*  NEPS -- INTEGER. */
-/*  EPS  -- DOUBLE PRECISION. */
-/*  TOL  -- DOUBLE PRECISION. OUTPUT AS THE TERMINATION CRITERION. */
-/*           TOL =2*(2*EPS*|B| + 10D-{NEPS}),  IF NEPS IS NOT 1000; */
-/*    AND    TOL =2*(2*EPS*|B|),               IF NEPS = 1000. */
-    if (*neps == 1000) {
-        *tol = 0.;
-    } else {
-//      *tol = 1.;
-// Changed by GWC: same tolerance as decimal_root()
-        *tol = 0.5;
-        i1 = *neps;
-        for (i0 = 1; i0 <= i1; ++i0) {
-            *tol /= 10.;
-/* L10: */
-        }
-    double const tolx = 0.5 * std::pow(10.0, -*neps);
-//  std::cout << "tolerance " << *tol << " should equal " << tolx << std::endl;
-    // Use the calculation copied from decimal_root() instead:
-    // it differs slightly, and is probably more exact than
-    // dividing repeatedly by ten.
-    *tol = tolx;
-    }
-    *tol += abs(*b) * 2. * *eps;
-    *tol *= 2.;
-//  std::cout << "actual tolerance " << *tol << std::endl;
-    return 0;
-}
-
-inline int func_(int* /* nprob */, double* x, double* fx)
-{
-    *fx = std::sin(*x) - *x / 2.;
-    return 0;
-}
-
-/* *** enclofx.f */
-template<typename FunctionalType>
-int rroot_(FunctionalType& f, int* nprob, int* neps, double* eps,
-        double* a, double* b, double* root, int* n_eval)
-{
-    /* System generated locals */
-    double d_1;
-
-    /* Local variables */
-    double c0, d_0, e, u, a0, b0, fa, fb, fd, fe, fu, tol;
-    double prof;
-    int itnum;
-
-/* FINDS EITHER AN EXACT SOLUTION OR AN APPROXIMATE SOLUTION OF THE */
-/* EQUATION F(X)=0 IN THE INTERVAL [A,B]. AT THE BEGINING OF EACH */
-/* ITERATION, THE CURRENT ENCLOSING INTERVAL IS RECORDED AS [A0,B0]. */
-/* THE FIRST ITERATION IS SIMPLY A SECANT STEP. STARTING WITH THE */
-/* SECOND ITERATION, THREE STEPS ARE TAKEN IN EACH ITERATION. FIRST */
-/* TWO STEPS ARE EITHER QUADRATIC INTERPOLATION OR CUBIC INVERSE */
-/* INTERPOLATION. THE THIRD STEP IS A DOUBLE-SIZE SECANT STEP. IF THE */
-/* DIAMETER OF THE ENCLOSING INTERVAL OBTAINED AFTER THOSE THREE STEPS */
-/* IS LARGER THAN 0.5*(B0-A0), THEN AN ADDITIONAL BISECTION STEP WILL */
-/* BE TAKEN. */
-/*  NPROB -- INTEGER. INDICATING THE PROBLEM TO BE SOLVED; */
-/*  NEPS  -- INTEGER. USED TO DETERMINE THE TERMINATION CRITERION; */
-/*  EPS   -- DOUBLE PRECISION. USED IN THE TERMINATION CRITERION; */
-/*  A,B   -- DOUBLE PRECISION. INPUT AS THE INITIAL INTERVAL AND */
-/*           OUTPUT AS THE ENCLOSING INTERVAL AT THE TERMINATION; */
-/*  ROOT  -- DOUBLE PRECISION. OUTPUT SOLUTION OF THE EQUATION. */
-
-/* INITIALIZATION. SET THE NUMBER OF ITERATION AS 0. CALL SUBROUTINE */
-/* "FUNC" TO OBTAIN THE INITIAL FUNCTION VALUES F(A) AND F(B). SET */
-/* DUMB VALUES FOR THE VARIABLES "E" AND "FE". */
-
-    itnum = 0;
-    fa = f(*a); // f(a, fa);
-    fb = f(*b); // f(b, fb);
-    *n_eval = 2; // Two evaluations have now been performed.
-    e = 1e5;
-    fe = 1e5;
-
-/* ITERATION STARTS. THE ENCLOSING INTERVAL BEFORE EXECUTING THE */
-/* ITERATION IS RECORDED AS [A0, B0]. */
-
-  L10:
-    a0 = *a;
-    b0 = *b;
-
-/* UPDATES THE NUMBER OF ITERATION. */
-
-    ++itnum;
-
-/* CALCULATES THE TERMINATION CRITERION. STOPS THE PROCEDURE IF THE */
-/* CRITERION IS SATISFIED. */
-
-    if (abs(fb) <= abs(fa)) {
-        tole_(b, &tol, neps, eps);
-    } else {
-        tole_(a, &tol, neps, eps);
-    }
-    if (*b - *a <= tol) {
-        goto L400;
-    }
-
-/* FOR THE FIRST ITERATION, SECANT STEP IS TAKEN. */
-
-    if (itnum == 1) {
-        c0 = *a - fa / (fb - fa) * (*b - *a);
-
-/* CALL SUBROUTINE "BRACKT" TO GET A SHRINKED ENCLOSING INTERVAL AS */
-/* WELL AS TO UPDATE THE TERMINATION CRITERION. STOP THE PROCEDURE */
-/* IF THE CRITERION IS SATISFIED OR THE EXACT SOLUTION IS OBTAINED. */
-
-        brackt_(f, nprob, a, b, &c0, &fa, &fb, &tol, neps, eps, &d_0, &fd);
-        ++*n_eval;
-        if (fa == 0. || *b - *a <= tol) {
-            goto L400;
-        }
-        goto L10;
-    }
-
-/* STARTING WITH THE SECOND ITERATION, IN THE FIRST TWO STEPS, EITHER */
-/* QUADRATIC INTERPOLATION IS USED BY CALLING THE SUBROUTINE "NEWQUA" */
-/* OR THE CUBIC INVERSE INTERPOLATION IS USED BY CALLING THE SUBROUTINE */
-/* "PZERO". IN THE FOLLOWING, IF "PROF" IS NOT EQUAL TO 0, THEN THE */
-/* FOUR FUNCTION VALUES "FA", "FB", "FD", AND "FE" ARE DISTINCT, AND */
-/* HENCE "PZERO" WILL BE CALLED. */
-
-    prof = (fa - fb) * (fa - fd) * (fa - fe) * (fb - fd) * (fb - fe) * (fd -
-            fe);
-    if (itnum == 2 || prof == 0.) {
-        newqua_(a, b, &d_0, &fa, &fb, &fd, &c0, &c2);
-    } else {
-        pzero_(a, b, &d_0, &e, &fa, &fb, &fd, &fe, &c0);
-        if ((c0 - *a) * (c0 - *b) >= 0.) {
-            newqua_(a, b, &d_0, &fa, &fb, &fd, &c0, &c2);
-        }
-    }
-    e = d_0;
-    fe = fd;
-
-/* CALL SUBROUTINE "BRACKT" TO GET A SHRINKED ENCLOSING INTERVAL AS */
-/* WELL AS TO UPDATE THE TERMINATION CRITERION. STOP THE PROCEDURE */
-/* IF THE CRITERION IS SATISFIED OR THE EXACT SOLUTION IS OBTAINED. */
-
-    brackt_(f, nprob, a, b, &c0, &fa, &fb, &tol, neps, eps, &d_0, &fd);
-    ++*n_eval;
-    if (fa == 0. || *b - *a <= tol) {
-        goto L400;
-    }
-    prof = (fa - fb) * (fa - fd) * (fa - fe) * (fb - fd) * (fb - fe) * (fd -
-            fe);
-    if (prof == 0.) {
-        newqua_(a, b, &d_0, &fa, &fb, &fd, &c0, &c3);
-    } else {
-        pzero_(a, b, &d_0, &e, &fa, &fb, &fd, &fe, &c0);
-        if ((c0 - *a) * (c0 - *b) >= 0.) {
-            newqua_(a, b, &d_0, &fa, &fb, &fd, &c0, &c3);
-        }
-    }
-
-/* CALL SUBROUTINE "BRACKT" TO GET A SHRINKED ENCLOSING INTERVAL AS */
-/* WELL AS TO UPDATE THE TERMINATION CRITERION. STOP THE PROCEDURE */
-/* IF THE CRITERION IS SATISFIED OR THE EXACT SOLUTION IS OBTAINED. */
-
-    brackt_(f, nprob, a, b, &c0, &fa, &fb, &tol, neps, eps, &d_0, &fd);
-    ++*n_eval;
-    if (fa == 0. || *b - *a <= tol) {
-        goto L400;
-    }
-    e = d_0;
-    fe = fd;
-
-/* TAKES THE DOUBLE-SIZE SECANT STEP. */
-
-    if (abs(fa) < abs(fb)) {
-        u = *a;
-        fu = fa;
-    } else {
-        u = *b;
-        fu = fb;
-    }
-    c0 = u - fu / (fb - fa) * 2. * (*b - *a);
-    if ((d_1 = c0 - u, abs(d_1)) > (*b - *a) * .5) {
-        c0 = *a + (*b - *a) * .5;
-    }
-
-/* CALL SUBROUTINE "BRACKT" TO GET A SHRINKED ENCLOSING INTERVAL AS */
-/* WELL AS TO UPDATE THE TERMINATION CRITERION. STOP THE PROCEDURE */
-/* IF THE CRITERION IS SATISFIED OR THE EXACT SOLUTION IS OBTAINED. */
-
-    brackt_(f, nprob, a, b, &c0, &fa, &fb, &tol, neps, eps, &d_0, &fd);
-    ++*n_eval;
-    if (fa == 0. || *b - *a <= tol) {
-        goto L400;
-    }
-
-/* DETERMINES WHETHER AN ADDITIONAL BISECTION STEP IS NEEDED. AND TAKES */
-/* IT IF NECESSARY. */
-
-    if (*b - *a < (b0 - a0) * .5) {
-        goto L10;
-    }
-    e = d_0;
-    fe = fd;
-
-/* CALL SUBROUTINE "BRACKT" TO GET A SHRINKED ENCLOSING INTERVAL AS */
-/* WELL AS TO UPDATE THE TERMINATION CRITERION. STOP THE PROCEDURE */
-/* IF THE CRITERION IS SATISFIED OR THE EXACT SOLUTION IS OBTAINED. */
-
-    d_1 = *a + (*b - *a) * .5;
-    brackt_(f, nprob, a, b, &d_1, &fa, &fb, &tol, neps, eps, &d_0, &fd);
-    ++*n_eval;
-    if (fa == 0. || *b - *a <= tol) {
-        goto L400;
-    }
-    goto L10;
-
-/* TERMINATES THE PROCEDURE AND RETURN THE "ROOT". */
-
-  L400:
-    *root = *a;
-    return 0;
-}
-
-template<typename FunctionalType>
-int brackt_(FunctionalType& f, int* nprob, double* a, double* b,
-        double* c0, double* fa, double* fb, double* tol,
-        int* neps, double* eps, double* d_0, double* fd)
-{
-    (void)&nprob;
-    double fc;
-
-/* GIVEN CURRENT ENCLOSING INTERVAL [A,B] AND A NUMBER C IN (A,B), IF */
-/* F(C)=0 THEN SETS THE OUTPUT A=C. OTHERWISE DETERMINES THE NEW */
-/* ENCLOSING INTERVAL: [A,B]=[A,C] OR [A,B]=[C,B]. ALSO UPDATES THE */
-/* TERMINATION CRITERION CORRESPONDING TO THE NEW ENCLOSING INTERVAL. */
-/*  NPROB   -- INTEGER. INDICATING THE PROBLEM TO BE SOLVED; */
-/*  A,B     -- DOUBLE PRECISION. [A,B] IS INPUT AS THE CURRENT */
-/*             ENCLOSING INTERVAL AND OUTPUT AS THE SHRINKED NEW */
-/*             ENCLOSING INTERVAL; */
-/*  C       -- DOUBLE PRECISION. USED TO DETERMINE THE NEW ENCLOSING */
-/*             INTERVAL; */
-/*  D       -- DOUBLE PRECISION. OUTPUT: IF THE NEW ENCLOSING INTERVAL */
-/*             IS [A,C] THEN D=B, OTHERWISE D=A; */
-/*  FA,FB,FD-- DOUBLE PRECISION. FA=F(A), FB=F(B), AND FD=F(D); */
-/*  TOL     -- DOUBLE PRECISION. INPUT AS THE CURRENT TERMINATION */
-/*             CRITERION AND OUTPUT AS THE UPDATED TERMINATION */
-/*             CRITERION ACCORDING TO THE NEW ENCLOSING INTERVAL; */
-/*  NEPS    -- INTEGER. USED TO DETERMINE THE TERMINATION CRITERION; */
-/*  EPS     -- DOUBLE PRECISION. USED IN THE TERMINATION CRITERION. */
-
-/* ADJUST C IF (B-A) IS VERY SMALL OR IF C IS VERY CLOSE TO A OR B. */
-
-    *tol *= .7;
-    if (*b - *a <= *tol * 2.) {
-        *c0 = *a + (*b - *a) * .5;
-    } else if (*c0 <= *a + *tol) {
-        *c0 = *a + *tol;
-    } else {
-        if (*c0 >= *b - *tol) {
-            *c0 = *b - *tol;
-        }
-    }
-
-/* CALL SUBROUTINE "FUNC" TO OBTAIN F(C) */
-
-    fc = f(*c0); // f(c0, fc);
-
-/* IF F(C)=0, THEN SET A=C AND RETURN. THIS WILL TERMINATE THE */
-/* PROCEDURE IN SUBROUTINE "RROOT" AND GIVE THE EXACT SOLUTION OF */
-/* THE EQUATION F(X)=0. */
-
-    if (fc == 0.) {
-        *a = *c0;
-        *fa = 0.;
-        *d_0 = 0.;
-        *fd = 0.;
-        return 0;
-    }
-
-/* IF F(C) IS NOT ZERO, THEN DETERMINE THE NEW ENCLOSING INTERVAL. */
-
-    if (isign_(fa) * isign_(&fc) < 0) {
-        *d_0 = *b;
-        *fd = *fb;
-        *b = *c0;
-        *fb = fc;
-    } else {
-        *d_0 = *a;
-        *fd = *fa;
-        *a = *c0;
-        *fa = fc;
-    }
-
-/* UPDATE THE TERMINATION CRITERION ACCORDING TO THE NEW ENCLOSING */
-/* INTERVAL. */
-
-    if (abs(*fb) <= abs(*fa)) {
-        tole_(b, tol, neps, eps);
-    } else {
-        tole_(a, tol, neps, eps);
-    }
-
-/* END OF THE SUBROUTINE. */
-
-    return 0;
-} /* brackt_ */
-
-inline int isign_(double* x)
-{
-    /* System generated locals */
-    int ret_val;
-
-/* INDICATES THE SIGN OF THE VARIABLE "X". */
-/*  X     -- DOUBLE PRECISION. */
-/*  ISIGN -- INTEGER. */
-    if (*x > 0.) {
-        ret_val = 1;
-    } else if (*x == 0.) {
-        ret_val = 0;
-    } else {
-        ret_val = -1;
-    }
-    return ret_val;
-} /* isign_ */
-
-inline int newqua_(double* a, double* b, double* d_0,
-        double* fa, double* fb, double* fd, double* c0,
-        int* k)
-{
-    /* System generated locals */
-    int i1;
-
-    /* Local variables */
-    int i0;
-    double a0, a1, a2, pc, pdc;
-    int ierror;
-
-/* USES K NEWTON STEPS TO APPROXIMATE THE ZERO IN (A,B) OF THE */
-/* QUADRATIC POLYNOMIAL INTERPOLATING F(X) AT A, B, AND D. SAFEGUARD */
-/* IS USED TO AVOID OVERFLOW. */
-/*  A,B,D,FA,FB,FD -- DOUBLE PRECISION. D LIES OUTSIDE THE INTERVAL */
-/*                    [A,B]. FA=F(A), FB=F(B), AND FD=F(D). F(A)F(B)<0. */
-/*  C              -- DOUBLE PRECISION. OUTPUT AS THE APPROXIMATE ZERO */
-/*                    IN (A,B) OF THE QUADRATIC POLYNOMIAL. */
-/*  K              -- INTEGER. INPUT INDICATING THE NUMBER OF NEWTON */
-/*                    STEPS TO TAKE. */
-
-/* INITIALIZATION. FIND THE COEFFICIENTS OF THE QUADRATIC POLYNOMIAL. */
-
-    ierror = 0;
-    a0 = *fa;
-    a1 = (*fb - *fa) / (*b - *a);
-    a2 = ((*fd - *fb) / (*d_0 - *b) - a1) / (*d_0 - *a);
-
-/* SAFEGUARD TO AVOID OVERFLOW. */
-
-  L10:
-    if (a2 == 0. || ierror == 1) {
-        *c0 = *a - a0 / a1;
-        return 0;
-    }
-
-/* DETERMINE THE STARTING POINT OF NEWTON STEPS. */
-
-    if (isign_(&a2) * isign_(fa) > 0) {
-        *c0 = *a;
-    } else {
-        *c0 = *b;
-    }
-
-/* START THE SAFEGUARDED NEWTON STEPS. */
-
-    i1 = *k;
-    for (i0 = 1; i0 <= i1; ++i0) {
-        if (ierror == 0) {
-            pc = a0 + (a1 + a2 * (*c0 - *b)) * (*c0 - *a);
-            pdc = a1 + a2 * (*c0 * 2. - (*a + *b));
-            if (pdc == 0.) {
-                ierror = 1;
-            } else {
-                *c0 -= pc / pdc;
-            }
-        }
-/* L20: */
-    }
-    if (ierror == 1) {
-        goto L10;
-    }
-    return 0;
-} /* newqua_ */
-
-inline int pzero_(double* a, double* b, double* d_0,
-        double* e, double* fa, double* fb, double* fd,
-        double* fe, double* c0)
-{
-    double d21, d31, d32, q11, q21, q31, q22, q32, q33;
-
-/* USES CUBIC INVERSE INTERPOLATION OF F(X) AT A, B, D, AND E TO */
-/* GET AN APPROXIMATE ROOT OF F(X). THIS PROCEDURE IS A SLIGHT */
-/* MODIFICATION OF AITKEN-NEVILLE ALGORITHM FOR INTERPOLATION */
-/* DESCRIBED BY STOER AND BULIRSCH IN "INTRO. TO NUMERICAL ANALYSIS" */
-/* SPRINGER-VERLAG. NEW YORK (1980). */
-/*  A,B,D,E,FA,FB,FD,FE -- DOUBLE PRECISION. D AND E LIE OUTSIDE */
-/*                         THE INTERVAL [A,B]. FA=F(A), FB=F(B), */
-/*                         FD=F(D), AND FE=F(E). */
-/*  C                   -- DOUBLE PRECISION. OUTPUT OF THE SUBROUTINE. */
-
-    q11 = (*d_0 - *e) * *fd / (*fe - *fd);
-    q21 = (*b - *d_0) * *fb / (*fd - *fb);
-    q31 = (*a - *b) * *fa / (*fb - *fa);
-    d21 = (*b - *d_0) * *fd / (*fd - *fb);
-    d31 = (*a - *b) * *fb / (*fb - *fa);
-    q22 = (d21 - q11) * *fb / (*fe - *fb);
-    q32 = (d31 - q21) * *fa / (*fd - *fa);
-    d32 = (d31 - q21) * *fd / (*fd - *fa);
-    q33 = (d32 - q22) * *fa / (*fe - *fa);
-
-/* CALCULATE THE OUTPUT C. */
-
-    *c0 = q31 + q32 + q33;
-    *c0 = *a + *c0;
-    return 0;
-} /* pzero_ */
-
-inline int rmp_(double* rel)
-{
-    double a, b, beta;
-
-/* CALCULATES THE RELATIVE MACHINE PRECISION (RMP). */
-/*  REL -- DOUBLE PRECISION. OUTPUT OF RMP. */
-
-    beta = 2.;
-    a = 1.;
-  L10:
-    b = a + 1.;
-    if (b > 1.) {
-        a /= beta;
-        goto L10;
-    }
-    *rel = a * beta;
-    return 0;
-} /* rmp_ */
-
-template<typename FunctionalType>
-root_type toms748_root
-    (FunctionalType& f
-    ,double          bound0
-    ,double          bound1
-    ,root_bias       bias
-    ,int             decimals
-    ,int             sprauchling_limit = INT_MAX
-    ,std::ostream&   os_trace          = null_stream()
-    )
-{
-    // Arguments that are unused, for now at least:
-    (void)&bias;
-    (void)&sprauchling_limit;
-
-    int    nprob  {1};    // has no actual meaning
-//  int    neps   {1000}; // like setting Brent's 'tol' to zero
-    int    neps   {decimals};
-    int    n_eval {0};
-    double eps    {DBL_EPSILON};
-    double a      {bound0};
-    double b      {bound1};
-    double root   {0.0};
-    rroot_(f, &nprob, &neps, &eps, &a, &b, &root, &n_eval);
-    os_trace << " " << n_eval << "    evaluations" << std::endl;
-    return {root, root_is_valid, n_eval - 2, n_eval};
-}
-
 #endif // zero_hpp
diff --git a/zero_test.cpp b/zero_test.cpp
index 28ef609..45a99b0 100644
--- a/zero_test.cpp
+++ b/zero_test.cpp
@@ -1233,122 +1233,6 @@ void test_former_rounding_problem()
     LMI_TEST(root_is_valid == r.validity);
 }
 
-void test_toms748()
-{
-    // begin test adapted from 'driver.f'
-    // (scoped to sequester an oddly imprecise 'pi')
-    {
-    auto f = [](double x) {return std::sin(x) - x / 2.0;};
-    /* Local variables */
-    double a, b, eps;
-    int neps;
-    double root;
-    int nprob;
-
-    int    n_eval {0};
-
-/* THIS PROGRAM CALCULATES A ROOT OF A CONTINUOUS FUNCTION F(X) */
-/* IN AN INTERVAL I=[A, B] PROVIDED THAT F(A)F(B)<0. THE FUNCTION F(X) */
-/* AND THE INITIAL INTERVAL [A, B] ARE TO BE SUPPLIED BY THE USER IN */
-/* THE SUBROUTINES "FUNC" AND "INIT". THE OUTPUT "ROOT" EITHER SATISFIES */
-/* THAT F(ROOT)=0 OR IS AN APPROXIMATE SOLUTION OF THE EQUATION F(X)=0 */
-/* SUCH THAT "ROOT" IS INCLUDED IN AN INTERVAL [AC, BC] WITH */
-/*      F(AC)F(BC)<0, */
-/* AND */
-/*      BC-AC <= TOL = 2*TOLE(AC,BC). */
-/* PRECISION CHOSEN AS THE RELATIVE MACHINE PRECISION, */
-/* AND "UC" IS EQUAL TO EITHER "AC" OR "BC" WITH THE CONDITION */
-/*      |F(UC)| = MIN{ |F(AC)|, |F(BC)| }. */
-
-/* INPUT OF THE PROGRAM: */
-/*  NPROB -- INTEGER. POSITIVE INTEGER STANDING FOR "NUMBER OF PROBLEM", */
-/*           INDICATING THE PROBLEM TO BE SOLVED. */
-/*  N     -- PROBLEM DEPENDENT PARAMETER */
-/* OUTPUT OF THE PROGRAM: */
-/*  ROOT  -- DOUBLE PRECISION. EXACT OR APPROXIMATE SOLUTION OF THE */
-/*           EQUATION F(X)=0. */
-
-nprob = 1;
-a = 0;
-b = 1;
-
-/* USE MACHINE PRECISION */
-
-    rmp_(&eps);
-    neps = 1000;
-// TOMS748 calculation matches DBL_EPSILON:
-//std::cout << eps << " = calculated ϵ" << std::endl;
-//std::cout << DBL_EPSILON << " = DBL_EPSILON" << std::endl;
-
-/* CALL SUBROUTINE "INIT" TO GET THE INITIAL INTERVAL. */
-
-// test problem #1 bounds (hardcoded)
-    double pi;
-    pi = 3.1416; // How very odd to use such a coarse approximation!
-    a = pi / 2.;
-    b = pi;
-
-/* CALL SUBROUTINE "RROOT" TO HAVE THE PROBLEM SOLVED. */
-
-    rroot_(f, &nprob, &neps, &eps, &a, &b, &root, &n_eval);
-
-/* PRINT OUT THE RESULT ON THE SCREEN. */
-
-//  s_stop("", (ftnlen)0);
-//std::cout << "Number of evaluations = " << n_eval << std::endl;
-//std::cout.precision(21);
-//std::cout << "Computed root = " << root << std::endl;
-    } // end test adapted from 'driver.f'
-
-    constexpr double pi {3.14159265358979323851};
-
-    double bound0   {pi / 2.0};
-    double bound1   {pi};
-    int    decimals {7};
-
-    double const tol = 0.5 * std::pow(10.0, -decimals);
-
-    auto f = [](double x) {return std::sin(x) - x / 2.0;};
-
-    std::cout.precision(21);
-
-    root_type r = lmi_root(f, bound0, bound1, 0.0);
-    double const validated = r.root;
-    std::cout
-        << "high-precision value " << validated
-        << "; observed error " << f(validated)
-        << std::endl
-        ;
-
-    r = lmi_root(f, bound0, bound1, tol);
-    std::cout
-        << "lmi_root()    : root " << r.root
-        << " #eval " << r.n_eval
-        << std::endl
-        ;
-
-    r = decimal_root(f, bound0, bound1, bias_none, decimals);
-    std::cout
-        << "decimal_root(): root " << r.root
-        << " #eval " << r.n_eval
-        << std::endl
-        ;
-
-    r = toms748_root(f, bound0, bound1, bias_none, decimals);
-    std::cout
-        << "TOMS748       : root " << r.root
-        << " #eval " << r.n_eval
-        << "\n                             ^"
-        << "\n    doesn't round to 1.8954943,"
-        << "\n  but within        ±0.00000005 of true root:"
-        << "\n      TOMS748   " << r.root
-        << "\n    - validated " << validated
-        << "\n    = error     " << std::fixed << std::fabs(r.root - validated)
-        << "\n              < 0.00000005"
-        << std::endl
-        ;
-}
-
 int test_main(int, char*[])
 {
     test_fundamentals();
@@ -1361,7 +1245,6 @@ int test_main(int, char*[])
     test_various_functions();
     test_hodgepodge();
     test_former_rounding_problem();
-    test_toms748();
 
     return 0;
 }



reply via email to

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