Files
sim-numerics/diag_contraction_similarity.py
T
vvsandClaude Opus 5 0ec7142baf Two audits, both on existing data or traces, method untouched. (1) Where S is evaluated: only in the step length (and simpair, and two refuted modes); the slope gate, the triple by shape, the far end and 'defect' decide by comparing - which is a similarity judgment of the ordinal kind ('which is more similar'), where every decreasing S gives the same decision. Their gains depend strongly on the S in the STEP: triple by shape -493 with the tent, up to +250 with others; defect -283 with the tent, up to +215. The records are the pairing of the tent step with those judgments.
(2) Valeri: 'similarity should solve the flat-family problem'. The similarity of two successive contraction ratios, min/max(rho_n, rho_n-1), was pre-declared as the detector; it FAILS and is inverted - AUC 0.28-0.42 flat against the rest, and 'the contraction did not speed up' fires more on APS (37.6%) than on the flat families (28.2%). The rho sequence shows why: on x^m the method runs a period-4 cycle - two Newton undershoots at exactly (1-1/m)^m (0.328 for m=5, 0.346 for m=9), one crossing, one nearly empty step (rho ~ 1) - so successive ratios are dissimilar, not constant. The safeguard is not the cause: the steps are as proposed. Candidate detectors suggested by the cycle are new hypotheses, not built.

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

107 lines
4.5 KiB
Python

"""Is the flat regime DETECTABLE by the similarity of two successive contraction ratios?
Valeri, 2026-09-21: "similarity should solve exactly this problem". The similarity of a
triple to a linear configuration, |phi - xi|, cannot: fun1 on a wide bracket and the
pure powers x^9, x^19 look equally non-linear, yet a quadratic model works on the first
and fails on the second. The flat regime shows in the HISTORY instead: with
rho_n = |f_n / f_{n-1}|, a superlinear run has rho falling from step to step (successive
ratios dissimilar), a linearly converging one has rho nearly constant (similar). So the
candidate similarity for this place is
S = min(rho_n, rho_{n-1}) / max(rho_n, rho_{n-1}) (the SIM ratio form)
Declared before the run, with no threshold anywhere:
* AUC of S, flat states (fun3-fun6) against each other group: the probability that a
random flat state has the higher S. 0.5 = no separation, 1.0 = perfect.
* the threshold-free rule "the contraction did not speed up", rho_n >= rho_{n-1}: how
often it fires in each group. The bar to beat is the three-point order estimate,
m >= 2: 0.2% of canonical states, 5.8% of flat ones (diag_flat_detectable.py).
Nothing in the method changes; states come from the behaviour-neutral trace hook.
python -u diag_contraction_similarity.py
"""
from __future__ import annotations
from scipy.optimize._tstutils import _APS_TESTS_DICTS, _CHANDRUPATLA_TESTS_DICTS
from simroot.pure import pure_root
XTOL, MAXFEV, ACC = 1e-12, 200, 1e-6
CONFIGS = {
"proposed (projection)": dict(similarity="ratio", scale="derived3", guard="project"),
"reading (3), as for m>=2": dict(similarity="ratio", scale="derived3", guard="safe",
prestep="slope", direction="dissimilar"),
}
FLAT = ("fun3", "fun4", "fun5", "fun6")
def states(f, a, b, r, cfg):
"""(S, contraction_did_not_speed_up) for every traced state with three nonzero f."""
st = {"trace": []}
x, _n, conv = pure_root(f, a, b, XTOL, MAXFEV, stats=st, **cfg)
if not (conv and abs(float(x) - r) <= ACC):
return []
out = []
for s in st["trace"]:
if s["xp2"] is None or 0.0 in (s["fx"], s["fp"], s["fp2"]):
continue
rho_n = abs(s["fx"] / s["fp"])
rho_p = abs(s["fp"] / s["fp2"])
hi, lo = max(rho_n, rho_p), min(rho_n, rho_p)
if hi == 0.0 or hi != hi:
continue
out.append((lo / hi, rho_n >= rho_p))
return out
def auc(pos, neg):
"""P(random pos > random neg) + 0.5 P(tie), by ranks (Mann-Whitney)."""
if not pos or not neg:
return float("nan")
allv = sorted([(v, 1) for v in pos] + [(v, 0) for v in neg])
rank_sum, i = 0.0, 0
while i < len(allv):
j = i
while j < len(allv) and allv[j][0] == allv[i][0]:
j += 1
mean_rank = (i + 1 + j) / 2.0
rank_sum += mean_rank * sum(1 for k in range(i, j) if allv[k][1] == 1)
i = j
n1, n0 = len(pos), len(neg)
return (rank_sum - n1 * (n1 + 1) / 2.0) / (n1 * n0)
def main():
out = {}
for cname, cfg in CONFIGS.items():
groups = {"APS": [], "CHA fun1": [], "CHA flat fun3-6": [], "CHA other": []}
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"] += states(f, a, b, float(d["root"]), cfg)
for d in _CHANDRUPATLA_TESTS_DICTS:
a, b = (float(v) for v in d["bracket"])
fam = str(d["ID"]).split(".")[0]
g = ("CHA flat fun3-6" if fam in FLAT else "CHA fun1" if fam == "fun1"
else "CHA other")
groups[g] += states(d["f"], a, b, float(d["root"]), cfg)
print(f"\n== {cname}")
print(f" {'group':<18} {'states':>7} {'rho_n >= rho_(n-1)':>20}")
for g, v in groups.items():
n = max(len(v), 1)
print(f" {g:<18} {len(v):7d} {100.0 * sum(x[1] for x in v) / n:19.1f}%")
flat = [x[0] for x in groups["CHA flat fun3-6"]]
print(" AUC of S, flat states against:")
res = {}
for g in ("APS", "CHA fun1", "CHA other"):
res[g] = auc(flat, [x[0] for x in groups[g]])
print(f" {g:<14} {res[g]:.3f}")
out[cname] = {"groups": {g: (len(v), sum(x[1] for x in v)) for g, v in groups.items()},
"auc": res}
print("\nbar to beat (three-point order estimate, m >= 2): 0.2% canonical, 5.8% flat")
return out
if __name__ == "__main__":
main()