The new sections move into the canonical text, article/sim_numerics.md (Valeri's decision): section 7 'Where the similarity is read' with 7.1 per-place similarity, 7.2 the decision place, 7.3 the fun7 scoring artefact, 7.4 the gap decomposition; negative results 8-11 appended so items 1-7 keep their numbers; abstract paragraph; Future work rewritten (the refuted log transform removed); item 6 now says aps.13.00 is a scoring artefact, not a method failure. Translated into the .md's revised names: code 'ratio' = the tent max(0,1-|z|), code 'rational' = the ratio similarity 1/(1+|z|); the proposed method stays the .md's (tent, 3-point, projection).

Found on the way: negative item 'log change of variable' compared 3474 with 4516, the total of a DIFFERENT configuration; the honest pair is the same configuration in x, CHA 3643 -> 3474, APS 5822 -> 6940. Fixed in both texts. The gap-decomposition numbers were only traced to saved logs; they are now RECOMPUTED by verify_article.py from fresh runs of the diagnosis scripts (which return their values): 216 checks OK on Linux, 762 tests pass twice.

Open, for Valeri: the .md still says the projection's doubling is 'not a tuning constant', which simroot/pure.py (project_credit) refutes and which is why the .tex proposes credit; the .md's Tables 2-3 predate Chandrupatla's own method as a baseline (2785 APS, first place), so its 'parity' abstract is out of date; Brent 2890/4101 in the .md against 2889/4099 in the current sweep.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
vvs
2026-09-21 07:48:55 +01:00
co-authored by Claude Opus 5
parent f5d036c9d8
commit de1f8f726d
6 changed files with 200 additions and 9 deletions
+63
View File
@@ -203,6 +203,7 @@ def main():
verify_placement_modes()
verify_per_place()
verify_decision_place()
verify_gap_decomposition()
print()
if FAILS:
@@ -356,6 +357,68 @@ def verify_decision_place():
check(f"{mode} refusal rate %", round(100.0 * ref / nfev, 1), want)
def verify_gap_decomposition():
"""Section 7.4 of the .md (sec:widelimit in the .tex): the wide-bracket gap taken
apart on the same evaluations. Every number is RECOMPUTED by running the diagnosis
scripts, not transcribed from their saved printouts."""
import contextlib
import io
print("\nThe gap decomposition (fresh runs of the diagnosis scripts):")
import diag_flat_detectable
import diag_model_order
import diag_model_order_checks
with contextlib.redirect_stdout(io.StringIO()):
mo = diag_model_order.main()
ck = diag_model_order_checks.main()
fl = diag_flat_detectable.main()
per = mo["per_problem"]
check("problems where we lose", len(mo["lose"]), 33)
check("fun1.4 our bracket halvings/eval", round(per["fun1.4"][2], 2), 0.62)
check("fun1.4 IQI from our points", round(per["fun1.4"][3], 2), 10.37)
flat = [p for p in per if p.split(".")[0] in ("fun3", "fun4", "fun5", "fun6")]
check("flat: ours min", round(min(per[p][2] for p in flat), 2), 0.41)
check("flat: ours max", round(max(per[p][2] for p in flat), 2), 0.81)
check("flat: IQI min", round(min(per[p][3] for p in flat), 2), 0.01)
check("flat: IQI max", round(max(per[p][3] for p in flat), 2), 0.17)
check("non-degenerate states with one negative weight", mo["neg_ok"], 428)
check("bracketing states in total", mo["neg_all"], 433)
check("every exception is an underflowed zero weight",
all(any(w == 0.0 for w in ws) for _p, _f, ws in ck["exceptions"]), True)
fam = ck["fam"]
gap = {k: v[2] - v[3] for k, v in fam.items()}
check("total gap on the losing problems", sum(gap.values()), 262)
check("flat families' gap", sum(gap[k] for k in ("fun3", "fun4", "fun5", "fun6")), 178)
check("fun1 gap", gap["fun1"], 58)
for k, want in (("fun3", 93), ("fun4", 96), ("fun5", 100), ("fun6", 100)):
b, q = fam[k][0], fam[k][1]
check(f"Chandrupatla bisect share {k} %", round(100.0 * b / (b + q)), want)
for k, want in (("fun4", 293), ("fun5", 228), ("fun6", 228)):
check(f"Chandrupatla total {k}", fam[k][3], want)
check("m>=2 on canonical states %", round(fl["APS (canonical)"][2], 1), 0.2)
check("m>=2 on flat states %", round(fl["CHA flat fun3-6"][2], 1), 5.8)
# the band per family, from the Linux sweep
with open("sweep_decision.json", encoding="utf8") as fh:
rows = json.load(fh)
by = {(r["spec"][1], r["spec"][5], r["spec"][3]): r for r in rows}
base = by[("ratio", "none", "project")]["CHA"]["per"]
band = by[("ratio", "band", "project")]["CHA"]["per"]
def fam_total(per_, k):
return sum(n if ok else 200 for pid, (n, ok) in per_.items()
if pid.split(".")[0] == k)
for k, b0, b1 in (("fun4", 573, 296), ("fun5", 456, 239), ("fun6", 456, 235)):
check(f"band {k} no-gate", fam_total(base, k), b0)
check(f"band {k} with band", fam_total(band, k), b1)
for k, d in (("fun1", 164), ("fun2", 111), ("fun8", 170), ("fun9", 144)):
check(f"band cost on {k}", fam_total(band, k) - fam_total(base, k), d)
# negative item 11, corrected pairing: the same configuration in x and in log space
with open("sweep_full.json", encoding="utf8") as fh:
full = json.load(fh)
xcell = next(r for r in full if r["label"] == "pure.ratio_soft.derived.safe")
check("log item: x-space control APS", xcell["APS"]["total"], 5822)
check("log item: x-space control CHA", xcell["CHA"]["total"], 3643)
PLACEMENT_PER_SET = {
"sweep_direction.json": ("CHA", "pure+dissim+slope.ratio.derived3.safe", 2683),
"sweep_gate.json": ("CHA", "gate.ratio_soft.derived.safe", 2851),