HierarchicalBVARResult.stable_share#

property HierarchicalBVARResult.stable_share: float[source]#

Posterior probability that the system is stable.

The share of retained draws whose companion matrix \(F^{(s)}\), built from that draw’s lag stack, has spectral radius strictly below one,

\[\Pr(\text{stable} \mid Y) \approx \frac{1}{S} \sum_{s=1}^{S} \mathbf{1}\bigl\{\rho(F^{(s)}) < 1\bigr\},\]

a Monte Carlo estimate with standard error \(\sqrt{q(1 - q) / S}\). Stability is the condition under which the moving-average representation converges, so it is the condition for irf() to die out and for the predictive of forecast_paths() to have finite variance at long leads.

Under a random-walk-centred prior this is routinely well below one on persistent data, and that is information about the posterior, not a defect: the prior puts mass at the unit root, the sample rarely rules it out, and draws just past it are what the posterior looks like there. A low value says long-horizon responses and forecasts carry explosive draws and should be read with that in mind, or that the series should be differenced or the prior centred at zero. It is reported on the summary. Costs one eigendecomposition of a (kp, kp) matrix per draw and is recomputed on every access; with order zero it is one.

Example

>>> import numpy as np
>>> from cultivars.multivariate.large_dim.bayesian import BVAR
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((120, 2))
>>> for t in range(1, 120):
...     y[t] = 0.7 * y[t - 1] + rng.standard_normal(2)
>>> BVAR(y, order=1).fit(n_draws=200, seed=0).stable_share
1.0

On random walks the random-walk prior keeps posterior mass past the unit circle:

>>> walks = rng.standard_normal((120, 2)).cumsum(axis=0)
>>> bool(BVAR(walks, order=1).fit(n_draws=200, seed=0).stable_share < 1.0)
True

See also

  • persistence – the prior mean of each own first lag; zero centres the prior on stationarity.