- gadm04: W, Aw, As start at their equilibria (equilibrium_init, tested); channel counters calibrated at GADM-0.4's own initial state - robustness/gsa use the model's own calibration - P3 now holds in all robustness variants (the T02 exception was an initial-condition artifact); life-cycle readings confirmed - GSA rerun: model mostly additive (sum S1 ~0.99 generative, was 0.89); governance levers m, L, r_lin strongly non-linear; T03 reading corrected 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
90 lines
4 KiB
Python
90 lines
4 KiB
Python
"""Robustness of key GADM readings to grounded and bracketed parameters (T02).
|
||
|
||
Variants: GADM-0.4 with the old organism depreciation (dO = 0.06), with the
|
||
grounded value (dO = 0.20, rescaled), and the grounded value with brackets on
|
||
the ungrounded channel self-reinforcement r and wealth conversion k_w. Channel
|
||
counters are recalibrated for every variant so each starts in equilibrium.
|
||
|
||
Usage: python3 -B simulations/gadm02/robustness.py
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import itertools
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
sys.dont_write_bytecode = True
|
||
|
||
import gadm04 as g # noqa: E402
|
||
from scenarios import load_all # noqa: E402
|
||
|
||
OUT = Path(__file__).resolve().parent / "results"
|
||
R_KEYS = ("r_m", "r_i", "r_mem", "r_lin", "r_pol")
|
||
OLD_DO = {"dO": 0.06, "aO": 0.15, "ell": 0.25, "oseed": 0.01}
|
||
|
||
|
||
def variant(extra: dict) -> dict:
|
||
return {**extra, **g.calibrate(extra)}
|
||
|
||
|
||
VARIANTS = [
|
||
("old dO = 0.06", variant(OLD_DO)),
|
||
("grounded dO = 0.20", variant({})),
|
||
("grounded, r = 0.15", variant({**{k: 0.15 for k in R_KEYS}, "r_d": 0.2})),
|
||
("grounded, r = 0.45", variant({**{k: 0.45 for k in R_KEYS}, "r_d": 0.6})),
|
||
("grounded, k_w = 0.02", variant({"k_w": 0.02})),
|
||
("grounded, k_w = 0.20", variant({"k_w": 0.20})),
|
||
]
|
||
GRID = {"lineage": ({"L": 0.1, "lin_open": 0.1}, {"L": 0.8, "lin_open": 0.8}),
|
||
"membrane": ({"m": 0.2}, {"m": 0.8}),
|
||
"attention": ({"x_att": 0.9}, {"x_att": 0.2})}
|
||
|
||
|
||
def main() -> None:
|
||
OUT.mkdir(exist_ok=True)
|
||
scs = load_all()
|
||
names = list(scs)
|
||
ref_rank = None
|
||
lines = [f"# {g.MODEL_VERSION}: robustness of key readings", "",
|
||
"Generated by `simulations/gadm02/robustness.py`. t = 100 years.",
|
||
"Readings checked: (1) scenario VFAC ranking (Spearman ρ against the grounded",
|
||
"variant), (2) generative regime lowest P, (3) organism lever order on the",
|
||
"baseline background, (4) P3: full wealth tax lowers P by < 0.06 in the",
|
||
"membrane/lineage-dominated case.", "",
|
||
"| Variant | best scenario | worst scenario | ρ ranking | generative P | lineage / membrane / attention effect | lever order holds | P3 ΔP | P3 holds |",
|
||
"|---|---|---|---|---|---|---|---|---|"]
|
||
rows = []
|
||
for label, prm in VARIANTS:
|
||
res = {n: g.simulate({**scs[n]["params"], **prm}, scs[n]["init"])[-1] for n in names}
|
||
order = sorted(names, key=lambda n: -res[n]["VFAC"])
|
||
rank = {n: i for i, n in enumerate(order)}
|
||
rows.append((label, prm, res, order, rank))
|
||
ref_rank = rows[1][4]
|
||
k = len(names)
|
||
for label, prm, res, order, rank in rows:
|
||
rho = 1 - 6 * sum((rank[n] - ref_rank[n]) ** 2 for n in names) / (k * (k * k - 1))
|
||
gen_lowest = min(names, key=lambda n: res[n]["P"]) == "generative_regime"
|
||
base = scs["baseline"]
|
||
out = {}
|
||
for lv in itertools.product((0, 1), repeat=3):
|
||
p = {**base["params"], **prm}
|
||
for ax, l in zip(GRID, lv):
|
||
p.update(GRID[ax][l])
|
||
out[lv] = g.simulate(p, base["init"])[-1]["VFAC"]
|
||
eff = [sum((1 if lv[i] else -1) * v for lv, v in out.items()) / 4 for i in range(3)]
|
||
order_ok = eff[0] > eff[1] > eff[2] > 0
|
||
mem = scs["generative_concentrated_lineages"]
|
||
p0 = g.simulate({**mem["params"], **prm, "wtax": 0.0}, mem["init"])[-1]["P"]
|
||
p1 = g.simulate({**mem["params"], **prm, "wtax": 1.0}, mem["init"])[-1]["P"]
|
||
lines.append(f"| {label} | {scs[order[0]]['title']} ({res[order[0]]['VFAC']:.3f}) | "
|
||
f"{scs[order[-1]]['title']} ({res[order[-1]]['VFAC']:.3f}) | {rho:.2f} | "
|
||
f"{res['generative_regime']['P']:.2f}{' (lowest)' if gen_lowest else ''} | "
|
||
f"{eff[0]:+.3f} / {eff[1]:+.3f} / {eff[2]:+.3f} | {'yes' if order_ok else 'no'} | "
|
||
f"{p1 - p0:+.3f} | {'yes' if p0 - p1 < 0.06 else 'no'} |")
|
||
(OUT / "robustness.md").write_text("\n".join(lines) + "\n")
|
||
print("\n".join(lines))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|