# Solving the Model

## The gensys routine

The DSGE model is written down in its canonical representation:

$\Gamma_0 s_t = \Gamma_1 s_{t-1} + C + \Psi \epsilon_t + \Pi \eta_t$

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:

\begin{aligned} s_t &= T s_{t-1} + R \epsilon_t + C & \epsilon_t &\sim N(0, Q) & \mathrm{(transition)} \\ y_t &= Z s_t + D + u_t & u_t &\sim N(0, E) & \mathrm{(measurement)} \end{aligned}

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.

1. Exogenous and unanticipated regimes
2. 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

1. 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.

1. 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.

1. 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 isgensys2.

Missing docstring.

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.solveFunction
solve(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 switching
• regimes::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
source

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
source
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
source

## 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.SystemType

System{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.

source
DSGE.TransitionType

Transition{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.

source
DSGE.MeasurementType

Measurement{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: the Ny x Ns measurement matrix
• DD: the Ny x 1 constant vector
• QQ: the Ne x Ne covariance matrix for the shocks ϵ_t
• EE: the Ny x Ny covariance matrix for the measurement error η_t
source
DSGE.PseudoMeasurementType
PseudoMeasurement{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: the Nx x Ns pseudo-measurement matrix
• DD_pseudo: the Nx x 1 constant vector
source
DSGE.compute_systemFunction
compute_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.

source
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

source
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 input m::AbstractDSGEModel and system::System.
• get_system::Bool: see Outputs
• get_population_moments::Bool: see Outputs
• use_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 updated system whose measurement matrices ZZ, DD, and QQ correspond to the VAR or VECM specified by m. If m is an AbstractDSGEVECMModel, then the system 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. If data 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.

source
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.

source

## 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.RegimeSwitchingSystemType

RegimeSwitchingSystem{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.

source

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.