"""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(): 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())) if __name__ == "__main__": point3() point4() print("revision2 diag done")