FunctionalCoefficientVARResult.irf#

FunctionalCoefficientVARResult.irf(horizon=20, *, u, orthogonalized=True, cumulative=False)[source]#

Impulse responses at one state value, held frozen.

The family’s usual linearization, in its continuous form: the coefficients are frozen at A(u), so the response is exact only while the shock does not move the state – read it as the transmission prevailing at u. Orthogonalization uses the single estimated covariance under the model’s constant-covariance assumption; the ordering of names is then an identifying assumption, as for a linear VAR.

Parameters:
  • horizon (int) – Largest lead to return.

  • u (float) – A state value inside state_range.

  • orthogonalized (bool) – Rotate by the Cholesky factor of sigma_u.

  • cumulative (bool) – Return running sums.

Return type:

NDArray[double]

Returns:

An array of shape (horizon + 1, k, k); entry [h, i, j] is the response of variable i at lead h to shock j, as of state u.

Raises:

SpecificationError – If horizon is negative or u is outside the estimated range.

Example

The own response of y1 dies faster where its local coefficient is near zero than where it is large:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((250, 2))
>>> for t in range(1, 250):
...     a = 0.8 * np.tanh(y[t - 1, 0])
...     y[t, 0] = a * y[t - 1, 0] + 0.5 * rng.standard_normal()
...     y[t, 1] = 0.4 * y[t - 1, 1] + 0.5 * rng.standard_normal()
>>> res = FunctionalCoefficientVAR(y, order=1, transition_variable="y1").fit(
...     bandwidth=1.2, n_grid=21
... )
>>> calm = res.irf(4, u=0.0, orthogonalized=False)
>>> hot = res.irf(4, u=res.state_range[1], orthogonalized=False)
>>> calm.shape, bool(np.allclose(calm[0], np.eye(2)))
((5, 2, 2), True)
>>> bool(abs(calm[2, 0, 0]) < abs(hot[2, 0, 0]))
True
>>> bool(np.allclose(res.irf(4, u=0.0)[0], np.linalg.cholesky(res.sigma_u)))
True
>>> res.irf(-1, u=0.0)
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: horizon must be non-negative; got -1.