"""Phase diagram of frozen-band recurrence: dynamics dial vs fidelity. x: spectral radius rho(A) of the trained state map (log scale) y: substrate fidelity = easy-bucket pass@1 at k=4 (free-running generation) label: hard-bucket pass@1 at k=4 (the gain every regime buys) All points: same frozen E2B band, same data, same 250-item eval, e400. """ from pathlib import Path import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt OUT = Path(__file__).resolve().parent.parent / "results-loop" # name rho easy hard color # name rho(plot x) easy hard color dy PTS = [ ("untrained 14%", 0.22, 0.885, 0.143, "#8a8f98", -26), ("merge ★ 46%", 0.26, 0.885, 0.464, "#2b6cb0", -40), ("per-depth 36%", 0.30, 0.893, 0.357, "#805ad5", 26), ("tied-α 43%", 0.35, 0.910, 0.429, "#0987a0", -32), ("rand-k 36%", 0.41, 0.918, 0.357, "#3182ce", 22), ("noise-s₀ 43%*", 0.48, 0.904, 0.429, "#b83280", -34), ("4×MLP 54%†", 0.56, 0.902, 0.536, "#5f6b7a", 20), ("Parcae rec 41%*\n(ρ<1 enforced, learned B)", 0.292, 0.722, 0.411, "#2f855a", -50), ("unconstrained rec 39%\n(learned A,B)", 4.5, 0.697, 0.393, "#c53030", 16), ] # x jittered around true rho=0.3 for the three anchored arms (visibility) # untrained merge x offset for visibility (true rho = 0.30) fig, ax = plt.subplots(figsize=(7.6, 5.2)) ax.set_xscale("log") ax.axvspan(1.0, 20, color="#fff5f5", zorder=0) ax.axvline(1.0, color="#c53030", lw=1.2, ls="--") ax.text(1.06, 0.99, "ρ = 1 stability boundary", rotation=90, fontsize=8, color="#c53030", va="top") ax.text(3.1, 0.615, "norm projection converts\nexplosion → stationary churn\n" "(training survives, substrate pays)", fontsize=8, color="#c53030", ha="center") for name, rho, easy, hard, c, dy in PTS: ax.scatter(rho, easy, s=90 + 900 * hard, color=c, alpha=0.85, zorder=3, edgecolor="white", linewidth=1.5) lbl = name dx = 0 ax.annotate(lbl, (rho, easy), textcoords="offset points", xytext=(dx, dy), ha="center", fontsize=7.5, color=c) ax.annotate("", xy=(0.285, 0.740), xytext=(0.29, 0.868), arrowprops=dict(arrowstyle="->", color="#2f855a", lw=1.3)) ax.text(0.55, 0.79, "learned free B:\nfixed point leaves the\n" "substrate manifold\n(curriculum, s₀, ρ, capacity\nall causally cleared)", fontsize=8, color="#2f855a", ha="left") ax.text(0.34, 0.972, "the anchored family — B tied to the anchor (labels: hard-bucket at k=4; * seed mean, † single seed)", fontsize=7.8, color="#2b6cb0", ha="center", style="italic") ax.set_xlim(0.17, 12) ax.set_ylim(0.58, 1.0) ax.set_xlabel("ρ(A) — spectral radius of the trained state map (dynamics dial)") ax.set_ylabel("substrate fidelity — easy-bucket pass@1 at k=4") ax.set_title("Frozen-band recurrence phase diagram: stability ≠ fidelity\n" "(marker size ∝ hard-bucket gain at k=4; every regime buys " "36–54% within seed noise; only anchored B keeps the substrate)", fontsize=10.5) ax.grid(True, color="#ececec", lw=0.7, which="both") ax.set_axisbelow(True) for s in ("top", "right"): ax.spines[s].set_visible(False) fig.text(0.13, -0.06, "Same frozen gemma-4-E2B band (L14–30), same MBPP data, same " "250-item eval, e400 checkpoints. ρ from checkpoints (power " "iteration / diag max). Dynamics (x) and fixed-point location " "(y) are independent dials: contraction guarantees convergence " "and certified tail gradients, but only anchored content — fixed " "B=(1−α)I, zero-init correction, difficulty→depth curriculum — " "keeps the fixed point substrate-preserving.", fontsize=7.5, color="#555", wrap=True) fig.tight_layout() fig.savefig(OUT / "fig_phase.png", dpi=140, facecolor="white", bbox_inches="tight") print("wrote", OUT / "fig_phase.png")