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:
vvs
2026-09-21 10:53:00 +01:00
co-authored by Claude Opus 5
parent de90c7a089
commit 1b6c626f67
32 changed files with 950 additions and 186 deletions
+41 -26
View File
@@ -16,8 +16,8 @@ import pytest
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# the other end of the trade the paper states: better average, one constant
PROJ_LABEL = "pure.ratio.derived3.project"
# the constant-free variant (the proposed rule is the projection, variant a)
CREDIT_LABEL = "pure.ratio.derived3.credit"
@pytest.mark.skipif(not os.path.exists(os.path.join(ROOT, "sweep_full.json")),
@@ -40,16 +40,21 @@ def test_the_headline_claim_is_what_the_paper_says_it_is():
It caught exactly that. Until Chandrupatla's own method was added - a
reader asked why the owner of half the benchmark was missing - this test
asserted that a configuration of ours came first, and it passed only
because the method that beats us was absent from the field. The claim it
now guards is the corrected one: we are not first, Chandrupatla is, and
our margin behind it on the canonical set is under one percent."""
because the method that beats us was absent from the field. The claims it
now guards (variant a, Valeri 2026-09-21): by TOTAL Chandrupatla is first
on the canonical set and we are within one percent of it; problem by
problem we beat it with significance; on the wide-bracket set and over
both sets it beats us. And the constant-free variant may not borrow the
projection's canonical numbers."""
import json
import math
from report_sweep import PROPOSED, rank
from report_sweep import PROPOSED, head_to_head, rank
with open(os.path.join(ROOT, "sweep_full.json"), encoding="utf8") as fh:
rows = json.load(fh)
by = {r["label"]: r for r in rows}
assert "chandrupatla" in by, "the sweep predates the missing baselines"
assert PROPOSED == "pure.ratio.derived3.project"
aps = rank(rows, "APS")
assert aps[0]["label"] == "chandrupatla", aps[0]["label"]
@@ -57,33 +62,43 @@ def test_the_headline_claim_is_what_the_paper_says_it_is():
def both(lbl):
return by[lbl]["APS"]["total"] + by[lbl]["CHA"]["total"]
# What the paper may claim for the credit method, and nothing more.
# It is NOT within a percent of the best on Alefeld-Potra-Shi - that was
# true of the projection variant, which carries a constant. Buying
# constant-freedom and a near-bisection worst case costs average
# performance, and the test pins the direction of that trade so the
# abstract cannot quietly reclaim the projection variant's numbers.
def tot(lbl, s):
return by[lbl][s]["total"]
# canonical set: parity by total with the best, a tie with TOMS 748
assert tot(PROPOSED, "APS") > tot("chandrupatla", "APS")
assert tot(PROPOSED, "APS") < 1.01 * tot("chandrupatla", "APS")
assert tot(PROPOSED, "APS") < tot("toms748", "APS") < 1.01 * tot(PROPOSED, "APS")
# ... and an edge problem by problem, with significance
w, _t, l, _ = head_to_head(rows, PROPOSED, "chandrupatla", "APS")
p = min(1.0, 2.0 * sum(math.comb(w + l, i) for i in range(min(w, l) + 1))
/ 2.0 ** (w + l))
assert w > 2 * l - 1 and p < 1e-3, (w, l, p)
# wide brackets and both sets: Chandrupatla is stronger, and the paper says so
assert tot(PROPOSED, "CHA") > tot("chandrupatla", "CHA")
assert both(PROPOSED) > both("chandrupatla"), "behind Chandrupatla"
for weaker in ("toms748", "brent", "itp", "ridders", "bisection"):
assert both(PROPOSED) < both(weaker), weaker
# On the canonical set alone it is behind the classical methods; saying
# otherwise would be quoting the projection variant.
assert by[PROPOSED]["APS"]["total"] > by["toms748"]["APS"]["total"]
assert by[PROPOSED]["APS"]["total"] > by["brent"]["APS"]["total"]
# the constant-free variant may not borrow the projection's canonical numbers
assert tot(CREDIT_LABEL, "APS") > tot("toms748", "APS")
assert tot(CREDIT_LABEL, "APS") > tot("brent", "APS")
assert tot(CREDIT_LABEL, "CHA") < tot(PROPOSED, "CHA")
# The claim it does own: the worst single problem, over the problems it
# solves, is close to bisection's and far below the classical methods'.
# the claim the constant-free variant does own: the worst single problem,
# over the problems it solves, is close to bisection's and far below the
# classical methods'
def worst(lbl):
w = 0
wst = 0
for setname in ("APS", "CHA"):
for n, ok in by[lbl][setname]["per"].values():
if ok:
w = max(w, n)
return w
wst = max(wst, n)
return wst
assert worst(PROPOSED) < 100, worst(PROPOSED)
assert worst(PROPOSED) < worst("brent")
assert worst(PROPOSED) < worst("toms748")
assert worst(PROPOSED) < worst(PROJ_LABEL), (worst(PROPOSED),
worst(PROJ_LABEL))
assert worst(CREDIT_LABEL) < 100, worst(CREDIT_LABEL)
assert worst(CREDIT_LABEL) < worst("brent")
assert worst(CREDIT_LABEL) < worst("toms748")
assert worst(CREDIT_LABEL) < worst(PROPOSED), (worst(CREDIT_LABEL), worst(PROPOSED))