Files
sim-numerics/diag_rescore_cha.py
T
vvsandClaude Opus 5 1b6c626f67 Valeri's decisions (1) competitors from the library, (2) variant a. (1) Chandrupatla is scipy.optimize.elementwise.find_root, Brent is brentq, no more per-problem best_of. Our Chandrupatla stopped on a bracket twice as wide as every other method (the factor the protocol corrects for ITP); fixed (+0.5*xtol) in baselines.py and in the two copies found by grep (stage16_blend, stage19_modern) and the traced mirror, and pinned: ours == library on every problem. Regenerating sweep_full.json changed exactly three rows - chandrupatla APS 2785->2787, CHA 2423->2441, brent CHA 4099->4115 - and nothing else (diff_sweeps.py: 0 unexpected).
(2) The proposed method is again the scheduled projection (2806/3220/6026), its budget multiplier DECLARED as the one free constant: the canonical total is the same for every multiplier 1.25-4, the wide-bracket one is not. The earned projection is the constant-free variant (3568/3020/6588). What the old tables hid: problem by problem the proposed rule beats Chandrupatla on the canonical set 87/24/42, exact sign test p = 9e-5, while trailing him by 0.7% in total; on the wide-bracket set he is genuinely stronger (26 to 9, p = 0.006). Gap decomposition recomputed with the library: 244 (was 262), 160 of it on the flat families (two thirds), fun1 58 (a quarter, not a third as the abstract said).

Also corrected on the way: the 'subsumed by Chandrupatla' pin claimed he is better on the worst single problem - true only with the looser tolerance (84 against the credit rule's 83 once fixed); §8.3 still called zero slack degenerate, which Table 1a refutes; §5.2's Brent figure is our pure-Python implementation and now says so. verify_article.py 286/286, 802 tests pass twice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 10:53:00 +01:00

85 lines
3.9 KiB
Python

"""Re-score the wide-bracket set with a criterion that accepts an ACTUAL root.
Measured (diag_fun7_root.py): on all five fun7 problems every method returns a point where
f(x) = 0 exactly, and f is identically zero out to about +-0.0316 around the declared root
0. The harness criterion |x - declared_root| <= 1e-6 therefore scores a genuine root as a
failure, and each such problem charges MAXFEV = 200 to EVERY method: 1000 evaluations of
every CHA total is this artefact.
Here both criteria are applied to the same runs:
strict : |x - declared_root| <= ACC (the harness rule, as published)
honest : strict OR f(x) == 0 (a root is a root)
python -u diag_rescore_cha.py
"""
from __future__ import annotations
import math
from simroot.baselines import BRENT_BASELINE, CHANDRUPATLA_BASELINE
from simroot.baselines import (best_of, bisection, brent, brent_scipy, chandrupatla,
chandrupatla_scipy, itp, toms748)
from simroot.pure import pure_root
from sweep_full import ACC, MAXFEV, XTOL, load_problems
METHODS = {
"ours (shape)": lambda f, a, b: pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio",
scale="derived3", guard="safe",
prestep="slope", points="shape"),
"ours (dissimilar)": lambda f, a, b: pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio",
scale="derived3", guard="safe",
prestep="slope", direction="dissimilar"),
"ours (published proj)": lambda f, a, b: pure_root(f, a, b, XTOL, MAXFEV,
similarity="ratio", scale="derived3",
guard="project"),
"chandrupatla": lambda f, a, b: CHANDRUPATLA_BASELINE(f, a, b, XTOL,
MAXFEV),
"toms748": lambda f, a, b: toms748(f, a, b, XTOL, MAXFEV),
"brent": lambda f, a, b: BRENT_BASELINE(f, a, b, XTOL, MAXFEV),
"itp": lambda f, a, b: itp(f, a, b, XTOL, MAXFEV),
"bisection": lambda f, a, b: bisection(f, a, b, XTOL, MAXFEV),
}
def main():
probs = [p for p in load_problems() if p[0] == "CHA"]
print(f"{'method':<22} {'strict: solved/total':>22} {'honest: solved/total':>22} "
f"{'fun7 strict':>12} {'fun7 honest':>12}")
out = []
for name, run in METHODS.items():
s_solved = s_total = h_solved = h_total = 0
f7s = f7h = 0
for _s, pid, f, a, b, root in probs:
try:
x, n, conv = run(f, a, b)
except Exception:
x, n, conv = float("nan"), MAXFEV, False
x = float(x)
n = int(n)
fin = conv and math.isfinite(x)
strict = bool(fin and abs(x - root) <= ACC)
honest = bool(strict or (fin and f(x) == 0.0))
s_total += n if strict else MAXFEV
h_total += n if honest else MAXFEV
s_solved += int(strict)
h_solved += int(honest)
if pid.startswith("fun7"):
f7s += int(strict)
f7h += int(honest)
out.append((h_total, h_solved, name, s_total, s_solved, f7s, f7h))
print(f"{name:<22} {s_solved:8d}/45 {s_total:8d} {h_solved:8d}/45 {h_total:8d} "
f"{f7s:8d}/5 {f7h:8d}/5")
print("\nranking under the HONEST criterion (fewest unsolved, then evaluations):")
for h_total, h_solved, name, *_ in sorted(out, key=lambda t: (45 - t[1], t[0])):
print(f" {name:<22} {h_solved}/45 {h_total}")
print("\nranking under the STRICT criterion, for comparison:")
for h_total, h_solved, name, s_total, s_solved, *_ in sorted(
out, key=lambda t: (45 - t[4], t[3])):
print(f" {name:<22} {s_solved}/45 {s_total}")
if __name__ == "__main__":
main()