112 lines
4.7 KiB
Python
112 lines
4.7 KiB
Python
"""The objection that the comparison stopped at 1973, and what it settled.
|
|
|
|
Two things came out of running it, and they scope the claim exactly:
|
|
|
|
the credit projection is the best repair known for the false-position
|
|
family - better than 1971, 1972, 1973, 1995 and 2011 on evaluations,
|
|
solved count and worst case at once, and the only one that reaches the
|
|
193-of-199 ceiling;
|
|
|
|
and it is NOT better than a purpose-built acceptance test: swapped into
|
|
Chandrupatla's own interpolation it costs 7627 where his test costs 5209.
|
|
|
|
So the safeguard is a good DEFAULT for a rule that has none, not a
|
|
replacement for one that has a good one. Both halves are pinned.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
import os
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from simroot.baselines import chandrupatla
|
|
from stage18_bulletproof import falsi_driver, load_roots
|
|
from stage19_modern import chandrupatla_guard, falsi_modern, score
|
|
|
|
PROBS = load_roots()
|
|
XTOL, MAXFEV = 1e-12, 200
|
|
|
|
|
|
def falsi(repair):
|
|
return score(lambda f, a, b, xt, mx: falsi_driver(f, a, b, xt, mx, repair),
|
|
PROBS)
|
|
|
|
|
|
def modern(variant):
|
|
return score(lambda f, a, b, xt, mx: falsi_modern(f, a, b, xt, mx, variant),
|
|
PROBS)
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
# the half that holds
|
|
# --------------------------------------------------------------------------
|
|
@pytest.mark.parametrize("name,getter", [
|
|
("illinois-1971", lambda: falsi("illinois")),
|
|
("pegasus-1972", lambda: falsi("pegasus")),
|
|
("anderson-1973", lambda: falsi("anderson")),
|
|
("ford-1995", lambda: modern("ford")),
|
|
("galdino-2011", lambda: modern("galdino")),
|
|
])
|
|
def test_credit_beats_every_published_repair_on_all_three_axes(name, getter):
|
|
c_t, c_s, c_w = falsi("credit")
|
|
t, s, w = getter()
|
|
assert c_t < t, (name, c_t, t)
|
|
assert c_s > s, (name, c_s, s)
|
|
assert c_w < w, (name, c_w, w)
|
|
|
|
|
|
def test_no_published_repair_reaches_the_ceiling():
|
|
"""193 of 199 is what bisection, Chandrupatla and TOMS 748 reach. Fifty
|
|
years of repairs of the false-position family stop at 176."""
|
|
assert falsi("credit")[1] == 193
|
|
for g in (lambda: falsi("illinois"), lambda: falsi("pegasus"),
|
|
lambda: falsi("anderson"), lambda: modern("ford"),
|
|
lambda: modern("galdino")):
|
|
assert g()[1] <= 176
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
# the half that does not - pinned so the claim is never overstated
|
|
# --------------------------------------------------------------------------
|
|
def test_the_pluggable_chandrupatla_reproduces_the_published_one():
|
|
"""Without this the swap below compares against a different algorithm."""
|
|
a = score(lambda f, x, y, xt, mx: chandrupatla_guard(f, x, y, xt, mx,
|
|
"own"), PROBS)
|
|
b = score(lambda f, x, y, xt, mx: chandrupatla(f, x, y, xt, mx), PROBS)
|
|
assert a[:2] == b[:2], (a, b)
|
|
|
|
|
|
def test_credit_rescues_chandrupatlas_interpolation_but_loses_to_his_test():
|
|
"""The sharp test. Same interpolation, same bookkeeping, only the guard
|
|
differs. Credit turns an unguarded rule that solves 165 into one that
|
|
solves 193 - and Chandrupatla's own acceptance test does the same job for
|
|
a third fewer evaluations."""
|
|
own = score(lambda f, a, b, xt, mx: chandrupatla_guard(f, a, b, xt, mx,
|
|
"own"), PROBS)
|
|
cred = score(lambda f, a, b, xt, mx: chandrupatla_guard(f, a, b, xt, mx,
|
|
"credit"), PROBS)
|
|
none = score(lambda f, a, b, xt, mx: chandrupatla_guard(f, a, b, xt, mx,
|
|
"none"), PROBS)
|
|
assert cred[1] > none[1] and cred[0] < none[0] # it rescues
|
|
assert own[0] < cred[0] # and is beaten
|
|
assert own[1] == cred[1] == 193
|
|
|
|
|
|
def test_the_scope_sentence_the_paper_may_use():
|
|
"""A default safeguard for a rule that has none - not a replacement for a
|
|
purpose-built one. Both directions asserted together so neither can be
|
|
quoted alone."""
|
|
c_t, c_s, _cw = falsi("credit")
|
|
best_published = min(falsi(r)[0] for r in ("illinois", "pegasus",
|
|
"anderson"))
|
|
best_published = min(best_published, modern("ford")[0],
|
|
modern("galdino")[0])
|
|
assert c_t < best_published # best repair known
|
|
own = score(lambda f, a, b, xt, mx: chandrupatla_guard(f, a, b, xt, mx,
|
|
"own"), PROBS)
|
|
assert own[0] < c_t # and not the best guard
|