Skip to content

IndependentNIW

The IndependentNIW model implements Bayesian VAR estimation with independent Normal-Inverse-Wishart priors. Unlike the natural-conjugate specification, the prior on the VAR coefficients is independent of \(\Sigma\), which allows a richer \((nk \times nk)\) full-system prior covariance matrix whose inverse encodes cross-variable shrinkage scaling by \(\sigma_i / \sigma_j\).

Because the prior is not conjugate, the posterior has no closed form and the model uses a Gibbs sampler that alternates between drawing \(\beta \mid \Sigma, Y\) and \(\Sigma \mid \beta, Y\). Burn-in draws are automatically discarded.

The public beta_point and sigma_point estimates come from the retained Gibbs draws, after burn-in. They are posterior means rather than posterior modes, and posterior_state_point references those same point arrays for forecasting with the full posterior state.

Note

IndependentNIW does not support marginal-likelihood optimisation, and its Gibbs sampler has no closed-form posterior point estimate, so optimisation_method="cross_validation" is not supported either (it requires refitting with point_only=True). Use optimisation_method="none" and set hyperparameters manually when constructing BVAR.

Constructor arguments (minnesota, soc, sur, covid, covid_dates) are documented on SamplingModel; soc and sur default to True.

Prior Structure

\[\beta \,\sim\, \mathcal{N}(\beta_0, V_\beta)\]
\[\Sigma \,\sim\, \mathcal{IW}(S_0, \nu_0)\]

where \(V_\beta\) is a full \((nk \times nk)\) covariance matrix. Its inverse is the prior precision used in the conditional posterior. The cross-variable off-diagonal blocks are scaled by a parameter c2 (Litterman, 1986), giving tighter shrinkage on cross-equation coefficients relative to own-equation coefficients. The Gibbs sampler iterates:

\[\beta \mid \Sigma, Y \;\sim\; \mathcal{N}\!\left(\tilde\beta,\; \tilde{V}\right), \qquad \tilde{V}^{-1} = V_\beta^{-1} + \Sigma^{-1} \otimes Z'Z\]
\[\Sigma \mid \beta, Y \;\sim\; \mathcal{IW}\!\left(S_0 + E'E,\; \nu_0 + T\right)\]

Hyperparameters

Parameter Description Default
c2 Cross-variable shrinkage 0.5
c1 Overall tightness 0.2
c3 Lag-decay exponent 2.0
mu SOC tightness (if soc=True) 1.0
theta SUR tightness (if sur=True) 1.0

Example

import bvar as bv

model = bv.IndependentNIW(
    c2=0.5,  # cross-variable shrinkage
    minnesota=True,
    soc=False,
    sur=False,
    covid=False,
)

# ML and cross-validation optimisation are not available; use "none"
bvar = bv.BVAR(n_lags=4, model=model, stationary=False, optimisation_method="none")
bvar.sample(data, N_draws=5000)

API

bvar.IndependentNIW

IndependentNIW(c2: float = 0.5, minnesota: bool = True, soc: bool = True, sur: bool = True, covid: bool = False, covid_dates: Optional[list] = None)

BVAR with independent Normal-Inverse-Wishart priors.

The prior is β ~ N(β₀, V_β) independently of Σ ~ IW(S₀, ν₀), where V_β is a full (nk, nk) precision matrix encoding cross-variable scaling σ_i / σ_j.

PARAMETER DESCRIPTION
c2

Cross-variable shrinkage (Litterman 1986 uses 0.5).

TYPE: float DEFAULT: 0.5

minnesota

Whether to use the Minnesota prior.

TYPE: bool DEFAULT: True

soc

Whether to use the sum-of-coefficients prior.

TYPE: bool DEFAULT: True

sur

Whether to use the single-unit-root prior.

TYPE: bool DEFAULT: True

covid

Whether to include COVID dummy observations.

TYPE: bool DEFAULT: False

covid_dates

Start and end dates for the COVID period.

TYPE: Optional[list] DEFAULT: None

ATTRIBUTE DESCRIPTION
requires_burnin

True — Gibbs draws require burn-in.

TYPE: bool

supports_ml

False — no closed-form marginal likelihood.

TYPE: bool

supports_point_only

False — the posterior has no closed-form point estimate, so optimisation_method="cross_validation" is not supported. Use "none" and set hyperparameters manually.

TYPE: bool

set_priors

set_priors(*, c2: float | None = None, **kwargs) -> None

Set prior hyperparameters including cross-variable shrinkage c2.

Also computes Gamma hyperprior parameters for c2.

fill_in_from_vector

fill_in_from_vector(pars: ndarray) -> None

Vector layout: [c1, c3, c2, mu?, theta?].

sample

sample(data: ndarray, n_lags: int, covid_indices: ndarray, vars_in_levels: ndarray, N_draws: int, point_only: bool = False, progressbar: bool = True, soc: Optional[bool] = None, sur: Optional[bool] = None, rng: Optional[Generator] = None) -> SamplingResult

Run the full independent-NIW Gibbs estimation pipeline.

PARAMETER DESCRIPTION
data

Input data array.

TYPE: ndarray

n_lags

Number of VAR lags.

TYPE: int

covid_indices

Indices for COVID dummy observations.

TYPE: ndarray

vars_in_levels

Indicators for variables in levels.

TYPE: ndarray

N_draws

Number of posterior draws.

TYPE: int

point_only

Whether to request a point estimate.

TYPE: bool DEFAULT: False

progressbar

Whether to display a progress bar.

TYPE: bool DEFAULT: True

soc

Effective sum-of-coefficients flag.

TYPE: Optional[bool] DEFAULT: None

sur

Effective single-unit-root flag.

TYPE: Optional[bool] DEFAULT: None

rng

Random number generator.

TYPE: Optional[Generator] DEFAULT: None

RETURNS DESCRIPTION
SamplingResult

Posterior draws and point estimates.

RAISES DESCRIPTION
ValueError

If point_only is True (no closed-form posterior point estimate).

sample_posterior_state

sample_posterior_state(Y: ndarray, Z: ndarray, current_state: PosteriorState, rng: Optional[Generator] = None) -> PosteriorState

Return the next Gibbs-sampled posterior state.

Performs one full Gibbs sweep (β|Σ then Σ|β) using the stored prior from the last call to :meth:sample. current_state.sigma seeds the sweep's covariance. The Gibbs kernel accepts current_state.beta for interface compatibility but ignores it; it samples β conditional on Σ within this sweep rather than carrying β forward.