SolvedModel
SolvedModel contains the policy/transition matrices and relevant methods.
Fields:
| Name | Type | Description |
|---|---|---|
| compiled | CompiledModel |
The compiled model object that resulted in the current solution. |
| policy | linearsolve.model |
Solver backend output (e.g., stability diagnostics, eigenvalues, raw solver objects). |
| A | np.ndarray |
The discovered state-transition matrix. |
| B | np.ndarray |
The discovered innovation impact matrix. |
Properties:
| Name | Type | Description |
|---|---|---|
| config | ModelConfig |
Parsed model configuration object. |
| kalman_config | KalmanConfig \| None |
Parsed Kalman Filter configuration object. |
Methods:
SolvedModel.sim(
T: int,
shocks: dict[str, Callable | np.ndarray], # (1)!
shock_scale: float = 1.0, # (2)!
x0: np.ndarray | None = None,
observables: bool = False
) -> dict[str, np.ndarray[float]]
- The dictionary keys can be populated by:
- An array of shocks
(T, 1) | (T,)when shocks are for a single variable and(T, K)when drawing correlated shocks simultaneously. - A callable accepting either a shock standard deviation (sigma) or a covariance matrix depending on univariate or multivariate requirements. The callable should return arrays shaped as described above. Per-step generators are not supported.
- Shocks are drawn from the specified distribution and all elements in the arrays are scaled by this parameter.
Returns the simulated path defined by the given inputs.
Univariate Shock Syntax
A univariate shock is defined as a dictionary entry for the given variable. For example, if a model specifies a variable x
and a shock symbol e_x, the dictionary would expect {"x": ...} where ... is populated by a ndarray of shape
(T,) or (T,1), or by a univariate generator callable.
Correlated Shock Syntax
To define a set of variables with nonzero shock covariance, a shared dictionary entry should be used. For example, a multivariate
shock to x and y should be defined as {"x,y": ...} where ... is populated by a (T, 2) array or a multivariate
generator callable.
Details regarding the dictionary key scheme:
- Variable names are parsed by splitting on commas; surrounding whitespace is stripped.
- Multiple variables can be chained as required. There is no variable count limitation.
- The ordering of variables in the key does not affect simulation results.
- Shock realizations are always aligned with the innovation ordering defined at model configuration or compilation (
Bmatrix order).
Multivariate Shock Canonicalization and Reproducibility
When multivariate shock generators are used, variables are internally reordered to a canonical model-defined order before sampling.
This ensures that simulations are reproducible under a fixed random seed, regardless of the order in which variables are specified
in the shock dictionary key (e.g. "g,z" vs "z,g").
This behavior is required because multivariate sampling methods (e.g. Cholesky-based Gaussian draws) are order-dependent at the realization level, even when the underlying covariance structure is permutation-invariant.
Concretely:
- Correlation and covariance matrices are constructed after canonicalizing variable order.
- Sampling is performed in this canonical order.
- Shock realizations are then mapped to the correct innovation indices used by the model.
As a result, variable ordering in multivariate shock keys does not affect either the statistical properties or the realized sample paths of the simulation when the random seed is fixed.
Custom Shock Generators
While it is technically possible to replicate the internal generator factory’s behavior, this is strongly discouraged.
Custom shock distributions and array manipulations are supported via the Shock class (see the docs).
Bypassing the shock interface may lead to unexpected or unstable behavior.
Inputs:
| Name | Description |
|---|---|
| T | Amount of steps to simulate the paths; excluding x0. |
| shocks | Array or callable generator of shocks keyed by their corresponding variable. |
| shock_scale | Scaling factor for the shocks. |
| x0 | Initial state of model variables shaped (n,). (None defaults to zeroes) |
| observables | Include observable paths in the output dict if True. |
Period Specification
Index 0 of the output will always be an initial state. (default or specified) The input T will result on T+1 array indices from index 0 to T.
Returns:
| Type | Description |
|---|---|
dict[str, np.ndarray[float]] |
Arrays of paths paired with their corresponding variables. The key "_X" contains the full state matrix. (Shape (T+1, n)) |
SolvedModel.irf(
shocks: list[str],
T: int,
scale: float = 1.0,
observables: bool = False
) -> dict[str, np.ndarray[float]]
Returns the IRF paths with shocks to specified variable(s).
Inputs:
| Name | Description |
|---|---|
| shocks | List of variables to receive shocks. |
| T | Time period of the IRF. |
| scale | Shock scaling factor. |
| observables | Include observables in the output if True. |
Returns:
| Type | Description |
|---|---|
dict[str, np.ndarray[float]] |
The paths simulated for the IRF. Mirrors the return of SolvedModel.sim with a specific shock configuration. |
SolvedModel.transition_plot(
T: int,
shocks: list[str],
scale: float = 1.0,
observables: bool = False
) -> None
Inputs:
| Name | Description |
|---|---|
| T | Time index to simulate. |
| shocks | List of variables to shock. |
| scale | Shock scaling factor. |
| observables | Include observables in the plot if True. |
Returns:
| Type | Description |
|---|---|
None |
Displays a plot of the paths created by a given config. |
SolvedModel.kalman(
y: ndarray | DataFrame,
filter_mode: Literal['linear', 'extended'] = 'linear',
*,
observables: list[str] | None = None, # (1)!
x0: ndarray | None = None, # (2)!
p0_mode: Literal['diag', 'eye'] | None = None, # (3)!
p0_scale: float | None = None, # (4)!
jitter: float | None = None, # (5)!
symmetrize: bool | None = None, # (6)!
return_shocks: bool = False,
estimate_R_diag: bool = False,
R_scale: float = 1.0,
_debug: bool = False
) -> FilterResult
None: Usey_namesfromKalmanConfig. If is not specified, use all observables.None: Use a zero vector.None: UseP0.modefromKalmanConfig. If this resolves to'diag',P0.diagmust be present.None: UseP0.scalefromKalmanConfig. IfP0.scaleis not specified, use '1.0'.None: UsejitterfromKalmanConfig. Ifjitteris not specified, use '0.0'.None: UsesymmetrizefromKalmanConfig. Ifsymmetrizeis not specified, use 'False'.
Run a Kalman Filter application on the observables specified.
y Array Alignment
When a DataFrame is used as y, column names will be used to align and order observables' names and position. However, for ndarray inputs, the method assumes names in observables and columns of y are position-aligned.
Inputs:
| Name | Description |
|---|---|
| y | observations to filter. |
| filter_mode | "linear" for affine measurements, "extended" for nonlinear measurements. |
| observables | Name of corresponding model measurements. |
| x0 | Initial state vector. |
| p0_mode | Generation strategy for \(P_0\). diag uses values given in the config (diag_mat * scale) and eye uses (np.eye(n) * scale) |
| p0_scale | Scaling factor for the \(P_0\) matrix. |
| jitter | Jitter term added to matrices when Cholesky fails. |
| symmetrize | Symmetrize covariances at each filter pass if True. |
| return_shocks | Include the estimated shocks in the return object if True. |
| estimate_R_diag | If True, estimate a diagonal R by MLE before running the filter. |
| R_scale | Post-estimation multiplicative scaling applied to R when estimate_R_diag=True. |
| _debug | Print debug information about filter inputs if True. |
Returns:
| Type | Description |
|---|---|
FilterResult |
dataclass containing information on filter state, measurements, and diagnostics. |
SolvedModel.fit_kf(
y: ndarray | DataFrame,
observable: str,
template_config: TemplateConfig,
sr_params: PySRParams,
variables: list[str] | None = None, # (1)!
) -> FitResult
None: Use all compiled model variables as symbolic-regression inputs.
Fit a symbolic regression model to Kalman Filter output for a selected observable.
Regression Target
Internally, the method first runs SolvedModel.kalman(...) using the model's observable set. If template_config.include_expression=True, the regression target is the predicted measurement for observable; otherwise the target is the observable's Kalman innovation.
Inputs:
| Name | Description |
|---|---|
| y | Observation data passed through the Kalman filter stage before symbolic regression. |
| observable | Observable name whose filter output should be fit. |
| template_config | Template-expression configuration used to build the symbolic-regression search space. |
| sr_params | Symbolic-regression backend hyperparameters. |
| variables | Optional subset of model variables to expose as regression inputs. |
Returns:
| Type | Description |
|---|---|
FitResult |
Regression fit output containing all candidate expressions and the best-ranked symbolic approximation. |
Dictionary representation of the class instance.
Inputs:
None
Returns:
| Type | Description |
|---|---|
dict[str, Any] |
Dictionary representation of the SolvedModel object. |