Restructure: descriptive tier and experiment names, paper/manuscript
- paper/pnas -> paper/manuscript (venue-neutral)
- configs/layer1 -> configs/inheritance, src/knowledge -> src/inheritance
(imported as `inheritance`), make layer1 -> make inheritance; layer2 alias dropped
- inheritance and trained-network bundles named after the manuscript figure
they feed (fig2_grounding_sweep, figS3_rebaselining, ...), or descriptively
where they feed none; configs keep their `experiment:` value so parquet
hashes are unchanged, only output.dir moves
- figure scripts, SI figure sources, notebooks, REPRODUCING.md, README and the
SI Methods/tables updated; make clean no longer deletes tracked manifests;
reproduce.sh hashes the s{seed}/ layouts too
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y64o8FKP7rCuXzC48pxpMm
This commit is contained in:
parent
84124de143
commit
ab3dc10587
240 changed files with 477 additions and 476 deletions
|
|
@ -1,11 +1,11 @@
|
|||
"""Eyeball diagnostic: watch a dry MNIST lineage collapse, generation by generation.
|
||||
|
||||
Unlike the `plot_mnist` figure (a pure function of committed parquet), this **re-runs** a short
|
||||
Unlike the `plot_fig2_mnist_collapse` figure (a pure function of committed parquet), this **re-runs** a short
|
||||
dry VAE lineage and saves a grid of freshly-generated digits at a few generations, so the
|
||||
collapse is visible directly — early generations show varied digits, late generations degenerate
|
||||
toward a single blurry mode. Diagnostic only; not part of the reproducible figure set.
|
||||
|
||||
Usage: python figures/mnist_montage.py [results/mnist_collapse]
|
||||
Usage: python figures/mnist_montage.py [results/fig2_mnist_collapse]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -28,7 +28,7 @@ _SNAP_GENS = [0, 4, 8, 12, 15] # generations to snapshot
|
|||
_COLS = 12 # sample digits per row
|
||||
|
||||
|
||||
def main(out_dir: str = "results/mnist_collapse") -> None:
|
||||
def main(out_dir: str = "results/fig2_mnist_collapse") -> None:
|
||||
cfg = MnistCfg()
|
||||
data = load_mnist(cfg.data_root)
|
||||
td = make_mnist_truth(cfg)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.analysis import critical_grounding, reduce_to_stationary # noqa: E402
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.analysis import critical_grounding, reduce_to_stationary # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from neural.config import SyntheticCfg # noqa: E402
|
||||
from neural.synthetic import make_mode_truth # noqa: E402
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from neural.config import SyntheticCfg # noqa: E402
|
||||
from neural.synthetic import make_mode_truth # noqa: E402
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Shows tail-first collapse under pure neutral drift: geometric H decay matching the
|
||||
analytic law, tail items dying faster than head items, support -> 1 and forward-KL
|
||||
diverging. Usage: python figures/plot_E1.py [results/E1]
|
||||
diverging. Usage: python figures/plot_collapse_null.py [results/collapse_null]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -17,7 +17,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E1") -> None:
|
||||
def main(results_dir: str = "results/collapse_null") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
n = cfg["dynamics"]["n"]
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ def main(results_dir: str = "results/E1") -> None:
|
|||
|
||||
fig.suptitle("E1 — distillation without grounding collapses, tail first", y=1.02)
|
||||
fig.tight_layout()
|
||||
savefig(fig, results_dir, "E1")
|
||||
savefig(fig, results_dir, "collapse_null")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -5,7 +5,7 @@ stationary H vs g tracking the exact H_eq, with an operational g* (where H first
|
|||
0.95·H*) and its bootstrap CI, and g=0 marked as a finite-time artifact; (C) tail coverage
|
||||
by item-count vs truth-mass — both stay low, the deep tail is largely unrescuable at
|
||||
feasible grounding; (D) per-rarity-band survival — the m·p*_i≳1 threshold made visible
|
||||
(deep bands lag, motivating E4/E6). Usage: python figures/plot_E2.py [results/E2]
|
||||
(deep bands lag, motivating E4/E6). Usage: python figures/plot_fig2_grounding_sweep.py [results/fig2_grounding_sweep]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -20,12 +20,12 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig, letter_axes # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.analysis import critical_grounding, reduce_to_stationary # noqa: E402
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from knowledge.truth import make_true_distribution # noqa: E402
|
||||
from inheritance.analysis import critical_grounding, reduce_to_stationary # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.truth import make_true_distribution # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E2") -> None:
|
||||
def main(results_dir: str = "results/fig2_grounding_sweep") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
n = cfg["dynamics"]["n"]
|
||||
td = make_true_distribution(cfg["truth"]["K"], 1, "zipf", cfg["truth"]["tail_frac"],
|
||||
|
|
@ -108,7 +108,7 @@ def main(results_dir: str = "results/E2") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E2")
|
||||
savefig(fig, results_dir, "fig2_grounding_sweep")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -10,7 +10,7 @@ Four panels, dry (g=0) vs grounded, mean ± 95% CI across replicates: (A) forwar
|
|||
(B) support size (distinct modes alive); (C) tail truth-mass alive; (D) heterozygosity. Reads the
|
||||
committed bundle (parquet) + manifest.json only.
|
||||
|
||||
Usage: python figures/plot_mnist.py [results/mnist_collapse]
|
||||
Usage: python figures/plot_fig2_mnist_collapse.py [results/fig2_mnist_collapse]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -26,7 +26,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from neural.config import MnistCfg # noqa: E402
|
||||
from neural.mnist_data import make_mnist_truth # noqa: E402
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ def _traj(df, g, col):
|
|||
return gens, grp.mean().to_numpy(), 1.96 * grp.sem().to_numpy()
|
||||
|
||||
|
||||
def main(results_dir: str = "results/mnist_collapse") -> None:
|
||||
def main(results_dir: str = "results/fig2_mnist_collapse") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
syn = MnistCfg(**cfg["mnist"])
|
||||
H_star = heterozygosity(make_mnist_truth(syn).p_star)
|
||||
|
|
@ -72,7 +72,7 @@ def main(results_dir: str = "results/mnist_collapse") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "mnist_collapse")
|
||||
savefig(fig, results_dir, "fig2_mnist_collapse")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -13,7 +13,7 @@ almost immediately; (C) the self-consumption signature — conformity minus true
|
|||
population's mutual agreement exceeds its real capability), largest for no_grounding. Reads only the
|
||||
committed bundle.
|
||||
|
||||
Usage: python figures/plot_E11.py [results/E11]
|
||||
Usage: python figures/plot_fig4_society_ablation.py [results/fig4_society_ablation]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -32,7 +32,7 @@ _ARMS = [("full", "#2ca02c", "full society"),
|
|||
("no_grounding", "#d62728", "no grounding (self-consumption)")]
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E11") -> None:
|
||||
def main(results_dir: str = "results/fig4_society_ablation") -> None:
|
||||
df, _ = load_bundle(results_dir)
|
||||
arms = [a for a in _ARMS if a[0] in set(df["arm"].unique())]
|
||||
g_opt = df["global_opt"].mean()
|
||||
|
|
@ -61,7 +61,7 @@ def main(results_dir: str = "results/E11") -> None:
|
|||
fig.suptitle("E11 — the dynamic Lamarckian society: grounding + directed sex + diversity climb to "
|
||||
"the optimum; remove any one and it breaks (the vertical claim, C3)", y=1.02, fontsize=12)
|
||||
fig.tight_layout()
|
||||
savefig(fig, results_dir, "E11")
|
||||
savefig(fig, results_dir, "fig4_society_ablation")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -8,7 +8,7 @@ vs divergence — the isolation cliff, moving to lower divergence as epistasis d
|
|||
epistasis wedge — as landscape ruggedness K grows, recombining two adapted local-optimum parents flips
|
||||
from a gain to outbreeding depression.
|
||||
|
||||
Usage: python figures/plot_E12.py
|
||||
Usage: python figures/plot_fig5_speciation_bdm.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -30,8 +30,8 @@ def _agg(df, keys, value):
|
|||
|
||||
|
||||
def main() -> None:
|
||||
bdm, _ = load_bundle("results/E12")
|
||||
nk, _ = load_bundle("results/E12_nk")
|
||||
bdm, _ = load_bundle("results/fig5_speciation_bdm")
|
||||
nk, _ = load_bundle("results/speciation_bdm_nk")
|
||||
rhos = sorted(bdm["rho"].unique())
|
||||
colors = plt.cm.viridis(np.linspace(0.15, 0.85, len(rhos)))
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ def main() -> None:
|
|||
fig.suptitle("E12 — model speciation: when two diverged models are too incompatible to merge",
|
||||
y=1.02, fontsize=13)
|
||||
fig.tight_layout()
|
||||
savefig(fig, "results/E12", "E12")
|
||||
savefig(fig, "results/fig5_speciation_bdm", "E12")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -12,7 +12,7 @@ Two panels: (A) the risk — mean offspring fitness minus best-parent vs recombi
|
|||
per ruggedness K (all ≤0, steeper as K grows); (B) with offspring selection — best-of-brood fitness
|
||||
vs rate per K, showing an intermediate optimum on rugged landscapes. Reads only the bundle.
|
||||
|
||||
Usage: python figures/plot_E9.py [results/E9]
|
||||
Usage: python figures/plot_figS10_rugged_landscapes.py [results/figS10_rugged_landscapes]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -27,7 +27,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E9") -> None:
|
||||
def main(results_dir: str = "results/figS10_rugged_landscapes") -> None:
|
||||
df, _ = load_bundle(results_dir)
|
||||
Ks = sorted(df["K"].unique())
|
||||
rates = sorted(df["rate"].unique())
|
||||
|
|
@ -58,7 +58,7 @@ def main(results_dir: str = "results/E9") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E9")
|
||||
savefig(fig, results_dir, "figS10_rugged_landscapes")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -10,7 +10,7 @@ Two panels: (A) deployed capability vs landscape ruggedness — best single pare
|
|||
directed sex, and the global optimum; (B) each strategy's edge over the best parent, making the
|
||||
random-sex collapse and the directed-sex rescue explicit. Reads only the committed bundle.
|
||||
|
||||
Usage: python figures/plot_E10.py [results/E10]
|
||||
Usage: python figures/plot_figS11_directed_recombination.py [results/figS11_directed_recombination]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -24,7 +24,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig, letter_axes # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E10") -> None:
|
||||
def main(results_dir: str = "results/figS11_directed_recombination") -> None:
|
||||
df, _ = load_bundle(results_dir)
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
|
||||
|
|
@ -57,7 +57,7 @@ def main(results_dir: str = "results/E10") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E10")
|
||||
savefig(fig, results_dir, "figS11_directed_recombination")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
At matched grounding, greedy (directional) selection drives the lineage toward the
|
||||
fittest items and collapses diversity, while quality-diversity selection (a novelty bonus
|
||||
w_i ∝ f_i·p_i^{-alpha}) maintains a high stationary heterozygosity that rises with the
|
||||
novelty exponent alpha. Usage: python figures/plot_E5.py [results/E5]
|
||||
novelty exponent alpha. Usage: python figures/plot_figS12_quality_diversity.py [results/figS12_quality_diversity]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -18,7 +18,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E5") -> None:
|
||||
def main(results_dir: str = "results/figS12_quality_diversity") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
last = int(cfg["generations"] * 0.8)
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ def main(results_dir: str = "results/E5") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E5")
|
||||
savefig(fig, results_dir, "figS12_quality_diversity")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -15,7 +15,7 @@ panmictic), one line per landscape ruggedness K:
|
|||
The tension between (A)/(C) is the result: promiscuity maximises the typical model and kills diversity;
|
||||
on rugged landscapes the best model needs preserved diversity, so an intermediate breadth wins.
|
||||
|
||||
Usage: python figures/plot_E14.py
|
||||
Usage: python figures/plot_figS13_mating_breadth.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -30,7 +30,7 @@ from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
|||
|
||||
|
||||
def main() -> None:
|
||||
df, _ = load_bundle("results/E14")
|
||||
df, _ = load_bundle("results/figS13_mating_breadth")
|
||||
last = df[df["generation"] == df["generation"].max()].copy()
|
||||
last["best_n"] = last["best_fitness"] / last["global_opt"]
|
||||
last["mean_n"] = last["mean_fitness"] / last["global_opt"]
|
||||
|
|
@ -60,7 +60,7 @@ def main() -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, "results/E14", "E14")
|
||||
savefig(fig, "results/figS13_mating_breadth", "E14")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -10,7 +10,7 @@ Three panels: (A) forward-KL trajectories per architecture, dry (solid) vs groun
|
|||
(C) tail-item survival, dry vs grounded, grouped by architecture (all rise). Reads only the
|
||||
committed bundle.
|
||||
|
||||
Usage: python figures/plot_architectures.py [results/architectures]
|
||||
Usage: python figures/plot_figS1_architectures.py [results/figS1_architectures]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -29,7 +29,7 @@ _ARCH_LABEL = {"histogram": "histogram\n(exact)", "rnn": "GRU\n(autoregressive)"
|
|||
"mlp": "MLP\n(causal-masked)"}
|
||||
|
||||
|
||||
def main(results_dir: str = "results/architectures") -> None:
|
||||
def main(results_dir: str = "results/figS1_architectures") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
kinds = [k for k in _ARCH_ORDER if k in set(df["kind"].unique())]
|
||||
g_dry, g_wet = min(df["g"].unique()), max(df["g"].unique())
|
||||
|
|
@ -74,7 +74,7 @@ def main(results_dir: str = "results/architectures") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "architectures")
|
||||
savefig(fig, results_dir, "figS1_architectures")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -4,7 +4,7 @@ Re-minting freezes the current distribution as the new grounding reference and d
|
|||
the original truth. Re-minting a collapsed lineage locks in the collapse: KL to the
|
||||
original truth diverges, because the lost original tails can no longer be grounded.
|
||||
Gating re-mint on diversity refuses to re-mint while collapsed and keeps KL bounded;
|
||||
re-minting a healthy lineage is harmless. Usage: python figures/plot_E6.py [results/E6]
|
||||
re-minting a healthy lineage is harmless. Usage: python figures/plot_figS3_rebaselining.py [results/figS3_rebaselining]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -26,7 +26,7 @@ STYLE = {
|
|||
}
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E6") -> None:
|
||||
def main(results_dir: str = "results/figS3_rebaselining") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
period = cfg["dynamics"]["remint"]["period"]
|
||||
G = cfg["generations"]
|
||||
|
|
@ -69,7 +69,7 @@ def main(results_dir: str = "results/E6") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E6")
|
||||
savefig(fig, results_dir, "figS3_rebaselining")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
Shows that grounding must *overlap* the content it protects. At the same total budget,
|
||||
uniform grounding spreads thin and lets the exercised region's tail collapse, while
|
||||
matched grounding concentrates on that region and keeps its rare items alive (at the cost
|
||||
of the regions it does not touch). Usage: python figures/plot_E3.py [results/E3]
|
||||
of the regions it does not touch). Usage: python figures/plot_figS5_aimed_grounding.py [results/figS5_aimed_grounding]
|
||||
|
||||
Metric: per-region tail-item survival. (Per-region *heterozygosity* is confounded by
|
||||
region mass under matched grounding, so it is deliberately not used here.)
|
||||
|
|
@ -21,7 +21,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E3") -> None:
|
||||
def main(results_dir: str = "results/figS5_aimed_grounding") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
R = cfg["truth"]["R"]
|
||||
exercised = cfg["dynamics"]["grounding"]["exercised"]
|
||||
|
|
@ -66,7 +66,7 @@ def main(results_dir: str = "results/E3") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E3")
|
||||
savefig(fig, results_dir, "figS5_aimed_grounding")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -14,7 +14,7 @@ recovery grounding (≈Layer-1's 0.048) and the note that full recovery needs mu
|
|||
smoothing model; (D) the metric-choice panel — H and tail-survival are flat/non-monotone
|
||||
while forward-KL responds. Reads only the committed bundle.
|
||||
|
||||
Usage: python figures/plot_grounding.py [results/grounding]
|
||||
Usage: python figures/plot_figS6_grounding_rnn.py [results/figS6_grounding_rnn]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -29,8 +29,8 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig, letter_axes # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.analysis import reduce_to_stationary # noqa: E402
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.analysis import reduce_to_stationary # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from neural.config import SyntheticCfg # noqa: E402
|
||||
from neural.synthetic import make_mode_truth # noqa: E402
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ def _recovery_gstar(piv: np.ndarray, gs: np.ndarray, frac: float, seed: int = 7)
|
|||
return float(pt), float(lo), float(hi)
|
||||
|
||||
|
||||
def main(results_dir: str = "results/grounding") -> None:
|
||||
def main(results_dir: str = "results/figS6_grounding_rnn") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
syn = SyntheticCfg(**cfg["synthetic"])
|
||||
H_star = heterozygosity(make_mode_truth(syn).p_star)
|
||||
|
|
@ -133,7 +133,7 @@ def main(results_dir: str = "results/grounding") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "grounding")
|
||||
savefig(fig, results_dir, "figS6_grounding_rnn")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -4,7 +4,7 @@ Three panels tell the honest story: (A) union coverage rises with K_T and decorr
|
|||
matching the exact closed form (recombination *supplies* the tail); (B) that supply is
|
||||
realised in the pupil only under a union-preserving merge — mean-mixture distillation
|
||||
dilutes it away (flat in K_T) while max-merge keeps it; (C) the union-surviving gap.
|
||||
Usage: python figures/plot_E4.py [results/E4]
|
||||
Usage: python figures/plot_figS8_multiparent_union.py [results/figS8_multiparent_union]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -23,7 +23,7 @@ def U_closed(K_T, rho, q):
|
|||
return rho * q + (1 - rho) * (1 - (1 - q) ** K_T)
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E4") -> None:
|
||||
def main(results_dir: str = "results/figS8_multiparent_union") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
q = cfg["coverage"]["q"]
|
||||
K_Ts = sorted(df["K_T"].unique())
|
||||
|
|
@ -71,7 +71,7 @@ def main(results_dir: str = "results/E4") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E4")
|
||||
savefig(fig, results_dir, "figS8_multiparent_union")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -11,7 +11,7 @@ mean-mixture "model soup" plateau below; (B) the decorrelation control — sexua
|
|||
count for ρ ∈ {0, 0.5, 1}: decorrelated parents (ρ=0) climb to the optimum, identical parents (ρ=1)
|
||||
buy nothing. Reads only the committed bundle.
|
||||
|
||||
Usage: python figures/plot_E8.py [results/E8]
|
||||
Usage: python figures/plot_figS9_specialist_superparent.py [results/figS9_specialist_superparent]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -26,7 +26,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig, letter_axes # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E8") -> None:
|
||||
def main(results_dir: str = "results/figS9_specialist_superparent") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
L = cfg["society"]["L"]
|
||||
rhos = sorted(df["rho"].unique())
|
||||
|
|
@ -60,7 +60,7 @@ def main(results_dir: str = "results/E8") -> None:
|
|||
|
||||
fig.tight_layout()
|
||||
letter_axes(fig)
|
||||
savefig(fig, results_dir, "E8")
|
||||
savefig(fig, results_dir, "figS9_specialist_superparent")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -13,7 +13,7 @@ one knob of the learning kernel:
|
|||
estimator REMOVES collapse pressure.
|
||||
|
||||
Analytic arms are read from results/kernel_{sharpen,smooth}; the neural reference endpoints
|
||||
(dashed) are read from the committed results/mnist_collapse and results/grounding parquets — so the
|
||||
(dashed) are read from the committed results/fig2_mnist_collapse and results/figS6_grounding_rnn parquets — so the
|
||||
figure is a pure function of committed artifacts.
|
||||
|
||||
Usage: python figures/plot_kernel.py
|
||||
|
|
@ -31,8 +31,8 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, savefig, letter_axes # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parents[1] / "src"))
|
||||
from knowledge.metrics import heterozygosity # noqa: E402
|
||||
from knowledge.truth import make_true_distribution # noqa: E402
|
||||
from inheritance.metrics import heterozygosity # noqa: E402
|
||||
from inheritance.truth import make_true_distribution # noqa: E402
|
||||
|
||||
|
||||
def _mean_traj(df, knob, val, col):
|
||||
|
|
@ -52,8 +52,8 @@ def _neural_dry(results_dir, col, stationary_frac=0.0):
|
|||
|
||||
|
||||
def main() -> None:
|
||||
sh, sh_cfg = load_bundle("results/kernel_sharpen")
|
||||
sm, sm_cfg = load_bundle("results/kernel_smooth")
|
||||
sh, sh_cfg = load_bundle("results/figS2_kernel_sharpen")
|
||||
sm, sm_cfg = load_bundle("results/figS2_kernel_smooth")
|
||||
Hstar_sh = heterozygosity(make_true_distribution(
|
||||
sh_cfg["truth"]["K"], 1, "zipf", 0.5, sh_cfg["truth"]["zipf_s"], 0,
|
||||
tail_threshold=sh_cfg["truth"]["tail_threshold"]).p_star)
|
||||
|
|
@ -62,10 +62,10 @@ def main() -> None:
|
|||
tail_threshold=sm_cfg["truth"]["tail_threshold"]).p_star)
|
||||
|
||||
# Neural reference endpoints (dashed) from the committed neural runs.
|
||||
vae_H = _neural_dry("results/mnist_collapse", "heterozygosity")
|
||||
vae_sup = _neural_dry("results/mnist_collapse", "support_size")
|
||||
rnn_H = _neural_dry("results/grounding", "heterozygosity", stationary_frac=0.4)
|
||||
rnn_KL = _neural_dry("results/grounding", "forward_kl", stationary_frac=0.4)
|
||||
vae_H = _neural_dry("results/fig2_mnist_collapse", "heterozygosity")
|
||||
vae_sup = _neural_dry("results/fig2_mnist_collapse", "support_size")
|
||||
rnn_H = _neural_dry("results/figS6_grounding_rnn", "heterozygosity", stationary_frac=0.4)
|
||||
rnn_KL = _neural_dry("results/figS6_grounding_rnn", "forward_kl", stationary_frac=0.4)
|
||||
|
||||
fig, axes = plt.subplots(2, 2, figsize=(13, 9))
|
||||
NEU, KER = "#1f77b4", "#d62728"
|
||||
|
|
@ -111,7 +111,7 @@ def main() -> None:
|
|||
ax.legend(frameon=False, fontsize=8)
|
||||
|
||||
fig.tight_layout()
|
||||
for d in ("results/kernel_sharpen", "results/kernel_smooth"):
|
||||
for d in ("results/figS2_kernel_sharpen", "results/figS2_kernel_smooth"):
|
||||
letter_axes(fig)
|
||||
savefig(fig, d, "kernel")
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Two panels: (A) mean-fitness adaptation curves, asexual vs sexual, over generati
|
|||
disequilibrium over generations — asexual holds beneficial alleles in disequilibrium (scattered
|
||||
across genotypes) while sexual drives it to ~0 (assembled), the mechanism of the speed gap.
|
||||
|
||||
Usage: python figures/plot_E7.py [results/E7]
|
||||
Usage: python figures/plot_sexual_vs_asexual_lineage.py [results/sexual_vs_asexual_lineage]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -24,7 +24,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from _figlib import load_bundle, mean_ci, savefig # noqa: E402
|
||||
|
||||
|
||||
def main(results_dir: str = "results/E7") -> None:
|
||||
def main(results_dir: str = "results/sexual_vs_asexual_lineage") -> None:
|
||||
df, cfg = load_bundle(results_dir)
|
||||
L = cfg["genotype"]["L"]
|
||||
arms = [(0.0, "#7f7f7f", "asexual (clonal)"), (1.0, "#d62728", "sexual (recombining)")]
|
||||
|
|
@ -55,7 +55,7 @@ def main(results_dir: str = "results/E7") -> None:
|
|||
fig.suptitle("E7 — the advantage of sex: recombination reassorts beneficial alleles that arose "
|
||||
"in different lineages", y=1.02, fontsize=12)
|
||||
fig.tight_layout()
|
||||
savefig(fig, results_dir, "E7")
|
||||
savefig(fig, results_dir, "sexual_vs_asexual_lineage")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Loading…
Add table
Add a link
Reference in a new issue