"""Why the contraction-ratio similarity came out inverted: the rho sequence itself. diag_contraction_similarity.py falsified "successive contraction ratios are similar on the flat families": they are LESS similar there than on the canonical set. The picture behind the hypothesis - rho constant at about (1 - 1/m)^m - holds for pure Newton steps on x^m. The explanation to check is that our safeguarded run is not pure: the projection interleaves forced moves, so rho alternates. Printed per step for one flat problem and one canonical problem: rho_n, and whether the step was the similarity step as proposed or was changed by the safeguard (x_new != x + raw). python -u diag_contraction_sequence.py """ from __future__ import annotations from scipy.optimize._tstutils import _APS_TESTS_DICTS, _CHANDRUPATLA_TESTS_DICTS from simroot.pure import pure_root CFG = dict(similarity="ratio", scale="derived3", guard="project") def show(name, f, a, b): evals = [] def g(t): v = f(t) evals.append((t, v)) return v st = {"trace": []} pure_root(g, a, b, 1e-12, 200, stats=st, **CFG) # map each traced state to the evaluation that followed it order = [e[0] for e in evals] print(f"\n== {name}: {len(evals)} evaluations") print(f" {'k':>3} {'rho_n=|f_n/f_(n-1)|':>22} {'step as proposed?':>18}") for k, s in enumerate(st["trace"][:40]): proposed = s["x"] + s["raw"] try: i = order.index(s["x"]) except ValueError: continue if i + 1 >= len(evals): break x_next, f_next = evals[i + 1] rho = abs(f_next / s["fx"]) if s["fx"] != 0.0 else float("nan") kept = "yes" if x_next == proposed else "CHANGED" print(f" {k:3d} {rho:22.3e} {kept:>18}") def main(): cha = {str(d["ID"]): d for d in _CHANDRUPATLA_TESTS_DICTS} d = cha["fun5.1"] show("fun5.1 = x^9 (flat)", d["f"], *(float(v) for v in d["bracket"])) d = cha["fun4.3"] show("fun4.3 = 6(x-2)^5 on a wide bracket (flat)", d["f"], *(float(v) for v in d["bracket"])) d = _APS_TESTS_DICTS[10] f = (lambda ff, aa: lambda t: ff(t, *aa))(d["f"], d.get("args", ())) show(f"{d['ID']} (canonical)", f, *(float(v) for v in d["bracket"])) if __name__ == "__main__": main()