STVARResult#
- class cultivars.multivariate.nonlinear.smooth_transition.STVARResult(*, endog, names, order, trend, delay, threshold, threshold_name, threshold_values, transition_series, lower_coefficients, upper_coefficients, lower_deterministic, upper_deterministic, resid, fittedvalues, llf, nobs, n_params, transition, gamma, transition_scale, sigma_u)[source]#
A fitted smooth-transition vector autoregression.
The estimate of
\[y_t = (1 - G(z_t))\,\bigl(c_L + \textstyle\sum_{i} A_{L,i}\, y_{t-i}\bigr) + G(z_t)\,\bigl(c_U + \textstyle\sum_{i} A_{U,i}\, y_{t-i}\bigr) + u_t, \qquad z_t = s_{t-d},\]with the transition weight either logistic or exponential in the standardized distance from the threshold,
\[G(z) = \bigl(1 + e^{-\gamma (z - c)/\sigma_z}\bigr)^{-1} \quad\text{or}\quad G(z) = 1 - e^{-\gamma (z - c)^2/\sigma_z^2},\]estimated by concentrated maximum likelihood: given \((\gamma, c)\) the two regimes’ coefficients come from one weighted least-squares solve, and only the pair is searched on the log-determinant of the residual covariance. The record extends the observed-regime surface – the two coefficient stacks, regime-conditional
irf,fevd,ma_representationandforecast, the stability of each regime, and comparison by information criteria – with the transition’s own parameters and the single covariance the smooth form admits.Note
gammais reported per standard deviation of the transition variable; divide bytransition_scalefor the speed on the original scale. The logistic weight equals one half at the threshold and is monotone in \(z\), so the regimes are directional; the exponential weight equals zero at the threshold and one far from it on either side, so the “upper” regime is the tails and the “lower” regime the middle. The likelihood is nearly flat in \(\gamma\) once the weight is effectively an indicator, so a very large fittedgammais a lower bound rather than an estimate, andis_effectively_abruptsays when that has happened. Information criteria rank specifications but do not test for nonlinearity, because \((\gamma, c)\) are not identified under linearity. Standard errors are not yet available.- Variables:
transition –
"logistic"or"exponential".gamma – Transition speed, per standard deviation of the transition variable.
transition_scale – The standard deviation
gammais expressed against, retained so the weight path can be reproduced and sogammacan be read on the original scale.sigma_u – Common innovation covariance, dof-corrected. One covariance rather than two: smooth weights never partition the sample, so a per-regime covariance has no subsample to be estimated from.
See also
STVAR– the model that produces this record.TVARResult– the abrupt limit, with a covariance per regime.STARResult– the univariate counterpart, split into LSTAR and ESTAR.
References
Auerbach, A. J., & Gorodnichenko, Y. (2012). Measuring the output responses to fiscal policy. American Economic Journal: Economic Policy, 4(2), 1-27.
Terasvirta, T., & Yang, Y. (2014). Specification, estimation and evaluation of vector smooth transition autoregressive models with applications. CREATES Research Paper 2014-08.
Example
A bivariate system whose own-lag coefficient slides from 0.6 to -0.3 as a logistic function of
y1’s lag with speed 2 per unit; the fit recovers both regimes, a speed of the right size per standard deviation, and a weight path that spends a real share of the sample in between:>>> import numpy as np >>> rng = np.random.default_rng(1) >>> y = np.zeros((400, 2)) >>> for t in range(1, 400): ... g = 1.0 / (1.0 + np.exp(-2.0 * y[t - 1, 0])) ... a = (1.0 - g) * 0.6 + g * -0.3 ... y[t] = a * y[t - 1] + rng.standard_normal(2) >>> res = STVAR(y, order=1, transition_variable="y1").fit() >>> res.transition, res.delay, res.threshold_name, res.nobs, res.n_params ('logistic', 1, 'y1', 399, 17.0) >>> bool(1.0 < res.gamma < 3.0), bool(abs(res.threshold) < 0.5), res.is_effectively_abrupt (True, True, False) >>> lower, upper = np.diag(res.lower_coefficients[0]), np.diag(res.upper_coefficients[0]) >>> bool(np.all(np.abs(lower - 0.6) < 0.15)), bool(np.all(np.abs(upper + 0.3) < 0.25)) (True, True) >>> weight = res.regime_weight >>> between = np.mean((weight > 0.2) & (weight < 0.8)) >>> bool(0.2 < res.upper_fraction < 0.5), bool(between > 0.25) (True, True) >>> res.sigma_u.shape, bool(np.allclose(res._weight_at(np.array([res.threshold])), 0.5)) ((2, 2), True)
Attributes#
|
|
Transition speed per standard deviation of the transition variable. |
|
Standard deviation of the delayed transition variable, the unit of |
|
|
|
AIC, BIC, and HQIC derived from the likelihood and parameter count. |
|
Whether the fitted transition is so fast it is a hard threshold. |
|
Whether both regimes are stationary read as linear systems. |
|
Number of endogenous variables. |
|
Companion-eigenvalue verdict for the lower regime's lag stack. |
|
The transition function evaluated over the sample. |
|
Share of the effective sample carried by the upper regime. |
|
Companion-eigenvalue verdict for the upper regime's lag stack. |
Methods#
|
Rank this result against others by an information criterion. |
|
One equation of one regime, keyed by regressor. |
|
Forecast-error variance decomposition within one regime, held frozen. |
|
Iterate the fitted skeleton forward, blending regimes as it goes. |
|
Impulse responses within one regime, held frozen. |
|
Refuse the test: the threshold is unidentified under the null. |
|
Moving-average matrices of one regime, held frozen. |
|
The estimation summary, renderable as text, HTML, or a dataframe. |