SV.sample#

SV.sample(*, method='gibbs', n_draws=5000, n_burn=1000, thin=1, n_particles=500, prior=None, seed=None)[source]#

Sample the posterior.

Both samplers use the same prior: Gaussian mu ~ N(m, v), Beta (phi + 1) / 2 ~ Beta(a, b) (the Kim-Shephard-Chib default (20, 1.5) puts the persistence near 0.86 a priori), inverse-gamma sigma2 ~ IG(shape, rate). The Gibbs sampler replaces \(\log \varepsilon_t^2\) by a seven-component normal mixture and draws the log-variance path exactly by simulation smoothing; the particle sampler targets the exact posterior through a particle estimate of the likelihood, so the two should agree, and a disagreement is the diagnostic that the mixture is binding.

Parameters:
  • method (str) – "gibbs" for the Kim-Shephard-Chib mixture sampler, "particle" for particle marginal Metropolis-Hastings.

  • n_draws (int) – Total iterations.

  • n_burn (int) – Burn-in discarded (the particle chain adapts its proposal during burn-in).

  • thin (int) – Keep every thin-th post-burn draw.

  • n_particles (int) – Particles per likelihood estimate under "particle".

  • prior (_VolatilityPrior | None) – VolatilityPrior instance; the Kim-Shephard-Chib defaults when None.

  • seed (int | None) – Seed.

Return type:

_SVPosterior

Returns:

The posterior record, with per-parameter draws, the posterior mean log-variance path and the convergence diagnostics.

Raises:

SpecificationError – If the method is unknown or the draw bookkeeping is inconsistent.

Example

>>> import numpy as np
>>> from cultivars.engine._internals._simulators import _simulate_stochastic_volatility
>>> rng = np.random.default_rng(0)
>>> y, h = _simulate_stochastic_volatility(
...     500, mu=-1.0, phi=0.95, sigma2=0.05, mean=0.0, rng=rng
... )
>>> post = SV(y, mean="zero").sample(n_draws=400, n_burn=100, seed=0)
>>> post.method, post.n_kept, post.phi_draws.shape
('gibbs', 300, (300,))
>>> bool(abs(post.phi_draws.mean() - 0.95) < 0.05)
True
>>> bool(np.corrcoef(post.log_variance, h)[0, 1] > 0.7)
True
>>> SV(y).sample(n_draws=100, n_burn=200)
Traceback (most recent call last):
    ...
cultivars.exceptions.SpecificationError: n_draws (100) must exceed n_burn (200).