- 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
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
"""Sanity tests for the GADM-0.2 toy simulation.
|
|
|
|
Usage: python3 -m unittest discover -s simulations/gadm02
|
|
"""
|
|
|
|
import unittest
|
|
|
|
import gadm02 as g
|
|
from scenarios import load_all
|
|
|
|
|
|
class TestGADM02(unittest.TestCase):
|
|
def test_stocks_stay_bounded_in_all_scenarios(self):
|
|
for name, sc in load_all().items():
|
|
for row in g.simulate(sc["params"], sc["init"]):
|
|
for k in g.STOCKS:
|
|
self.assertGreaterEqual(row[k], 0.0, (name, k))
|
|
self.assertLessEqual(row[k], 1.0, (name, k))
|
|
|
|
def test_deterministic(self):
|
|
self.assertEqual(g.simulate(), g.simulate())
|
|
|
|
def test_unknown_parameter_rejected(self):
|
|
with self.assertRaises(KeyError):
|
|
g.simulate({"not_a_param": 1.0})
|
|
|
|
def test_vfac_is_geometric_mean(self):
|
|
s = {k: 0.5 for k in g.STOCKS}
|
|
self.assertAlmostEqual(g.vfac(s), 0.5)
|
|
s["E"] = 0.0
|
|
self.assertEqual(g.vfac(s), 0.0) # full collapse in one factor collapses VFAC
|
|
s["E"] = 0.01
|
|
# equal exponents damp near-collapse: (0.01/0.5)^(1/9) ≈ 0.65 of the level,
|
|
# which is why constitutional floors are checked separately from VFAC
|
|
self.assertAlmostEqual(g.vfac(s), 0.5 * (0.02 ** (1 / 9)), places=6)
|
|
|
|
def test_scenarios_only_use_known_parameters(self):
|
|
for name, sc in load_all().items():
|
|
self.assertFalse(set(sc["params"]) - set(g.PARAMS), name)
|
|
|
|
def test_floor_violations(self):
|
|
rows = [{"G": 0.1, "E": 0.5, "P": 0.8, "A": 0.5}, {"G": 0.5, "E": 0.5, "P": 0.5, "A": 0.5}]
|
|
v = g.floor_violations(rows)
|
|
self.assertEqual(v["G"], 0.5)
|
|
self.assertEqual(v["P"], 0.5)
|
|
self.assertEqual(v["E"], 0.0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|