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.

Regimes

A regime is a phase of life with its own utility function, states, actions, and constraints. Models have at least one terminal regime, and usually non-terminal ones.

For how functions and dependency wiring work inside a regime, see Write Economics, Not Glue Code. This page covers the regime-level features:

  • Regime anatomy — what each field does

  • Terminal vs non-terminal regimes

  • Transitions — regime and state (overview; full reference in Transitions)

  • Where a regime is solved

Choose the regime family together with the solver. Regime is the general GridSearch declaration. EGM-family models use ConsumptionSavingsRegime or NestedConsumptionSavingsRegime so liquid and outer roles are named from the outset. A collective household remains a Regime with stakeholders and currently uses GridSearch; see the collective example.

Regime Anatomy

A Regime is defined by these fields:

FieldTypePurpose
statesdict[str, Grid]State variable grids — pure outcome-space definitions.
state_transitionsdict[str, Callable | StochasticTransition | dict]How states evolve over time. Values are callables, StochasticTransition-wrapped callables, per-target dicts keyed by target regime name, or fixed_transition(state_name) for fixed states.
actionsdict[str, Grid]Choice variables with grids.
functionsdict[str, Callable]Must include "utility"; can include auxiliary functions.
constraintsdict[str, Callable]Feasibility constraints on state-action combinations.
descriptionstrOptional description string.

A regime does not declare where it goes next. Its outgoing edges, and the law that chooses among them where there are several, live in Model(edges=...); see Transitions below.

A states grid and a functions/constraints entry are ordinarily the same object for every period the regime is solved — a Regime is declared once, not per period. See Age-specialized functions and grids for loosening this: a function’s closure or a continuous state’s grid bounds can be made to vary with age (e.g., a tax-transfer system pinned to a policy date, or an age-dependent borrowing limit).

A state that never changes gets the identity law via fixed_transition:

from lcm import fixed_transition

state_transitions={
    "wealth": next_wealth,
    "education": fixed_transition("education"),  # education stays fixed
}

Terminal vs Non-Terminal Regimes

  • Terminal regime: no outgoing edges in Model(edges=...). The value function equals the utility function directly — there is no continuation value.

  • Non-terminal regime: has outgoing edges — a single destination per source age, or a Transition whose law chooses among several. pylcm uses the resolved Koopmans aggregator, which combines utility with the certainty equivalent of continuation:

W(ut,CEt+1,β)=ut+β CEt+1W(u_t, CE_{t+1}, \beta) = u_t + \beta \, CE_{t+1}

LinearAggregator() is the default Koopmans form and LinearExpectation() is the default certainty equivalent. With CEt+1=E[Vt+1]CE_{t+1}=E[V_{t+1}], together they give the recursion shown above. For the full Epstein-Zin recursion, pair CESAggregator() with PowerMean(); the CES form alone does not define Epstein-Zin preferences.

A terminal regime provides the boundary condition for the dynamic programming problem — it is the last period’s value function. Note that the last period can vary across agents, for example through stochastic mortality. A terminal regime does not mean the agent stays in this regime forever (that would be an absorbing regime, which is non-terminal with a self-loop transition).

Common uses:

  • Simple retirement: one period where the agent consumes all remaining wealth

  • Death: terminal utility is zero or determined by a bequest function — see the three-regime example in Write Economics

State transitions: {}
Utility function: utility_retirement

Transitions

Regimes define two kinds of transitions:

  • Regime transitions (declared in Model(edges=...), not on the regime) — which regime does the agent enter next period? A source with one destination at each source age is a plain {target: source_ages} mapping: the graph is the law. A source with several destinations at some age is a Transition(targets=..., law=...), whose law is a bare callable (deterministic, returns a regime ID), a StochasticTransition (stochastic, returns probabilities over all regimes), a per-target dict supplying scalar destination probabilities, or ByAge of these. A regime with no outgoing edges is terminal.

  • State transitions (state_transitions field) — how do individual state variables evolve? Supports deterministic functions, fixed states (fixed_transition), stochastic transitions (StochasticTransition), and per-target dicts for cross-regime transitions.

See Transitions for the full reference with examples.

Where a Regime Is Solved

A regime’s edges in Model(edges=...) declare where it can go from each source age; they do not decide where the regime is solved:

  • a regime with no outgoing edges is terminal and available at every age;

  • a regime with outgoing edges supplies a problem only at the source ages its edges select.

The solved problems are derived from the model’s required initial_nodes: every root, every problem a history can reach from it, and every value those problems read. Each demanded nonterminal problem needs an edge, and each declared target must be available at the next age. A regime that is left at a fixed age stops its self-edge there:

edges = {
    # Working life: stay or retire before 64; at 64 retirement is the only edge,
    # landing in retirement at 65, and `next_regime` must return it there.
    "working_life": Transition(
        targets={
            "working_life": AgeRange(start=25, exclusive_stop=64),
            "retirement": AgeRange(start=25, exclusive_stop=65),
        },
        law=DeterministicTransition(func=next_regime),
    ),
    # Retirement: no outgoing edges, so terminal and evaluated wherever demanded.
}

Example: Assembling Regimes into a Model

A minimal two-regime model to show the full assembly. For the economic functions and DAG wiring, see Write Economics. For model construction details, see Defining Models.

Regimes: ['working_life', 'retirement']
Periods: 3
Terminal: ['retirement']