pymc_forecast.markov#

Markov (state-space) time-series latents via pytensor.scan.

The scan analogue of time_series(): in-sample steps run in one scan-backed pm.CustomDist under the base name; when forecasting, horizon steps run in a second scan-backed CustomDist named {name}_future whose initial state is the final in-sample value — so under posterior replay the forecast is conditioned through the state, exactly upstream’s “seeded by the final carry” invariant.

This follows PyMC’s documented pattern for time series derived from a generative graph (CustomDist + scan + collect_default_updates), which is also what makes the in-sample latent’s logp derivable for NUTS/ADVI. Two constraints follow from it:

  • every random parameter used by the transition must be passed via params= (PyMC needs them as explicit inputs of the generative graph);

  • the transition returns a distribution for the next step (pm.Normal.dist(...)), not a sample — the wrapper owns the randomness, so the Markov structure cannot be broken by user resampling.

pymc_forecast.markov.markov_time_series(h, name, init, transition, *, params=(), xs=None, dims=())[source]#

Sample a Markov latent over the full horizon.

Parameters:
  • h – The horizon of the current model build.

  • name – Base variable name of the in-sample latent; the forecast segment is named f"{name}_future".

  • init – Initial state fed to the first transition — a constant or a model variable (e.g. pm.Normal("z0", 0, 1)).

  • transition(z_prev, *params) -> dist (with xs: (z_prev, x_t, *params) -> dist). Must return a .dist() distribution for the next step.

  • params – Every random variable the transition uses (beyond the state), passed as explicit generative-graph inputs. Deterministic constants may be closed over freely.

  • xs – Optional exogenous inputs over the full horizon, time on axis 0 (numpy array or DataArray).

  • dims – Extra (non-time) dims of the per-step state, e.g. ("series",).

Returns:

TensorVariable – The latent over the full horizon, time on axis 0.

Raises:

HorizonError – When forecasting without observed data, or when xs does not span the full horizon.