GTAP 7 Parity Coverage Matrix

Same-engine parity between the Python equilibria GTAP Standard 7 implementation and GAMS: NLP vs NLP (IPOPT both sides) and MCP vs MCP (PATH both sides), so the solver’s equality tolerance cancels and the cell-by-cell match reflects model fidelity, not solver noise. Cells show the conservative per-stage floor each pytest gate asserts (the gate runs the real solve, measures match% @ tol 1% and the return code, and requires match floor and code == 1); the measured snapshot is not stored here — the live views re-run the measurement. A separate solver-free .nl coefficient gate (0 Jacobian diffs vs GAMS, test_gtap7_nl_parity.py) runs in CI as the structural canary.

Each cell is the per-stage floor the pytest gate asserts (measured match% @ tol 1% must be ≥ floor):≥9995–99<95convergence chip: ✓ code 1 required code ≤ 2 audited near-misslocal gates need PATH/IPOPT + GAMS refs — run by hand, not in CI

NLP vs NLP

Python solved as an NLP (EQUILIBRIA_GTAP_SOLVE_NLP=1, maximize walras) against the GAMS ifMCP=0 NLP reference — same IPOPT both sides. Gate: test_gtap7_nlp_parity.py (local; needs IPOPT + the committed GAMS refs). Measured view: live NLP matrix.

Pure-gtap (real-CES)

Dataset · ifSUBBaseCheckShockReference
gtap7_3x3ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_3x3_ifsub0_nlp.gdx
gtap7_3x3ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_3x3_nlp.gdx
gtap7_5x5ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_5x5_ifsub0_nlp.gdx
gtap7_5x5ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_5x5_nlp.gdx
gtap7_10x7ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_10x7_ifsub0_nlp.gdx
gtap7_10x7ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_10x7_nlp.gdx
100% across every stage, both ifSUB, after the Jacobian pre-scale skip (commit e4c40d7) — GAMS solves the raw model; the Python-only pre-scale steered IPOPT to a wrong basin on the 5×5 shock (59.56% → 100%).

Altertax (CD)

Dataset · ifSUBBaseCheckShockReference
gtap7_3x3ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub0.gdx
gtap7_3x3ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub1.gdx
gtap7_3x4ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub0.gdx
gtap7_3x4ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub1.gdx
gtap7_5x5ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub0.gdx
gtap7_5x5ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_nlp_ifsub1.gdx
gtap7_10x7ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 98✓ code 1
out_altertax_nlp_ifsub0.gdx
gtap7_10x7ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 98✓ code 1
out_altertax_nlp_ifsub1.gdx
The check/shock ceiling here is the reference, not the model. The altertax NLP references are mis-converged (IPOPT "Locally Optimal", the ref violates its own eq_pxeq in the ag sector). Where a cleanly-converged MCP reference exists the same Python solve reaches 99.9% — see the MCP gate below.

MCP vs MCP

Python solved via PATH (nonlinear-full MCP) against the cleanly-converged NEOS MCP references — same PATH both sides. Gate: test_gtap7_mcp_parity.py (local; needs PATH + the committed refs). This is the daily fidelity gate. Measured view: live MCP matrix.

Pure-gtap (real-CES)

Dataset · ifSUBBaseCheckShockReference
gtap7_3x3ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub0.gdx
gtap7_3x3ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub1.gdx
gtap7_5x5ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub0.gdx
gtap7_5x5ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub1.gdx
gtap7_10x7ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub0.gdx
gtap7_10x7ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub1.gdx
gtap7_15x10ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_gtap_shock_ifsub0.gdx
gtap7_15x10ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99code ≤ 2
out_gtap_shock_ifsub1.gdx

Altertax (CD)

Dataset · ifSUBBaseCheckShockReference
gtap7_3x3ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub0.gdx
gtap7_3x3ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub1.gdx
gtap7_3x4ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub0.gdx
gtap7_3x4ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub1.gdx
gtap7_5x5ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub0.gdx
gtap7_5x5ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub1.gdx
gtap7_10x7ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 98✓ code 1
out_altertax_ifsub0.gdx
gtap7_10x7ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 98✓ code 1
out_altertax_ifsub1.gdx
gtap7_15x10ifSUB=0
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub0.gdx
gtap7_15x10ifSUB=1
≥ 99✓ code 1
≥ 99✓ code 1
≥ 99✓ code 1
out_altertax_ifsub1.gdx