2: 'pre-registered' -> 'recorded in advance'; Appendix D states the order is attested only by the author's git history. 3: Dekker, Illinois and false position exhaust the budget on aps.13.00 under either criterion (stalled where |f|<1e-62, no sign change within 1e-6) - hence unchanged totals. 4: exact-zero stops in Table 11 (CHA: Brent 15/20, Chandrupatla 4/20, A' 2/20; corpus 1: none, transformation still 3.4x cheaper). 5: Table 12, the multiplicity estimated during the run (A' ahead; the analogy order inside Chandrupatla closes 31-59% of the gap on multiple roots and pays on simple ones; Lagouanelle blind on side-alternating triples); 6.6, conclusion, future work. 6: Algorithms 1-2 - lo/hi, return on a stall, L_x/L_f and the empty memory, the step pattern as a formula, O(n^2). 7: Table 3's two bracket-scaled rows, dashes in Table 5, the abstract's last sentence (250 words). verify_revision2: 17 checks. Server: verify 544 OK / 0 BAD, regression x2 1238 passed, PDF 32 pages, 0 errors, 0 overfull. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
91 lines
3.6 KiB
Python
91 lines
3.6 KiB
Python
"""Revision 2, points 3 and 4 - facts only, no new method.
|
|
|
|
Point 3: Dekker, Illinois and false position show the same APS totals under both criteria. Which
|
|
problems do they fail, and why do they fail aps.13.00 under 'sign change or f = 0' as well?
|
|
Point 4: how do the runs on g = sign(f)|f|^(1/m*) (Table 11) end - by the bracket width, or on an
|
|
exact zero of g (which every method, A' included, accepts)? Counted per method on the
|
|
multiple/fractional problems, next to A' on the same problems.
|
|
|
|
python -u diag_revision2.py
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import math
|
|
import random
|
|
|
|
import scipy.optimize._tstutils as T
|
|
|
|
from corpus_roots_jl import solved
|
|
from rescore_uniform import load_uniform
|
|
from simroot.baselines import brent_scipy, chandrupatla_lib
|
|
from simroot.pure import pure_root
|
|
from sweep_controls import k1_problems, m_star, nonsimple
|
|
from sweep_full import MAXFEV, XTOL, make_method
|
|
|
|
APRIME = ("pure", "ratio", "derived3", "project", "x", "contra+flatanalogmempt+exp+half+close+sub",
|
|
"recent", "distance", "none", "pattern")
|
|
|
|
|
|
def point3():
|
|
U = {r["label"]: r for r in load_uniform("sweep_full.json")}
|
|
O = {r["label"]: r for r in json.load(open("sweep_full.json", encoding="utf8"))}
|
|
probs = {pid: (f, a, b) for s, pid, f, a, b, _r in __import__("sweep_full").load_problems()}
|
|
for lb in ("dekker", "illinois", "regula_falsi"):
|
|
fails_u = [p for p, (n, ok) in U[lb]["APS"]["per"].items() if not ok]
|
|
fails_o = [p for p, (n, ok) in O[lb]["APS"]["per"].items() if not ok]
|
|
print(f"{lb}: APS failures uniform {len(fails_u)}, harness {len(fails_o)}, "
|
|
f"same set {sorted(fails_u) == sorted(fails_o)}; uniform total {U[lb]['APS']['total']}, "
|
|
f"harness {O[lb]['APS']['total']}")
|
|
f, a, b = probs["aps.13.00"]
|
|
x, n, conv = make_method(("base", lb))(f, a, b, XTOL, MAXFEV)
|
|
print(f" aps.13.00: returned x={float(x):.3g}, nfev={n}, converged={conv}, "
|
|
f"f(x)={f(float(x))!r}, sign-change criterion {solved(f, float(x))}")
|
|
|
|
|
|
def ends_on_zero(method, f, g, a, b):
|
|
"""(nfev, stopped on an exact zero of the function it saw, bracket-width stop)."""
|
|
seen = []
|
|
|
|
def w(x):
|
|
v = g(x)
|
|
seen.append(v)
|
|
return v
|
|
T._f6_cache.clear()
|
|
random.seed(20260921)
|
|
x, n, conv = method(w, a, b, XTOL, MAXFEV)
|
|
return int(n), bool(seen and seen[-1] == 0.0), bool(conv)
|
|
|
|
|
|
def point4():
|
|
"""Returns {corpus: {method: [problems, exact-zero stops, evaluations]}} and prints it."""
|
|
out = {}
|
|
for s in ("CHA", "NEW", "D"):
|
|
tally = {"chandrupatla_g": [0, 0, 0], "brent_g": [0, 0, 0], "Aprime": [0, 0, 0]}
|
|
for pid, f, a, b, r in k1_problems(s):
|
|
m = m_star(f, r)
|
|
if not nonsimple(m):
|
|
continue
|
|
inv = 1.0 / m
|
|
|
|
def g(x, _f=f, _i=inv):
|
|
v = _f(x)
|
|
return 0.0 if v == 0 else math.copysign(abs(v) ** _i, v)
|
|
for name, meth, fun in (("chandrupatla_g", chandrupatla_lib, g), ("brent_g", brent_scipy, g),
|
|
("Aprime", make_method(APRIME), f)):
|
|
n, zero, conv = ends_on_zero(meth, f, fun, a, b)
|
|
t = tally[name]
|
|
t[0] += 1
|
|
t[1] += zero
|
|
t[2] += n
|
|
print(f"{s}: problems {tally['Aprime'][0]}; runs ending on an exact zero / total evaluations: " +
|
|
"; ".join(f"{k} {v[1]}/{v[2]}" for k, v in tally.items()))
|
|
out[s] = tally
|
|
return out
|
|
|
|
|
|
if __name__ == "__main__":
|
|
point3()
|
|
point4()
|
|
print("revision2 diag done")
|