View source: R/kalman-skewed.R
| kalman_filter_skewed | R Documentation |
Evaluates the log-likelihood of a linear state-space DSGE model whose structural shocks are skew-normal rather than Gaussian. The mean and covariance recursions are the usual Kalman ones (which remain the optimal linear filter under any shock distribution); in addition the filter propagates the third cumulant of the state exactly, and uses it to build a skewed one-step-ahead predictive density.
kalman_filter_skewed(y, G, H, M, D, shock_skew)
y |
Matrix of observed data (T x n_obs). |
G |
Policy matrix mapping states to controls. |
H |
State transition matrix. |
M |
Shock impact matrix (already scaled by the shock standard
deviations, as returned by |
D |
Observation selection matrix; the observation equation is
|
shock_skew |
Numeric vector of shock skewness coefficients, one
per column of |
The filtered and predicted means, covariances, and third cumulants are computed exactly for the linear system: the Kalman gain is the exact minimum-MSE linear filter, and the third cumulant obeys the exact linear-map rule. The only approximation is in the shape of the predictive density used for the likelihood, which is taken to be a product of univariate skew-normals in the Cholesky-decorrelated space, each matched to the exact marginal skewness. This is exact when the shocks are Gaussian and is a third-order-accurate approximation otherwise.
Each shock is standardised to zero mean and unit variance, so
shock_skew is the coefficient of skewness. The largest
magnitude attainable by a skew-normal is about 0.995; values are
clamped to \pm 0.99.
A list with the same components as the Gaussian filter –
loglik, filtered_states, predicted_states,
prediction_errors, filtered_P, innovation_var,
predicted_obs – plus:
innovation_skew(T x n_obs) matrix of model-implied skewness coefficients of the decorrelated one-step-ahead forecast errors.
shock_skewThe skewness vector used.
particle_filter for a fully nonlinear /
non-Gaussian alternative.
m <- dsge_model(
obs(y ~ z),
state(z ~ rho * z),
fixed = list(rho = 0.8))
sol <- solve_dsge(m, params = c(rho = 0.8), shock_sd = c(z = 1))
set.seed(1)
dat <- matrix(rnorm(100), 100, 1, dimnames = list(NULL, "y"))
# Gaussian shocks: identical to the standard filter
kalman_filter_skewed(dat, sol$G, sol$H, sol$M, sol$D,
shock_skew = 0)$loglik
# Left-skewed shocks
kalman_filter_skewed(dat, sol$G, sol$H, sol$M, sol$D,
shock_skew = -0.7)$loglik
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.