Skip to content

0.3 Methodization (spec_0.1d): schemes, methods, settings

Methodization is the step that attaches numerical-method metadata to a syntactic stage without changing its mathematics.

It is a functor that lives in a Syntax Collection: it takes a stage plus a methodization config and returns a new stage object with metadata attached. In a model instance, the orchestration layer applies this common functor to each period-instance.


1. What methodization is (and is not)

1.1 Is

  • A pure attachment step: methodize(stage, methodization.yml, registry=None) returns a new stage with .methods populated.
  • A way to select how downstream solvers/compilers should treat parts of the model:
  • integration rules (expectation schemes)
  • backward-solution algorithms (e.g. EGM vs other)
  • interpolation / grid / simulation choices
  • A bridge between SYM and the implementation-specific representation map \( \rho \): it is where representation choices live (e.g. “represent policy on continuation grid”).

1.2 Is not

  • Not a place to put numbers (numbers live in settings.yml and calibration.yml).
  • Not allowed to invent new targets (no synthetic implicit labels beyond the stage’s own labels and operator instances in equation text).
  • Not a change to equation bodies: methodization does not rewrite or reinterpret the mathematics; it only records metadata “on the side”.

2. File split and pipeline position

Per spec_0.1d, the split is:

  • stage.yml: symbols + equations (pure syntax)
  • methodization.yml: target → schemes/methods + wiring to symbols.settings
  • settings.yml: numeric values for settings symbols (grid sizes, tolerances, node counts, etc.)
  • calibration.yml: numeric economic parameters

Execution order:

Parse stage → Validate stage → Methodize → Calibrate → Apply settings → ρ/Solve

3. Target universe (what can be methodized)

The implementation constructs the set of valid “targets” from the stage itself. Targets come from two sources:

3.1 Stage labels and sub-labels (dot notation)

Extracted from equations::

  • Top-level labels: each key under equations: is targetable (e.g. cntn_to_dcsn_mover).
  • Sub-equations: if a mover is a mapping (one-level nested), each subkey becomes a dot-target:
  • cntn_to_dcsn_mover.Bellman
  • cntn_to_dcsn_mover.InvEuler
  • cntn_to_dcsn_mover.ShadowBellman

3.2 Implied forward movers (derived targets)

Implementation detail (and tested): for any *_transition label, we also add a corresponding implied forward mover label:

  • arvl_to_dcsn_transitionarvl_to_dcsn_mover
  • dcsn_to_cntn_transitiondcsn_to_cntn_mover

This provides an explicit hook for forward operations like simulation/distribution propagation even when the stage only declares the transition equality.

3.3 Operator instances extracted from equation bodies

Methodization can also attach schemes to operator instances that appear inside equation payloads.

Currently implemented operator instance extraction (v0.1d):

  • Expectation heads of the form E_{...}(...) become instance IDs:
  • E_{y}(...)E_y
  • E_{w,z}(...)E_w_z

This is how “expectation location” becomes methodizable: you attach a quadrature/sampling scheme to E_y rather than to an entire mover label.


4. The methodization table and “exhaustive surface”

Important: the set of schemes should be such that there is faithful mapping to the set of computational operations that need to be performed and the approximate objects produced.

methodization.yml authoring surface (canonical v0.1d) is:

methods:
  - on: <target-id>
    schemes:
      - scheme: <registered-scheme-name>
        method: <opaque tag or string>
        settings: { <option_key>: <settings_symbol>, ... }

Implementation behavior matches the spec’s “exhaustive listing” rule:

  • You may author only some targets.
  • The methodization step expands to an exhaustive table over all stage targets and operator instance targets:
  • any missing target is filled with schemes: [].

The attached representation is stored in two forms on the returned stage:

  • stage.methods: dict {target_id: entry}
  • stage.methods_list: ordered list of entries (stable order)

5. Schemes vs methods vs settings (concrete runtime meaning)

This is the only semantics v0.1d needs:

  • scheme: the registered category of numerical task (expectation, bellman_backward, interpolation, grid, simulation, …)
  • Optional registry validation warns if a scheme name is unknown.
  • method: an opaque selection inside a scheme, preserved from YAML (often as a YAML tag like !egm or !gauss-hermite)
  • Never registry-gated at v0.1d.
  • Implementation preserves tags rather than interpreting them.
  • settings: maps scheme option keys to settings symbol names (strings)
  • Numeric values are resolved later from settings.yml.
  • Implementation warns if a referenced settings symbol is not declared in symbols.settings in the stage.

6. Implementation notes (what actually happens in code)

The packages/dolo implementation lives in dolo/compiler/methodization.py and follows the spec closely:

  • Target extraction:
  • extract_stage_targets(stage) gathers equation labels + dot-sublabels and adds implied forward movers for *_transition.
  • extract_operator_instances(stage) scans equation text for E_{...}( patterns to produce E_* instance IDs.
  • Config loading:
  • load_methodization(...) preserves YAML tags and normalizes the on: key (important because YAML 1.1 may parse on as boolean True; the loader fixes this).
  • Functor behavior:
  • methodize(...) does not mutate the original stage; it shallow-copies and attaches _methods / _methods_list.
  • Validation:
  • Duplicate targets error.
  • Unknown targets warn by default (or error if strict=True).
  • Unknown schemes warn if a registry is provided.
  • Unknown settings symbols warn.

7. Worked example: consumption–savings IID (EGM)

In packages/dolo/examples/models/doloplus/consumption_savings_iid_egm_doloplus/methodization.yml, you can see all three target types:

  • Operator instance: E_y gets an expectation scheme with !gauss-hermite and n_nodes: n_y_nodes.
  • Backward mover: cntn_to_dcsn_mover gets:
  • bellman_backward with method !egm
  • interpolation with method !Cartesian plus grid/bounds/domain settings wired to symbols.settings.
  • Forward mover hook: arvl_to_dcsn_mover (implied from arvl_to_dcsn_transition) gets a simulation scheme with !monte-carlo.

The stage's math stays unchanged; methodization only records how to execute/represent those operations.

8. Composability of schemes and method recipes

The registered schemes (expectation, bellman_backward, grid, interpolation, maximization, simulation, upper_envelope) are mix-and-match building blocks. The user combines them freely on a target to describe a complete solution method. For example, a VFI stage might combine bellman_backward: !vfi + grid: !Cartesian + interpolation: !linear + maximization: !scipy-bounded, while an EGM stage uses bellman_backward: !egm + interpolation: !Cartesian with no maximization at all.

The combination of schemes on a stage's targets constitutes the solution method specification — it tells the whisperer/solver what computational operations to perform and what approximate objects to produce.

Method recipes (post-Feb 2026)

A future milestone will define a set of method recipes: named, standard combinations of schemes that describe common solution procedures (e.g. "standard VFI", "EGM with upper envelope", "pure expectation"). Each recipe will provide a concrete map from the stage's equation AST to the set of compiled operations — but not the implementation itself. Recipes are a convenience layer: they pre-fill the methodization table with a known-good combination of schemes, methods, and settings for a given solution approach. The user can always override individual scheme entries or author the full methodization table directly.

See the Method Schemes Reference for the complete registry of scheme names, their targets, and worked examples.