pymc_forecast.markov#
Scan-based state latents are markov_series. There is no advance argument.
Markov (state-space) time-series latents via pytensor.scan.
The scan analogue of innovations(): 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_series(h, name, init, transition, *, params=(), xs=None, dims=())[source]#
Sample a Markov latent over the full horizon.
- Parameters:
h (
pymc_forecast.model.Horizon) – The horizon of the current model build.name (
str) – Base variable name of the in-sample latent; the forecast segment is namedf"{name}_future".init (
float,array_likeorpytensor.tensor.TensorVariable) – Initial state fed to the first transition — a constant or a model variable (e.g.pm.Normal("z0", 0, 1)). Cast to float64 inside the scan.transition (
callable) –(z_prev, *params) -> dist(withxs:(z_prev, x_t, *params) -> dist). Must return a.dist()distribution for the next step.params (
sequence, default()) – Every random variable the transition uses (beyond the state), passed as explicit generative-graph inputs. Deterministic constants may be closed over freely.xs (
array_like, optional) – Exogenous inputs, purely positional: time on axis 0 (any array-like, or an object with.valuessuch as aDataArray, whose dim names and coords are ignored), cast to float64. Must have at leasth.durationrows; extra rows are ignored.Nonemeans no inputs.dims (
tupleofstr, default()) – Extra (non-time) dims of the per-step state, e.g.("series",).
- Returns:
pytensor.tensor.TensorVariable– The latent over the full horizon, time on axis 0. Whenh.future == 0this is the registered model variablenameitself; otherwise it is an unnamed concatenation ofnameand{name}_future.- Raises:
pymc_forecast.exceptions.HorizonError – If forecasting (
h.future > 0) without observed data, or ifxshas fewer thanh.durationrows along axis 0.