- gadm04.py: cohort capability split into durable (education-formed, slow depreciation, birth dilution) and current components; learning begets learning; starts identical to GADM-0.3 (tested) - L3 now supported: education reaches working-age capability with a 17-year half-time and 3x the effect; L1 still holds, more weakly - life_cycle.py selectable per model; GADM-0.3 results unchanged 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
85 lines
4 KiB
Python
85 lines
4 KiB
Python
"""Life-cycle hypotheses L1-L3 for GADM-0.3 with cohorts (gadm03c).
|
|
|
|
L1: strong intergenerational transfer T_g lets an ageing society keep H.
|
|
L2: care demand competes with attention; without recognized care participation
|
|
(C_p), attention headroom falls fastest in the working-age cohort.
|
|
L3: children's capability formation reaches working-age capability with a lag
|
|
of 15-20 years.
|
|
|
|
Usage: python3 -B simulations/gadm02/life_cycle.py [--model gadm04]
|
|
(default model: gadm03c, the GADM-0.3 cohort model)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.dont_write_bytecode = True
|
|
|
|
import importlib # noqa: E402
|
|
|
|
MODEL = sys.argv[sys.argv.index("--model") + 1] if "--model" in sys.argv else "gadm03c"
|
|
c = importlib.import_module(MODEL)
|
|
from scenarios import load_all # noqa: E402
|
|
|
|
OUT = Path(__file__).resolve().parent / "results"
|
|
STABLE, AGEING = 1 / 45, 0.75 / 45
|
|
|
|
|
|
def run(params: dict, base: dict) -> list[dict]:
|
|
return c.simulate({**base["params"], **params}, base["init"])
|
|
|
|
|
|
def main() -> None:
|
|
OUT.mkdir(exist_ok=True)
|
|
sc = load_all()["baseline"]
|
|
lines = [f"# {c.MODEL_VERSION}: life-cycle hypotheses", "",
|
|
"Generated by `simulations/gadm02/life_cycle.py`. Baseline background,",
|
|
"t = 100 years. Ageing demography: births at 75 % of replacement.", ""]
|
|
|
|
lines += ["## L1: intergenerational transfer in an ageing society", "",
|
|
"| Demography | T_g (tg) | seniors + very old (share, t=100) | H (t=0) | H (t=100) | ΔH |",
|
|
"|---|---|---|---|---|---|"]
|
|
for demo, b in (("stable", STABLE), ("ageing", AGEING)):
|
|
for tg in (0.0, 0.05, 0.15):
|
|
r = run({"birth": b, "tg": tg}, sc)
|
|
old = r[-1]["n_s"] + r[-1]["n_d"]
|
|
lines.append(f"| {demo} | {tg:.2f} | {old:.2f} | {r[0]['H']:.3f} | {r[-1]['H']:.3f} | "
|
|
f"{r[-1]['H'] - r[0]['H']:+.3f} |")
|
|
|
|
lines += ["", "## L2: care load and attention", "",
|
|
"Levels at t = 100 are compared across settings (not against t = 0, because",
|
|
"initial cohort attention is not at its own equilibrium).", "",
|
|
"| Demography | care_sen (seniors' care share) | cp | A working age | A seniors | care load per working-age person | per senior |",
|
|
"|---|---|---|---|---|---|---|"]
|
|
for demo, b in (("stable", STABLE), ("ageing", AGEING)):
|
|
for cs in (0.1, 0.3):
|
|
for cp in (0.0, 0.15):
|
|
prm = {"birth": b, "cp": cp, "care_sen": cs}
|
|
r = run(prm, sc)[-1]
|
|
pp = {**c.PARAMS, **sc["params"], **prm}
|
|
load = pp["care_load"] * r["care_need"] * max(0.0, 1 - pp["care_relief"] * cp)
|
|
lines.append(f"| {demo} | {cs:.1f} | {cp:.2f} | {r['Aw']:.3f} | {r['As']:.3f} | "
|
|
f"{load * (1 - cs) / r['n_w']:.4f} | {load * cs / r['n_s']:.4f} |")
|
|
|
|
lines += ["", "## L3: lag from education to working-age capability", "",
|
|
"Run difference: education intensity 1.5 vs. 1.0, everything else equal.", "",
|
|
"| t | ΔH children | ΔH working age | ΔH aggregate |", "|---|---|---|---|"]
|
|
lo, hi = run({"edu": 1.0}, sc), run({"edu": 1.5}, sc)
|
|
diffs = [(a["t"], b["Hch"] - a["Hch"], b["Hw"] - a["Hw"], b["H"] - a["H"]) for a, b in zip(lo, hi)]
|
|
for t, dc, dw, dh in diffs:
|
|
if t in (0, 5, 10, 15, 20, 25, 30, 40, 50, 75, 100):
|
|
lines.append(f"| {t:.0f} | {dc:+.3f} | {dw:+.3f} | {dh:+.3f} |")
|
|
final_w, final_c = diffs[-1][2], diffs[-1][1]
|
|
t_w = next(t for t, _dc, dw, _dh in diffs if dw >= 0.5 * final_w)
|
|
t_c = next(t for t, dc, _dw, _dh in diffs if dc >= 0.5 * final_c)
|
|
lines += ["", f"Half of the final effect is reached after {t_c:.0f} years for children and "
|
|
f"{t_w:.0f} years for working-age capability.", ""]
|
|
name = "life_cycle.md" if MODEL == "gadm03c" else f"life_cycle_{MODEL}.md"
|
|
(OUT / name).write_text("\n".join(lines))
|
|
print("\n".join(lines))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|