- models/GADM-CLD.md: causal-loop diagram, loops, 49 signed links - models/GADM-0.2.md: organism extensions (K split, attention headroom, selection channel O, membrane/lineage levers, participation claims), equations, findings - simulations/gadm02: stdlib simulation, scenario runner, OAT sensitivity, unit tests; results committed - scenarios/: six GADM-0.1 regimes + baseline + two organism-axis variants - metrics/MetricsCatalog.md, models/GADM-0.3-Candidates.md, references/LiteratureComparison.md - ASSEMBLY-WP-0005 (proposed, residual): GADM-0.3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 1494246@bnt-lap001 Assistant-Session: caf6de6f-f9e4-47ce-a584-49baa271fa4b
60 lines
2.2 KiB
Python
60 lines
2.2 KiB
Python
"""One-at-a-time sensitivity of final VFAC to every parameter (±20 %).
|
||
|
||
Usage: python3 simulations/gadm02/sensitivity.py
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
import gadm02 as g
|
||
from scenarios import load_all
|
||
|
||
OUT = Path(__file__).resolve().parent / "results"
|
||
LEVERS = {"m", "L", "lin_open", "std", "disc", "expl", "x_att", "auto", "dshare", "cp", "od"}
|
||
DELTA = 0.20
|
||
TOP = 15
|
||
|
||
|
||
def final_vfac(params: dict, init: dict) -> float:
|
||
return g.simulate(params, init)[-1]["VFAC"]
|
||
|
||
|
||
def analyse(sc: dict) -> list[tuple[str, float, float, float]]:
|
||
base_p = {**g.PARAMS, **sc["params"]}
|
||
v0 = final_vfac(base_p, sc["init"])
|
||
res = []
|
||
for k, val in base_p.items():
|
||
lo, hi = val * (1 - DELTA), val * (1 + DELTA)
|
||
if k in LEVERS:
|
||
hi = min(hi, 1.0)
|
||
if val == 0:
|
||
lo, hi = 0.0, 0.05
|
||
d_lo = final_vfac({**base_p, k: lo}, sc["init"]) - v0
|
||
d_hi = final_vfac({**base_p, k: hi}, sc["init"]) - v0
|
||
res.append((k, d_lo, d_hi, max(abs(d_lo), abs(d_hi))))
|
||
res.sort(key=lambda r: -r[3])
|
||
return v0, res
|
||
|
||
|
||
def main() -> None:
|
||
OUT.mkdir(exist_ok=True)
|
||
scs = load_all()
|
||
lines = [f"# {g.MODEL_VERSION} sensitivity (one-at-a-time, ±{DELTA:.0%})", "",
|
||
"Generated by `simulations/gadm02/sensitivity.py`. ΔVFAC is the change in",
|
||
"final VFAC (t = 100) when one parameter moves down or up by 20 %, all others",
|
||
"fixed. Levers in [0, 1] are capped at 1. Zero-valued parameters are tested at",
|
||
"0.05. One-at-a-time analysis misses interactions.", ""]
|
||
for name in ("baseline", "generative_regime"):
|
||
v0, res = analyse(scs[name])
|
||
rank = {r[0]: i + 1 for i, r in enumerate(res)}
|
||
lines += [f"## {scs[name]['title']} (VFAC = {v0:.3f})", "",
|
||
"| Rank | Parameter | ΔVFAC at −20 % | ΔVFAC at +20 % |", "|---|---|---|---|"]
|
||
lines += [f"| {i + 1} | `{k}` | {lo:+.4f} | {hi:+.4f} |" for i, (k, lo, hi, _) in enumerate(res[:TOP])]
|
||
lines += ["", f"Reuse coefficient `rho0` ranks {rank['rho0']} of {len(res)}.", ""]
|
||
(OUT / "sensitivity.md").write_text("\n".join(lines))
|
||
print("\n".join(lines))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|