"""Why Chandrupatla wins the probe — measured, and stated in similarity terms. ANALYSIS ONLY. The traced copy below mirrors `simroot.baselines.chandrupatla` so its decisions can be counted; it is NEVER used for a ranking number, and its fidelity is asserted against the original (identical evaluation count on all 45 problems). If that assert fails, the mirror has drifted and nothing here may be believed. The reading being tested: Chandrupatla = similarity(configuration, well-conditioned configuration) used as a GATE on a model step, with bisection as the refusal branch. ours = similarity(residual, 0) used as a SCALE for the step, with the safeguard bolted on afterwards. * the decision variable is t in (0,1): the probe is a FRACTION of the bracket, so the method is scale-free by construction (what the logarithmic attempt tried to buy); * the gate is written in two RATIOS, xi = (x1-x2)/(x3-x2) and phi = (f1-f2)/(f3-f2), both invariant under affine rescaling of x and of f — relations, not magnitudes; * for a LINEAR f, phi = xi exactly, and that point lies strictly inside the band 1 - sqrt(1-xi) < phi < sqrt(xi), so the band is a neighbourhood of the linear configuration: the model is trusted exactly where the data still look linear enough. Metric for "probe quality", parameter-free and comparable across methods: halvings per evaluation = log2(w0 / xtol) / nfev Bisection is 1.0 by definition; more is better. python -u explain_chandrupatla.py """ from __future__ import annotations import math from simroot.baselines import Counter, chandrupatla from simroot.pure import pure_root from sweep_full import ACC, MAXFEV, XTOL, load_problems def chandrupatla_traced(f, a, b, xtol, maxfev): """Mirror of the published routine plus counters. Returns (x, nfev, ok, trace).""" g = Counter(f, maxfev) trace = {"iqi": 0, "bisect": 0, "gate_rejected": 0, "no_third_point": 0} x1, x2 = b, a f1 = f2 = 0.0 try: f1, f2 = g(x1), g(x2) if f1 == 0.0: return x1, g.n, True, trace if f2 == 0.0: return x2, g.n, True, trace x3, f3 = x2, f2 t = 0.5 while True: x = x1 + t * (x2 - x1) fx = g(x) if (fx > 0.0) == (f1 > 0.0): x3, f3 = x1, f1 x1, f1 = x, fx else: x3, f3 = x2, f2 x2, f2 = x1, f1 x1, f1 = x, fx xm, fm = (x1, f1) if abs(f1) < abs(f2) else (x2, f2) if fm == 0.0: return xm, g.n, True, trace tol = 2.0 * 2.22e-16 * abs(xm) + xtol span = abs(x2 - x1) if span == 0.0: return xm, g.n, True, trace tl = tol / span if tl > 0.5: return xm, g.n, True, trace t = 0.5 took_iqi = False if x3 != x2 and f3 != f2: xi = (x1 - x2) / (x3 - x2) ph = (f1 - f2) / (f3 - f2) if 0.0 < xi < 1.0 and 1.0 - math.sqrt(1.0 - xi) < ph < math.sqrt(xi): d1, d2, d3 = f1 - f2, f1 - f3, f2 - f3 if d1 != 0.0 and d2 != 0.0 and d3 != 0.0: t = (f1 / d1) * (f3 / (-d3)) + \ ((x3 - x1) / (x2 - x1)) * (f1 / d2) * (f2 / d3) took_iqi = True else: trace["gate_rejected"] += 1 else: trace["no_third_point"] += 1 if not math.isfinite(t): t = 0.5 took_iqi = False if t < tl: t = tl elif t > 1.0 - tl: t = 1.0 - tl trace["iqi" if took_iqi else "bisect"] += 1 except Exception: return float("nan"), g.n, False, trace def main(prestep="none"): probs = [p for p in load_problems() if p[0] == "CHA"] print(f"ours: prestep={prestep!r}") print(f"CHA problems: {len(probs)} metric: halvings per evaluation " f"= log2(w0/xtol)/nfev (bisection = 1.0)\n") print(f"{'problem':<16} {'CH nfev':>8} {'CH h/ev':>8} {'gate ok%':>9} " f"{'ours nfev':>10} {'ours h/ev':>10} {'forced%':>8}") agg = {"ch_n": 0, "our_n": 0, "ch_h": [], "our_h": [], "gate": [], "forced": []} drift = 0 for _s, pid, f, a, b, root in probs: w0 = abs(b - a) decades = math.log2(w0 / XTOL) x_ref, n_ref, ok_ref = chandrupatla(f, a, b, XTOL, MAXFEV) x_t, n_t, ok_t, tr = chandrupatla_traced(f, a, b, XTOL, MAXFEV) if (n_ref, ok_ref) != (n_t, ok_t): drift += 1 steps = tr["iqi"] + tr["bisect"] gate_ok = 100.0 * tr["iqi"] / steps if steps else float("nan") stats = {} x_o, n_o, ok_o = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3", guard="credit", stats=stats, prestep=prestep) forced = 100.0 * stats.get("forced", 0) / max(n_o, 1) ch_h = decades / n_ref if n_ref else float("nan") our_h = decades / n_o if n_o else float("nan") agg["ch_n"] += n_ref if ok_ref else MAXFEV agg["our_n"] += n_o if ok_o else MAXFEV if ok_ref: agg["ch_h"].append(ch_h) agg["gate"].append(gate_ok) if ok_o: agg["our_h"].append(our_h) agg["forced"].append(forced) print(f"{pid:<16} {n_ref:8d} {ch_h:8.3f} {gate_ok:8.1f}% " f"{n_o:10d} {our_h:10.3f} {forced:7.1f}%") mean = lambda v: sum(v) / len(v) if v else float("nan") # noqa: E731 print(f"\nmirror fidelity: {'OK' if drift == 0 else f'DRIFTED on {drift} problems'}") print(f"totals (failures charged {MAXFEV}): Chandrupatla {agg['ch_n']}, ours {agg['our_n']}") print(f"halvings per evaluation: Chandrupatla {mean(agg['ch_h']):.3f}, " f"ours {mean(agg['our_h']):.3f}") print(f"Chandrupatla accepted the model on {mean(agg['gate']):.1f}% of steps " f"(the rest it REFUSED and halved)") print(f"our safeguard had to repair {mean(agg['forced']):.1f}% of evaluations") if __name__ == "__main__": import sys main("slope" if "--slope" in sys.argv else "progress" if "--gate" in sys.argv else "none")