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>
This commit is contained in:
+38
-1
@@ -348,7 +348,13 @@ def chandrupatla(f, a, b, xtol, maxfev):
|
||||
xm, fm = (x1, f1) if abs(f1) < abs(f2) else (x2, f2)
|
||||
if fm == 0.0:
|
||||
return xm, g.n, True
|
||||
tol = 2.0 * 2.22e-16 * abs(xm) + xtol
|
||||
# tl > 1/2 stops once span < 2*tol, so the absolute term must be xtol/2 for
|
||||
# this method to stop on the same bracket width as every other one (<= xtol).
|
||||
# Until 2026-09-21 it was xtol, a bracket twice as wide - the factor the
|
||||
# protocol corrects for ITP and had not corrected here. With xtol/2 this
|
||||
# code and SciPy's elementwise.find_root agree on all 199 problems exactly
|
||||
# (audit_chandrupatla_library.py).
|
||||
tol = 2.0 * 2.22e-16 * abs(xm) + 0.5 * xtol
|
||||
span = abs(x2 - x1)
|
||||
if span == 0.0:
|
||||
return xm, g.n, True
|
||||
@@ -455,6 +461,37 @@ def chandrupatla_scipy(f, a, b, xtol, maxfev):
|
||||
return 0.5 * (a + b), g.n, False
|
||||
|
||||
|
||||
def chandrupatla_lib(f, a, b, xtol, maxfev):
|
||||
"""Chandrupatla from the library's PUBLIC interface, the benchmark's baseline since
|
||||
2026-09-21 (Valeri: remove the risk of our own implementation). Same stopping rule
|
||||
as every other method - bracket narrower than xtol, relative term at machine
|
||||
precision, no stopping on |f| - and evaluations counted by the same Counter."""
|
||||
import numpy as np
|
||||
from scipy.optimize import elementwise
|
||||
g = Counter(f, maxfev)
|
||||
|
||||
def vec(x):
|
||||
return np.asarray([g(float(xi)) for xi in np.atleast_1d(x)]).reshape(np.shape(x))
|
||||
|
||||
try:
|
||||
res = elementwise.find_root(vec, (a, b), maxiter=maxfev,
|
||||
tolerances=dict(xatol=xtol, xrtol=8.9e-16,
|
||||
fatol=0.0, frtol=0.0))
|
||||
return (float(np.asarray(res.x).ravel()[0]), g.n,
|
||||
bool(np.all(np.asarray(res.success))))
|
||||
except _Budget:
|
||||
return 0.5 * (a + b), g.n, False
|
||||
except Exception:
|
||||
return 0.5 * (a + b), g.n, False
|
||||
|
||||
|
||||
# The competitors as benchmarked: the library alone wherever the library ships the
|
||||
# method. Until 2026-09-21 they were best_of(ours, library) problem by problem, which
|
||||
# let a tolerance slip in OUR Chandrupatla leak into the reported numbers.
|
||||
CHANDRUPATLA_BASELINE = chandrupatla_lib
|
||||
BRENT_BASELINE = brent_scipy
|
||||
|
||||
|
||||
def best_of(*methods):
|
||||
"""Give the competitor the cheaper of its implementations on every
|
||||
problem. The same concession the paper already makes to ITP by reporting
|
||||
|
||||
Reference in New Issue
Block a user