PerturbationDSGEResult.impulse_responses#

PerturbationDSGEResult.impulse_responses(*, horizon=40, size=1.0)[source]#

Responses to each structural shock.

Deterministic paths from the steady state after a one-time impulse of size standard deviations in one structural shock, through the solution at the estimate.

Parameters:
  • horizon (int) – Periods after the impulse.

  • size (float) – Impulse size in standard deviations.

Return type:

tuple[NDArray[double], NDArray[double]]

Returns:

(states, controls) of shapes (n_eps, horizon, n_x) and (n_eps, horizon, n_y), as deviations from the steady state.

Raises:

SpecificationError – If the horizon is not positive.

Example

For the AR(1) latent state the response decays geometrically at the estimated persistence:

>>> import numpy as np
>>> class Latent:
...     parameter_names, bounds = ("rho", "sigma"), ((0.0, 0.99), (0.01, 1.0))
...     n_states, n_controls = 1, 1
...     def equations(self, th, y_next, y, x_next, x):
...         return np.array([y[0] - x[0], x_next[0] - th[0] * x[0]])
...     def steady_state(self, th):
...         return np.zeros(1), np.zeros(1)
...     def shock_loading(self, th):
...         return np.array([[th[1]]])
...     def observation(self, th):
...         return np.array([[0.0, 1.0]]), np.zeros(1), np.array([[1e-4]])
...     def log_prior(self, th):
...         return 0.0
>>> rng = np.random.default_rng(0)
>>> x = np.zeros(200)
>>> for t in range(1, 200):
...     x[t] = 0.8 * x[t - 1] + 0.5 * rng.standard_normal()
>>> res = PerturbationDSGE(Latent(), x, order=1).fit([0.5, 0.3], filter="kalman")
>>> states, controls = res.impulse_responses(horizon=3)
>>> states.shape, controls.shape
((1, 3, 1), (1, 3, 1))
>>> rho, sigma = res.theta
>>> bool(np.allclose(states[0, :, 0], sigma * rho ** np.arange(3)))
True
>>> res.impulse_responses(horizon=0)
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: horizon must be at least 1; got 0.