Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Choosing a solver

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:

  1. keep only solvers whose assumptions represent the economic problem;

  2. 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:

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 pathProblem shape and declarationConstraint shapeMain tradeoff
GridSearch + RegimeGeneral discrete-continuous action productOrdinary callable constraintsBroadest representation; cost grows with the full action product
EGM + ConsumptionSavingsRegimeSmooth, concave, one-state/one-action cash-on-hand problemDeclared savings lower bound onlyFastest and simplest EGM route; very narrow contract
DCEGM + ConsumptionSavingsRegimeOne liquid Euler margin with a genuine resources node and optional discrete choiceIntrinsic budget and declared savings lower bound; EV1 supportedOff-grid Euler inversion plus an upper envelope; envelope work and simulation re-decision matter
NBEGM + ConsumptionSavingsRegimeOne liquid margin with supported declared kinks, jumps, hard boundaries, or smooth discrete branchesSupported structured boundary declarations; no EV1 taste shocksPreserves topology that ordinary DCEGM cannot; more validation and candidate geometry
NEGM + NestedConsumptionSavingsRegimeA DCEGM liquid solve conditional on a finite outer candidate gridInner DCEGM contract plus declared outer roles; no EV1 shocksExact relative to the outer candidate set; work scales with its size
NNBEGM + NestedConsumptionSavingsRegimeAn NBEGM liquid solve inside a finite or adaptive outer searchInner NBEGM contract plus a supported outer search; no EV1Handles 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:

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

SolverRepresentsMain numerical configuration
GridSearchBroad discrete-continuous problemsNo solver-specific fields
EGMSmooth one-margin cash-on-hand problemSavings grid
DCEGMGenuine resources or supported extra dimensions on one liquid marginSavings grid, envelope, refinement/batching
NEGMDCEGM inner solve conditional on a finite outer gridInner solver, outer grid, batch size
NBEGMDeclared liquid kinks, jumps, hard boundaries, or discrete branchesSavings grid, jump read, comparison and batching controls
NNBEGMNested outer choice with inner NBEGMInner 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:

  1. solve a reduced version with GridSearch;

  2. compare values and discrete decisions, not only absence of NaNs;

  3. inspect borrowing corners and every declared boundary from both sides;

  4. repeat at both supported numerical precisions where relevant;

  5. measure cold compile, warm execution, and peak memory;

  6. document which approximation profile and hardware produced the result.

Use log_level="debug" while developing the model so structural and numerical validation fails loudly.