Constant#

class impulso.volatility.Constant(*, name='constant', is_time_varying=False, sigma_sd_beta=2.5, tril_offdiag_sigma=0.5)[source]#

Bases: ImpulsoModel

Homoscedastic volatility — single Σ shared across all time points.

Lifts today’s manual-Cholesky parameterisation from spec.py:_build_pymc_model into the volatility-process seam: HalfCauchy(beta=sigma_sd_beta) on the diagonal scales, Normal(mu=0, sigma=tril_offdiag_sigma) on the lower-triangular off-diagonals (scaled by the row’s diagonal). For n_vars == 1 the off-diagonal block is empty.

The factor is assembled from primitives rather than with PyMC’s purpose-built LKJCholeskyCov / LKJCorr because those are broken on the dependency set Impulso supports — an einsum unpacking bug — so the obvious built-in is not an option here. See docs/adr/0014-manual-cholesky-parameterisation.md.

The PyMC variable names produced inside build_pymc_latent (sigma_sd, tril_offdiag) match today’s posterior contents exactly so existing identification and downstream code keep working unchanged. The Sigma = L @ L.T deterministic is registered by the caller in spec.py, not by the adapter.

Parameters:
name#

Discriminator key for the registry (always “constant”).

Type:

Literal[‘constant’]

is_time_varying#

Always False — Σ is shared across t.

Type:

bool

sigma_sd_beta#

HalfCauchy scale on diagonal SDs.

Type:

float

tril_offdiag_sigma#

Normal SD on off-diagonal correlation factors.

Type:

float

build_pymc_latent(n_vars, T, data=None)[source]#

Register the constant-volatility latent vars in the active PyMC model.

Lifts the manual-Cholesky parameterisation from the previous location in spec.py:_build_pymc_model. PyMC variable names (sigma_sd, tril_offdiag) match the prior contents byte-for-byte so existing posterior-consuming code keeps working unchanged.

Parameters:
  • n_vars (int) – Number of endogenous variables.

  • T (int) – Number of observations after lag trimming. Ignored for constant volatility — kept in the signature for parity with stochastic adapters.

  • data (ndarray | None) – Accepted for Protocol parity with stochastic adapters and ignored — Σ is data-independent in the constant case.

Returns:

Lower-triangular Cholesky factor L of shape (n_vars, n_vars).

Return type:

pt.TensorVariable

cholesky_at(posterior, t)[source]#

Return the lower-triangular Cholesky factor of Σ for every draw.

Reads posterior[“L”] directly — the factor is registered as a deterministic in build_pymc_latent so this method does not re-decompose Σ. For constant volatility, t is ignored.

Parameters:
  • posterior (xr.Dataset) – An xarray Dataset (typically idata.posterior) containing L of shape (chains, draws, n_vars, n_vars).

  • t (int | None) – Time index. Ignored.

Returns:

Cholesky factors of shape (chains, draws, n_vars, n_vars).

Return type:

ndarray

cholesky_path(posterior, T)[source]#

Broadcast the constant Cholesky factor across all in-sample t.

For constant volatility there is no per-t variation; this is a broadcast convenience for the IdentifiedVAR query layer.

Parameters:
  • posterior (xr.Dataset) – An xarray Dataset containing L of shape (chains, draws, n_vars, n_vars). Read via Constant.cholesky_at, which is the canonical accessor.

  • T (int) – In-sample length (after lag trimming).

Returns:

Cholesky factor path of shape (chains, draws, T, n_vars, n_vars).

Return type:

ndarray

forecast_cholesky_path(posterior, steps, rng)[source]#

Broadcast the constant Cholesky factor across forecast steps.

For constant volatility there is nothing to simulate — the forecast covariance equals the in-sample covariance. rng is accepted for signature parity with stochastic adapters and is ignored.

Parameters:
  • posterior (xr.Dataset) – An xarray Dataset containing L of shape (chains, draws, n_vars, n_vars). Read via Constant.cholesky_at, which is the canonical accessor.

  • steps (int) – Forecast horizon.

  • rng (Generator) – Unused.

Returns:

Cholesky factor path of shape (chains, draws, steps, n_vars, n_vars).

Return type:

ndarray

model_config = {'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].