Files
sim-numerics/diag_flat_detectable.py
vvsandClaude Opus 5 862feaff86 Revision 1, step 1: one scoring criterion, the correct order, and the internal inconsistencies.
Point 1. The base step's order is Muller's 1.839, not 2: the derivative of the parabola through
the last three points errs by f'''/6 (x_n - x_{n-1})(x_n - x_{n-2}) = O(e_{n-1} e_{n-2}).
order_high_precision.py (3000 digits, to 1e-2900): 1.840 on cos x - x, e^x - 2, x^3 - x - 2,
sin x - 1/2; 2.000 only on x^2 - 2; two-point 1.618. The double-precision medians (2.000, 1.94)
are removed from the text.

Point 3. Every protocol number is re-scored under the criterion of section 9 - a sign change
within 1e-6 or f(x) == 0. rescore_uniform.py re-runs all 2779 distinct configurations of the 25
protocol sweeps on APS and CHA (the runs did not keep x) -> sweep_uniform.json, same row format;
it reproduces the APS/CHA lines of Table 10 exactly (built-in check). verify_article.py,
audit_similarity_places.py and the gap diagnostics read the re-scored data; the multiplier and
endowment measurements score by the same criterion. Table 7 (two criteria side by side) is gone;
7.3 now explains why the criterion is a sign change. Consequences stated in the text: the base
rule 2634 / 2357 against Chandrupatla 2595 / 1505 (1.5% behind on APS, no longer "level"); A'
2259 / 1074 (12.9% and 28.6% below Chandrupatla); the defect reading 2351 is second to the
shape reading 2337, not the record; the remembered analogy is level with no regime (2633 vs
2634) under this criterion; Table 9a's range is 19% to 425%.

Point 8. report_sweep.head_to_head counts every problem, failures charged (it counted only the
problems both methods solved, which is why Table 8 rows summed to 153 and 40). Family-level
comparisons added (A' vs Chandrupatla 8/1/6 of 15 and 7/0/2 of 9 families, not significant), and
an independence paragraph in section 9.

Point 11. sweep_itp.py: ITP (recommended constants and per-problem oracle) on all six corpora ->
Table 10; behind A' on every corpus, 0 bound violations.

Points 7, 9, 10 and the internals: the 2x bound is ours, not the rivals' promise; the law
predicts the group order only; "outside the proven bracket" explained (narrowest bracket of all
observed signs); 7.4's fun1 paragraph corrected (five costs under safe; the unguarded numbers
belong to fun1.4, fun1.5 and to fun3.1, fun5.1 separately); Table 1's last cell; the corpus-4
composition and odd multiplicities stated, also in the abstract.

build_tex.py: pdflatex output decoded with errors="replace" (a UTF-8 character cut by TeX's log
wrap crashed the build). Table 10 column widths rebalanced.

Checks: verify_article on the server 500 OK / 0 BAD (467 existing with the new values, 33 new);
regression x2 on the server 1232 passed, 0 failed; PDF 28 pages, 0 errors, 0 undefined, 0 overfull.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 07:01:36 +01:00

70 lines
2.7 KiB
Python

"""Is the flat regime DETECTABLE from evaluations already paid for?
Established by diag_model_order.py and its checks: two thirds of the wide-bracket gap sit
on the flat families (fun3-fun6), where Chandrupatla bisects 93-100% of his steps and our
step removes 0.41-0.81 halvings of the bracket per evaluation - less than bisection's 1.
On an approach |f| ~ K e^m the tangent step lands at e(1 - 1/m): it beats bisection's
halving only while 1 - 1/m < 1/2, i.e. m < 2. The 2 is bisection's 1/2 rewritten, not a
chosen number. m is what _local_order reads from the three latest evaluations.
Question measured here, BEFORE anything is built: does "m >= 2" separate the states of
the flat families from the states of the canonical set? _local_order is known to fire
falsely (derived3_m: m > 1 on 27.9% of APS steps, excursions to 34.8), so the separation
is the whole question. If APS states cross m >= 2 about as often as flat ones, the regime
is NOT detectable this way and no gate may be built on it.
python -u diag_flat_detectable.py
"""
from __future__ import annotations
from collections import defaultdict
from scipy.optimize._tstutils import _APS_TESTS_DICTS, _CHANDRUPATLA_TESTS_DICTS
from diag_model_order import ACC, MAXFEV, OURS, XTOL, solved
from simroot.pure import _local_order, pure_root
FLAT = ("fun3", "fun4", "fun5", "fun6")
def states(f, a, b, r):
st = {"trace": []}
x, _n, conv = pure_root(f, a, b, XTOL, MAXFEV, stats=st, **OURS)
if not (conv and solved(f, float(x))):
return []
out = []
for s in st["trace"]:
if s["xp2"] is None:
continue
out.append(_local_order(s["x"], s["fx"], s["xp"], s["fp"], s["xp2"], s["fp2"]))
return out
def main():
groups = defaultdict(list)
for d in _APS_TESTS_DICTS:
a, b = (float(v) for v in d["bracket"])
f = (lambda ff, aa: lambda t: ff(t, *aa))(d["f"], d.get("args", ()))
groups["APS (canonical)"] += states(f, a, b, float(d["root"]))
for d in _CHANDRUPATLA_TESTS_DICTS:
a, b = (float(v) for v in d["bracket"])
fam = str(d["ID"]).split(".")[0]
key = "CHA flat fun3-6" if fam in FLAT else "CHA other"
groups[key] += states(d["f"], a, b, float(d["root"]))
print(f"{'group':<18} {'states':>7} {'m > 1':>8} {'m >= 2':>8}")
shares = {}
for k in ("APS (canonical)", "CHA other", "CHA flat fun3-6"):
ms = groups[k]
n = max(len(ms), 1)
gt1 = 100.0 * sum(m > 1.0 for m in ms) / n
ge2 = 100.0 * sum(m >= 2.0 for m in ms) / n
shares[k] = (len(ms), gt1, ge2)
print(f"{k:<18} {len(ms):7d} {gt1:7.1f}% {ge2:7.1f}%")
return shares # for verify_article.py
if __name__ == "__main__":
main()