Architecture#
CGE-Core v0.8 separates six concerns:
economic model definitions;
benchmark data and calibration;
model-owned closure and policy metadata;
counterfactual workflow;
numerical result interfaces; and
solver resolution.
The public interface is deliberately smaller than the implementation. The four bundled model families present a similar modelling workflow, but v0.8 does not force them through one internal implementation when their economics or validation requirements differ.
Practitioner-first public architecture#
flowchart TB
U["Practitioner"]
subgraph PUBLIC["Practitioner entry points"]
G["SimpleCGE · StandardCGE · CamCGE"]
I["IFPRICGE"]
end
subgraph GENERIC["Generic Simple / Standard / CAMCGE path"]
GW["Scientific workflow<br/>CGE → Equilibrium → Scenario → Result"]
MD["Model definition + ModelSpec"]
CE["CoreEngine<br/>model-declared policy"]
PY["PyCGE<br/>instance · mutation · rollback · solve bookkeeping"]
end
subgraph IFPRI["IFPRI-specific path"]
IW["IFPRI workflow<br/>IFPRIEquilibrium → IFPRIScenario → IFPRIResult"]
IM["IFPRI calibration · closure<br/>named scenario builders"]
end
subgraph NUM["Shared numerical boundary"]
P["Pyomo model"]
SR["cge_core.solver<br/>backend resolution"]
N["Supported NLP backend<br/>Ipopt · cyipopt · COIN/ipoptnl"]
end
U --> G
U --> I
G --> GW
GW --> MD
MD --> CE
CE --> PY
PY --> P
I --> IW
IW --> IM
IM --> P
P --> SR
SR --> N
classDef public fill:#eef4ff,stroke:#4f6fad,stroke-width:2px,color:#172033;
classDef generic fill:#f6f2ff,stroke:#7252b8,stroke-width:1.5px,color:#172033;
classDef ifpri fill:#edf8f4,stroke:#3c806b,stroke-width:1.5px,color:#172033;
classDef numerical fill:#fff7e8,stroke:#9a6b22,stroke-width:1.5px,color:#172033;
class U,G,I public;
class GW,MD,CE,PY generic;
class IW,IM ifpri;
class P,SR,N numerical;
Use the mouse wheel or a trackpad pinch gesture to zoom, drag to pan, or select ⛶ to inspect the diagram in full screen.
Mermaid source
flowchart TB
U["Practitioner"]
subgraph PUBLIC["Practitioner entry points"]
G["SimpleCGE · StandardCGE · CamCGE"]
I["IFPRICGE"]
end
subgraph GENERIC["Generic Simple / Standard / CAMCGE path"]
GW["Scientific workflow<br/>CGE → Equilibrium → Scenario → Result"]
MD["Model definition + ModelSpec"]
CE["CoreEngine<br/>model-declared policy"]
PY["PyCGE<br/>instance · mutation · rollback · solve bookkeeping"]
end
subgraph IFPRI["IFPRI-specific path"]
IW["IFPRI workflow<br/>IFPRIEquilibrium → IFPRIScenario → IFPRIResult"]
IM["IFPRI calibration · closure<br/>named scenario builders"]
end
subgraph NUM["Shared numerical boundary"]
P["Pyomo model"]
SR["cge_core.solver<br/>backend resolution"]
N["Supported NLP backend<br/>Ipopt · cyipopt · COIN/ipoptnl"]
end
U --> G
U --> I
G --> GW
GW --> MD
MD --> CE
CE --> PY
PY --> P
I --> IW
IW --> IM
IM --> P
P --> SR
SR --> N
classDef public fill:#eef4ff,stroke:#4f6fad,stroke-width:2px,color:#172033;
classDef generic fill:#f6f2ff,stroke:#7252b8,stroke-width:1.5px,color:#172033;
classDef ifpri fill:#edf8f4,stroke:#3c806b,stroke-width:1.5px,color:#172033;
classDef numerical fill:#fff7e8,stroke:#9a6b22,stroke-width:1.5px,color:#172033;
class U,G,I public;
class GW,MD,CE,PY generic;
class IW,IM ifpri;
class P,SR,N numerical;
For the Hosoe Simple, Hosoe Standard, and CAMCGE families, the modeller sees the generic scientific lifecycle:
StandardCGE.example()
│
└── solve()
↓
Equilibrium
│
├── scenario("A") → tariff/endowment/... → solve() → Result A
│
└── scenario("B") → tariff/endowment/... → solve() → Result B
Result A.compare(Equilibrium)
Result A.compare(Result B)
SimpleCGE, StandardCGE, and CamCGE configure this lifecycle with their own model
definition and ModelSpec. Their canonical closure is therefore model-owned even though
the surrounding workflow is shared.
IFPRICGE deliberately follows a parallel path. It exposes the same benchmark → scenario →
solve → inspect idea through IFPRIEquilibrium, IFPRIScenario, and IFPRIResult, while
retaining IFPRI-specific calibration, named policy scenarios, and macro-closure machinery.
It does not pass through the generic CGE / CoreEngine workflow merely for architectural
symmetry.
For the generic Simple/Standard/CAMCGE path, a scenario owns one independent clone of the calibrated benchmark. The benchmark remains protected, and solved results expose immutable numerical snapshots for ordinary inspection. IFPRI provides its own result objects over its model-specific solved states.
Generic workflow and the retained PyCGE engine#
The generic v0.8 path has three distinct software layers:
CGE → Equilibrium → Scenario → Resultis the scientific workflow layer;CoreEngineis the CGE-Core policy adapter; andPyCGEis the retained lower-level engine mechanics.
flowchart TB
USER["Model façade / advanced user"]
subgraph DEF["Model-specific definition and policy"]
MODEL["Economic model definition<br/>sets · parameters · variables · equations"]
SPEC["ModelSpec<br/>closure metadata · protection<br/>semantic shocks · required data"]
DATA["SAM / packaged model data"]
end
subgraph WF["Generic scientific workflow"]
CGE["CGE"]
EQ["Equilibrium<br/>protected benchmark + snapshot"]
SC["Scenario<br/>one independent model clone"]
RES["Result<br/>immutable numerical snapshot"]
end
subgraph ENG["Engine layers"]
CORE["CoreEngine<br/>ModelSpec-driven policy"]
PYCGE["PyCGE<br/>instance construction · mutation<br/>undo/rollback · solve bookkeeping"]
end
subgraph RUN["Numerical runtime"]
PYOMO["Pyomo ConcreteModel"]
SOLVER["cge_core.solver<br/>resolve supported backend"]
NLP["NLP backend<br/>Ipopt · cyipopt · COIN/ipoptnl"]
end
USER --> CGE
MODEL --> CGE
SPEC --> CGE
DATA --> CGE
CGE --> CORE
SPEC --> CORE
CORE --> PYCGE
PYCGE --> PYOMO
PYOMO --> SOLVER
SOLVER --> NLP
NLP --> EQ
EQ --> SC
SC --> PYCGE
NLP --> RES
classDef model fill:#edf8f4,stroke:#3c806b,stroke-width:1.5px,color:#172033;
classDef workflow fill:#eef4ff,stroke:#4f6fad,stroke-width:1.5px,color:#172033;
classDef engine fill:#f6f2ff,stroke:#7252b8,stroke-width:1.5px,color:#172033;
classDef runtime fill:#fff7e8,stroke:#9a6b22,stroke-width:1.5px,color:#172033;
class MODEL,SPEC,DATA model;
class CGE,EQ,SC,RES workflow;
class CORE,PYCGE engine;
class PYOMO,SOLVER,NLP runtime;
Mermaid source
flowchart TB
USER["Model façade / advanced user"]
subgraph DEF["Model-specific definition and policy"]
MODEL["Economic model definition<br/>sets · parameters · variables · equations"]
SPEC["ModelSpec<br/>closure metadata · protection<br/>semantic shocks · required data"]
DATA["SAM / packaged model data"]
end
subgraph WF["Generic scientific workflow"]
CGE["CGE"]
EQ["Equilibrium<br/>protected benchmark + snapshot"]
SC["Scenario<br/>one independent model clone"]
RES["Result<br/>immutable numerical snapshot"]
end
subgraph ENG["Engine layers"]
CORE["CoreEngine<br/>ModelSpec-driven policy"]
PYCGE["PyCGE<br/>instance construction · mutation<br/>undo/rollback · solve bookkeeping"]
end
subgraph RUN["Numerical runtime"]
PYOMO["Pyomo ConcreteModel"]
SOLVER["cge_core.solver<br/>resolve supported backend"]
NLP["NLP backend<br/>Ipopt · cyipopt · COIN/ipoptnl"]
end
USER --> CGE
MODEL --> CGE
SPEC --> CGE
DATA --> CGE
CGE --> CORE
SPEC --> CORE
CORE --> PYCGE
PYCGE --> PYOMO
PYOMO --> SOLVER
SOLVER --> NLP
NLP --> EQ
EQ --> SC
SC --> PYCGE
NLP --> RES
classDef model fill:#edf8f4,stroke:#3c806b,stroke-width:1.5px,color:#172033;
classDef workflow fill:#eef4ff,stroke:#4f6fad,stroke-width:1.5px,color:#172033;
classDef engine fill:#f6f2ff,stroke:#7252b8,stroke-width:1.5px,color:#172033;
classDef runtime fill:#fff7e8,stroke:#9a6b22,stroke-width:1.5px,color:#172033;
class MODEL,SPEC,DATA model;
class CGE,EQ,SC,RES workflow;
class CORE,PYCGE engine;
class PYOMO,SOLVER,NLP runtime;
ModelSpec#
ModelSpec carries model-specific software policy that should not be guessed from component
names: default closure metadata, protected benchmark components, semantic policy shocks, and
required data declarations. Economic equations remain in the model-definition modules.
CoreEngine#
CoreEngine is intentionally small. It subclasses PyCGE and changes the protection policy
so benchmark/base protection comes from ModelSpec rather than historical naming rules such
as a trailing 0.
PyCGE#
The retained lower-level engine owns the mature mechanics used by the generic workflow: instance construction, mutation, undo/rollback, solver execution, and result bookkeeping. Advanced users can still import it intentionally with:
from cge_core import PyCGE
The practitioner façades do not rewrite validated economic algebra. They configure and call the appropriate model-specific implementation while hiding routine framework plumbing.
Solver boundary#
Ordinary code calls .solve() rather than managing solver installation or PATH state.
cge_core.solver resolves a supported nonlinear backend and is shared by the generic and
IFPRI paths. It prefers a usable system Ipopt, then a working cyipopt, and otherwise can
prepare the packaged COIN/Ipopt NL route used through Pyomo.
The architecture therefore separates an economic modelling decision from the numerical backend used to solve it.
Model-family boundaries#
Family |
v0.8 public path |
Closure |
|---|---|---|
Hosoe Simple |
Generic |
Model-owned canonical closure |
Hosoe Standard |
Generic |
Model-owned canonical closure |
CAMCGE |
Generic |
CAMCGE-specific closure |
IFPRI Standard |
IFPRI-specific equilibrium/scenario/result adapter |
IFPRI-specific closure and named scenarios |
The project therefore shares practitioner semantics without pretending there is one universal CGE equation template or one mandatory internal workflow.
The Standard CGE in economic blocks#
Block |
Main role |
|---|---|
Production and factors |
Firms combine factors and intermediate inputs |
Household |
Factor income finances consumption, saving, and direct taxes |
Government |
Tax revenue finances government demand and saving |
Investment |
Domestic and foreign saving finance investment demand |
Armington trade |
Imports and domestic goods form composite supply |
CET transformation |
Output is allocated between domestic and export markets |
Market clearing |
Commodity and factor markets balance |
External balance |
Export receipts and foreign saving finance imports |
Closure |
A price anchor and independent equilibrium conditions complete the system |
Trace economics to implementation#
Economic concept |
Theory |
Detailed equations |
Public workflow |
|---|---|---|---|
Production |
|
||
Final demand |
result inspection |
||
Trade |
|
||
Closure / Walras’ law |
model-owned for bundled models |
||
SAM loading |
|
||
Policy simulation |
benchmark → scenario → result |
||
IFPRI scenarios |
|
||
Advanced engine inspection |
|
The intended reading path is:
economic meaning → equation → practitioner workflow → lower-level implementation only when needed.