Solving the Model
The gensys
routine
The DSGE model is written down in its canonical representation:
where $\Gamma_0$, $\Gamma_1$, $C$, $\Psi$, and $\Pi$ are matrices of coefficients for $s_t$ (states at time $t$), $s_{t-1}$ (lagged states), $\epsilon_t$ (exogenous shocks) and $\eta_t$ (expectational shocks).
DSGE.jl solves the model to obtain its state-space form:
using the gensys
routine of Chris Sims, introduced in this paper. This algorithm can be easily extended to (exogenous) regime switching. For each regime $i$, define the canonical matrices $\Gamma_{0, i}$, $\Gamma_{1, i}$, $C_i$, $\Psi_i$, and $\Pi_i$. Calling gensys
on each regime and constructing the relevant easurement matrix yields the matrices $T_i$, $R_i$, $C_i$, $Q_i$, $Z_i$, $D_i$, and $E_i$, which define the state-space form of a DSGE with multiple regimes.
We provide a standalone native Julia implementation of the routine (gensys
) as well as a wrapper for AbstractDSGEModel
subtypes (solve
). When the Gensys.jl package becomes ready for use, we intend to deprecate our gensys
code and substitute the gensysdt
method for our code.
Regime-Switching
We allow solving the model with regime-switching in two cases.
- Exogenous and unanticipated regimes
- Alternative policies (permanent and temporary)
The first is straightforward to implement because the regimes are exogenous and unanticipated. We simply need to specify the equilibrium conditions in each regime, run gensys
for each regime, and return multiple transition equations. The required steps to solve a model with exogenous and unanticipated regime-switching are
- Write
eqcond
to accept a second argument specifying the regime, e.g.eqcond(m::MyDSGEModel, reg::Int)
.
To allow no regime-switching, we recommend also writing the wrapper eqcond(m) = eqcond(m, 1)
or whatever default regime is desired.
- Add additional keyword arguments to
measurement
so that it is defined as
function measurement(m::MyDSGEModel, TTT::AbstractMatrix{T}, RRR::AbstractMatrix{T}, CCC::AbstractVector{T};
reg::Int = 1, TTTs::Vector{<: AbstractMatrix{T}} = Matrix{T}[],
CCCs::Vector{<: AbstractVector{T}} = Vector{T}[],
information_set::UnitRange = reg:reg,
memo::Union{ForwardMultipleExpectationsMemo, Nothing} = nothing) where {T <: Real}
The type assertions for the arrays and keywords are not strictly necessary but are advised. Alternatively, the user could simply set
function measurement(m::MyDSGEModel, TTT::AbstractMatrix{T}, RRR::AbstractMatrix{T}, CCC::AbstractVector{T};
kwargs...) where {T <: Real}
to avoid problems with forgetting certain kwargs.
- Add the settings and indices required to ensure regime-switching is properly handled.
See Regime-Switching Forecasts for guidance on how to do this.
For 1 and 2, we recommend conferring with the implementation of regime-switching for Model 1002. See the equilibrium conditions here and the measurement equation here.
Temporary alternative policies are slightly more complicated. They leverage the same machinery as exogenous and unanticipated regime-switching, so steps 1 and 2 above are required still. But in addition, we need to specify in which regimes policies should be different than those specified by eqcond
, which assumes all policies are permanent ones. Once we have specified these policies, we use the algorithm from Calgiarini and Kulish to calculate the rational expectations solution to a model with `predicted structural changes'', which allows us to specify temporary alternative policies like a temporary ZLB or a temporary switch to average inflation targeting. The function implementing this algorithm is
gensys2`.
Missing docstring for DSGE.gensys2
. Check Documenter's build log for details.
See Alternative Policies and the regime-switching example script for guidance on how to use temporary alternative policies.
DSGE.solve
— Functionsolve(m::AbstractDSGEModel)
Driver to compute the model solution and augment transition matrices.
Inputs
m
: the model object
Keyword Arguments
regime_switching::Bool
: true if the state space system features regime switchingregimes::Union{Int, Vector{Int}, UnitRange{Int}}
: specifies the specific regime to solve for.
Outputs
- TTT, RRR, and CCC matrices of the state transition equation:
S_t = TTT*S_{t-1} + RRR*ϵ_t + CCC
solve(m::PoolModel) ```
Driver to compute the model solution when using the PoolModel type
Inputs
m
: the PoolModel object
Outputs
- Φ: transition function
- F_ϵ: distribution of structural shock
- Fλ: prior on the initial λ0
solvect(m::AbstractCTModel; reduction_settings_check::Bool = false)
Driver to compute the model solution and augment transition matrices.
Inputs
m
: the model object
Outputs
- TTT, RRR, and CCC matrices of the state transition equation:
S_t = TTT*S_{t-1} + RRR*ϵ_t + CCC
The System
Type
The solve
function only returns the $TTT$, $RRR$, and $CCC$ matrices. To obtain the other matrices in the state-space representation of the DSGE, we provide a wrapper function compute_system
, which returns an object of type System
, whose fields are also special types we have implemented to faciltiate use of the state-space form.
DSGE.System
— TypeSystem{T <: Real}
A mutable struct containing the transition and measurement equations for a state-space model. The matrices may be directly indexed: sys[:TTT]
returns sys.transition.TTT
, sys[:ZZ]
returns sys.measurement.ZZ
, etc.
DSGE.Transition
— TypeTransition{T<:Real}
The transition equation of the state-space model takes the form
`s_t = TTT*s_{t-1} + RRR*ϵ_t + CCC`
The Transition
type stores the coefficient Matrix{T}
s (TTT
, RRR
) and constant Vector{T} CCC
.
DSGE.Measurement
— TypeMeasurement{T<:Real}
The measurement equation of the state-space model takes the form
y_t = ZZ*s_t + DD + u_t
where the error u_t
is the measurement error, which is uncorrelated with the shocks in the transition equation ϵ_t
.
Fields
If Ns
is the number of states s_t
, Ny
is the number of observables y_t
, and Ne
is the number of shocks ϵ_t
:
ZZ
: theNy
xNs
measurement matrixDD
: theNy
x 1 constant vectorQQ
: theNe
xNe
covariance matrix for the shocksϵ_t
EE
: theNy
xNy
covariance matrix for the measurement errorη_t
DSGE.PseudoMeasurement
— TypePseudoMeasurement{T<:Real}
The pseudo-measurement equation of the state-space model takes the form
x_t = ZZ_pseudo*s_t + DD_pseudo
Fields
Let Ns
be the number of states s_t
and Nx
be the number of pseudo-observables x_t
:
ZZ_pseudo
: theNx
xNs
pseudo-measurement matrixDD_pseudo
: theNx
x 1 constant vector
DSGE.compute_system
— Functioncompute_system(m; tvis::Bool = false, verbose = :high)
compute_system_helper(m; tvis::Bool = false, verbose = :high)
Given the current model parameters, compute the state-space system corresponding to model m
. Returns a System
or RegimeSwitchingSystem
object. The keyword apply_altpolicy
indicates whether the state-space system should reflect an alternative policy, and the keyword tvis
indicates whether the state-space system involves time-varying information sets. To use tvis = true
, at least the setting :tvis_information_set
must exist. See ?DSGE.compute_tvis_system
for more information about computing state-space systems with time-varying information sets.
computesystem just runs computesystem_helper (which actually computes the system) and then in the case of imperfect but positive credibility, adjusts the anticipated observables and pseudo-observables' measurement equations.
compute_system(m::PoolModel{T})
Given the current model parameters, compute the state-space system corresponding to the PoolModel model m
.
Outputs
``` Φ: state transition function Ψ: likelihood function, given weights on underlying models (the states) and predictive densities Fϵ: structural shock distribution Fu: likelihood function measurement error distribution F_λ: initial distribution of λ for state transition function
compute_system(m; apply_altpolicy = false,
check_system = false, get_system = false,
get_population_moments = false, use_intercept = false,
tvis::Bool = false, verbose = :high)
compute_system(m, data; apply_altpolicy = false,
check_system = false, get_system = false,
get_population_moments = false,
tvis::Bool = false, verbose = :high)
Given the current model parameters, compute the DSGE-VAR or DSGE-VECM system corresponding to model m
. If a matrix data
is also passed, then the VAR is estimated on data
using the DSGE m
as a prior with weight λ.
Keyword Arguments
check_system::Bool
: see?compute_system
that takes the inputm::AbstractDSGEModel
andsystem::System
.get_system::Bool
: see Outputsget_population_moments::Bool
: see Outputsuse_intercept::Bool
: use an intercept term when computing the OLS estimate of the VAR system.tvis::Bool
indicates whether the state-space system involves time-varying information sets.
Outputs
- If
get_system = true
: Returns the updatedsystem
whose measurement matricesZZ
,DD
, andQQ
correspond to the VAR or VECM specified bym
. Ifm
is anAbstractDSGEVECMModel
, then thesystem
and the vector implied by additional cointegrating relationships are returned as a 2-element tuple. - If
get_population_moments = true
: Returns the limit cross product matrices that describe the DSGE implied population moments between the observables and their lags. Ifdata
is also passed as an input, then the sample population moments are also returned. - Otherwise:
Returns β
and Σ
, the coefficients and observables covariance matrix of the VAR or VECM. If data
is passed in, then β
and Σ
are estimated from the data using m
as a prior with weight λ. Otherwise, β
and Σ
comprise the VECM approximation of the DSGE m
.
compute_system(m::AbstractDSGEModel, system::System;
observables::Vector{Symbol} = collect(keys(m.observables)),
pseudo_observables::Vector{Symbol} = collect(keys(m.pseudo_observables)),
states::Vector{Symbol} = vcat(collect(keys(m.endogenou_states)),
collect(keys(m.endogenous_states_augmented)))
shocks::Vector{Symbol} = collect(keys(m.exogenous_shocks)),
zero_DD = false, zero_DD_pseudo = false)
compute_system(m::AbstractDSGEVECMModel, system::System;
observables::Vector{Symbol} = collect(keys(m.observables)),
pseudo_observables::Vector{Symbol} = collect(keys(m.pseudo_observables)),
cointegrating::Vector{Symbol} = collect(keys(m.cointegrating)),
states::Vector{Symbol} = vcat(collect(keys(m.endogenou_states)),
collect(keys(m.endogenous_states_augmented)))
shocks::Vector{Symbol} = collect(keys(m.exogenous_shocks)),
zero_DD = false, zero_DD_pseudo = false)
computes the corresponding transition and measurement equations specified by the keywords (e.g. states
, pseudo_observables
) using the existing ZZ
, ZZ_pseudo
, and TTT
matrices in system
.
Note that this function does not update the EE matrix, which is set to all zeros. To incorporate measurement errors, the user must specify the EE matrix after applying compute_system.
Keywords
observables
: variables that should be
entered into the new ZZ
and DD
matrices. The observables
can be both Observables and PseudoObservables, but they must be an element of the system already.
pseudo_observables
: variables that should be
entered into the new ZZ_pseudo
and DD_pseudo
matrices. The observables
can be both Observables and PseudoObservables, but they must be an element of the system already.
cointegrating
: variables that should be
entered into the new ZZ
and DD
matrices as cointegrating relationships. The observables
can be both Observables and PseudoObservables, but they must be an element of the system already.
states
: variables that should be
entered into the new TTT
and RRR
matrices as states. They must be existing states.
shocks
: variables that should be
entered into the new RRR
and QQ
matrices as shocks. They must be existing exogenous shocks.
The RegimeSwitchingSystem
Type
When there are multiple (exogenous) regimes in the state-space representation of the DSGE, it is useful to treat the system as one type rather than a vector of individual System
objects. The RegimeSwitchingSystem
type implements this idea, and via multiple dispatch, most commands that work on a System
object also work on a RegimeSwitchingSystem
object.
DSGE.RegimeSwitchingSystem
— TypeRegimeSwitchingSystem{T <: Real}
A mutable struct containing the transition and measurement equations for a state-space model with regime-switching. The matrices may be directly indexed: sys[1, :TTT]
returns sys.regime[1].transition.TTT
, etc.
To get the number of regimes, one can call n_regimes(regime_switch_system)
or regime_switch_system[:regimes]
. Like a System
object, the fields of a RegimeSwitchingSystem
can be accessed by
regime_switch_system[:transitions]
regime_switch_system[:measurements]
regime_switch_system[:pseudo_measurements]
A System
can be formed from a specific regime by calling
sys_reg2 = regime_switch_system[2]
and specific matrices/types in a given regime can be accessed by
regime_switch_system[2, :TTT]
regime_switch_system[2, :transition]
regime_switch_system[2, :measurement]
regime_switch_system[2, :pseudo_measurement]
The TimeVaryingInformationSetSystem
Type
This type implements a state space system with time-varying information sets. We alter two parts of the RegimeSwitchingSystem
.
First, the transitions
field is now a Vector{Vector{Transition}}
` because we may need to calculate the transition equations under different information sets. For example, the time-varying transition equations implied by expecting a temporary ZLB to 2023:Q4 in 2020:Q4 will be different than those implied by expecting a temporary ZLB to 2024:Q4. Thus, if the Federal Reserve announced a ZLB to 2023:Q4 in 2020:Q4, and then in 2021:Q1, they announced an extension of the ZLB to 2024:Q4, then the measurement equation needs to calculate two sets of time-varying transition equations.
Second, we add two new fields, information_set
and select
. The first specifies which regimes are part of the information set in a given regime. The second specifies which transition equation to use in each regime. Continuing the example of the change in the ZLB length, the regime in the select
field for 2020:Q4 would point to the set of transition equations associated with a temporary ZLB to 20203:Q4, while the regime in select
for 2021:Q1 would point to the set of transition equations associated with a temporary ZLB to 20204:Q4.
For more guidance, see Time-Varying Information Sets and the example tvis_system.jl, which shows how to work with this type.