Choose a solver before you write the detailed model. Solver selection determines which
economic roles and structural boundaries the model must declare; it is not a performance
switch to flip after an arbitrary Regime has been assembled.
Make the decision in two passes:
keep only solvers whose assumptions represent the economic problem;
benchmark those candidates for accuracy, compilation, memory, and wall time on the target hardware.
Before choosing an EGM-family solver¶
An EGM-family route is available only when the model exposes the structure the numerical method consumes. Check these gates before selecting a solver:
the declaration is
ConsumptionSavingsRegimefor one liquid margin orNestedConsumptionSavingsRegimefor a liquid margin inside one outer continuous choice;each margin names its state, action, post-decision state, and resources or no-adjustment role;
the savings grid begins at the declared
post_decision_lower_bound;every additional constraint, discrete choice, stochastic object, boundary, and preference recursion is supported by the particular solver;
kinks, jumps, and hard boundaries are declared with case pieces or a piecewise-affine schedule rather than hidden inside an opaque function.
for
NNBEGM, the outer post-decision map is affine in the outer action with a constant power-of-two coefficient —new = offset(states, params) + actionandnew = old + 2 * actionqualify, a state-dependent or non-dyadic slope does not. A model whose conversion rate depends on the state needsGridSearch; see NNBEGM.
Plain EGM has the narrowest gate: exactly one continuous state and action, no discrete
or process states/actions, liquid resources equal to the liquid state, savings equal to
state minus action, utility independent of the liquid state, the default Koopmans
aggregator, and no solve-time constraint except a provable savings lower bound. DCEGM,
NBEGM, and the nested solvers each add specific structure; they do not relax every
gate at once.
Pass 1: represent the problem¶
| Solver path | Problem shape and declaration | Constraint shape | Main tradeoff |
|---|---|---|---|
GridSearch + Regime | General discrete-continuous action product | Ordinary callable constraints | Broadest representation; cost grows with the full action product |
EGM + ConsumptionSavingsRegime | Smooth, concave, one-state/one-action cash-on-hand problem | Declared savings lower bound only | Fastest and simplest EGM route; very narrow contract |
DCEGM + ConsumptionSavingsRegime | One liquid Euler margin with a genuine resources node and optional discrete choice | Intrinsic budget and declared savings lower bound; EV1 supported | Off-grid Euler inversion plus an upper envelope; envelope work and simulation re-decision matter |
NBEGM + ConsumptionSavingsRegime | One liquid margin with supported declared kinks, jumps, hard boundaries, or smooth discrete branches | Supported structured boundary declarations; no EV1 taste shocks | Preserves topology that ordinary DCEGM cannot; more validation and candidate geometry |
NEGM + NestedConsumptionSavingsRegime | A DCEGM liquid solve conditional on a finite outer candidate grid | Inner DCEGM contract plus declared outer roles; no EV1 shocks | Exact relative to the outer candidate set; work scales with its size |
NNBEGM + NestedConsumptionSavingsRegime | An NBEGM liquid solve inside a finite or adaptive outer search | Inner NBEGM contract plus a supported outer search; no EV1 | Handles both declared inner boundaries and an outer margin; highest structural and computational cost |
Use GridSearch for genuinely coupled multi-dimensional choices, unsupported
constraints, or any problem whose required structure cannot be declared honestly. It is
also the baseline against which specialized solutions should be checked.
GridSearch work still covers the full represented action support. Eligible JIT solve-value routes evaluate bounded C-order action blocks. Same-period value references, gated-target continuations, and edge-reference mappings are declared as exact target artifacts and source argument paths. The engine either preserves an already aligned layout or explicitly copies a supported input onto the source core’s mesh, using the same plan during lowering and runtime. Ordinary co-mapped state routes also stream while preserving device-local continuation reads. Eligible singleton folded-state routes stream the action product at each shock node and then apply the unchanged quadrature over the full fold-node axis. The classifier deliberately keeps co-map intersections with separate same-period or edge-reference channels, trivial action products, JIT-disabled and raw execution, and all simulation-policy construction dense. Those dense or otherwise unplanned consumers stay conservatively pinned; current liveness bookkeeping does not release, donate, or offload their arrays. Collective EV1, EV1 with a fold, collective hard max with a fold, and EV1 without a discrete action are unsupported by the streamed program. See the canonical GridSearch route matrix. Treat the blockwise route as an execution detail until runtime and peak-memory effects have been measured for the model and hardware at hand.
The EGM routes require named liquid roles. Nested routes add named outer roles. Institutional kinks and cliffs must be declared as case pieces or a piecewise-affine schedule from the outset.
Plan phase topology before choosing NNBEGM. Simulation replays the candidate bank
ranked during the solve, so a bare declaration or Phased(solve=f, simulate=f) is
accepted only when f is the exact same callable object in both fields. Genuine phase
variation and carried-only states are rejected during Model(...) construction. See
NNBEGM replay capability.
If the discrete choice has EV1 taste shocks, choose GridSearch or DCEGM. NEGM
cannot move its outer durable search inside every taste-shocked discrete branch, while
NBEGM and NNBEGM publish hard-maximum carries. All three reject the declaration
rather than silently changing the model.
Read Consumption-saving regimes and margins and Declared non-convex budgets before authoring those models.
Pass 2: decide whether specialization pays¶
Among correct representations, compare:
candidate growth: action products for grid search; savings nodes, branches, stochastic nodes, and outer candidates for EGM-family methods;
source-level execution shape: bounded action blocks on eligible singleton and collective hard-max and singleton EV1 JIT solve-value GridSearch routes; dense GridSearch fallbacks and simulation-policy construction; streamed envelope/outer batches in structural solvers;
measured peak memory: bounded source-level blocks do not establish device peak; measure compiler and runtime memory for the exact model and profile;
compilation: number and size of distinct JAX programs;
hardware: dense static work often favors GPUs; sequential topology scans often favor CPUs;
accuracy: grid spacing, interpolation, boundary ownership, and approximation profiles;
workflow: one solve, repeated estimation, or repeated simulation can amortize different fixed costs.
There is no universal break-even point. Benchmark the actual model and device. See Scaling, memory, and hardware for the reasoning and Performance and memory tuning for the workflow.
Solver summary¶
| Solver | Represents | Main numerical configuration |
|---|---|---|
GridSearch | Broad discrete-continuous problems | No solver-specific fields |
EGM | Smooth one-margin cash-on-hand problem | Savings grid |
DCEGM | Genuine resources or supported extra dimensions on one liquid margin | Savings grid, envelope, refinement/batching |
NEGM | DCEGM inner solve conditional on a finite outer grid | Inner solver, outer grid, batch size |
NBEGM | Declared liquid kinks, jumps, hard boundaries, or discrete branches | Savings grid, jump read, comparison and batching controls |
NNBEGM | Nested outer choice with inner NBEGM | Inner solver, outer search, batch size |
Exact constructors and limitations are in Solvers and capabilities.
Constraints do not all need Condition¶
Use an ordinary callable when pylcm only needs the Boolean result. Use a structured
Condition when a solver must retain named comparisons to prove, compile, or precisely
refuse a constraint—or when that declaration is clearer. A Condition does not grant a
solver support it otherwise lacks.
The syntax and solver interaction live on the separate Constraints and structured Conditions page. Case pieces and piecewise-affine schedules are separate declarations for budget structure, not alternative constraint syntax.
Verify the choice¶
Before trusting a specialized route:
solve a reduced version with
GridSearch;compare values and discrete decisions, not only absence of NaNs;
inspect borrowing corners and every declared boundary from both sides;
repeat at both supported numerical precisions where relevant;
measure cold compile, warm execution, and peak memory;
document which approximation profile and hardware produced the result.
Use log_level="debug" while developing the model so structural and numerical
validation fails loudly.