14  Linear rational expectations models

14.1 Introduction

How do we solve rational expectations models? What does that even mean? Here I show how to implement versions of the Blanchard and Kahn (1980) and Klein (2000) solutions to linear rational expectations models in R. The implementation is fairly general, and copes with singular models. It is a very transparent implementation, with all the necessary code, and also shows how to calculate and plot impulse responses.

14.2 Model

We take a simple New Keynesian model \[\begin{align} y_t &= y_{t+1}^e-\frac{1}{\sigma} (i_t - \pi_{t+1}^e) + e_t^1 \\ \pi_t &= \beta \pi_{t+1}^e + \kappa y_t + e_t^2 \\ i_t &= \gamma i_{t-1} + (1-\gamma) \delta \pi_t + \varepsilon_t^3 \\ e_t^1 &= \rho_1 e_{t-1}^1 + \varepsilon_t^1 \\ e_t^2 &= \rho_2 e_{t-1}^2 + \varepsilon_t^2 \end{align}\] The model comprises a dynamic IS curve, a Phillips Curve and a policy rule with smoothing. There are three shocks, two of which are persistent. This we need to write in the general algebraic linear state-space form: \[ E\begin{bmatrix} z_t \\ x_{t+1}^e \end{bmatrix} = A \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} + B \varepsilon_t \] We map our variables to their algebraic equivalent as (\(z_t\), \(x_t\)) \(=\) ((\(e^1_t\), \(e^2_t\), \(i_t\)), (\(y_t\), \(\pi_t\))). Then the model in state-space form but including the matrix \(E\) is \[ \begin{bmatrix} 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 1 & 0 & -\frac{1}{\sigma} & 1 & \frac{1}{\sigma} \\ 0 & 1 & 0 & 0 & \beta \end{bmatrix} \begin{bmatrix} e^1_t \\ e^2_t \\ i_t \\ y^e_{t+1} \\ \pi^e_{t+1} \end{bmatrix} = \begin{bmatrix} \rho_1 & 0 & 0 & 0 & 0 \\ 0 & \rho_2 & 0 & 0 & 0 \\ 0 & 0 & \gamma & 0 & (1-\gamma)\delta \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -\kappa & 1 \end{bmatrix} \begin{bmatrix} e^1_{t-1} \\ e^2_{t-1} \\ i_{t-1} \\ y_t \\ \pi_t \end{bmatrix} + \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ 0 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} \varepsilon^1_t \\ \varepsilon^2_t \\ \varepsilon^3_t \end{bmatrix} \] Anyone wanting to code up solutions should familiarize themselves with this before continuing.

14.2.1 Coding the model

Before we begin coding this in R, load the tidyverse libraries so we can do impulse responses with our usual tool kit and then we can forget about it.

library(tidyverse)

Set the model parameters

nf    <- 2
ns    <- 5
ne    <- 3
np    <- ns-nf

beta  <- 0.99   # Discount factor 
sigma <- 2.0    # Elas. substitution
kappa <- 0.075  # Slope PC
delta <- 1.5    # Inflation feedback
gamma <- 0.75   # Smoothing
rho_1 <- 0.9    # AR1
rho_2 <- 0.8    # AR1
Omega <- diag(c(0.33,0.33,0.33)) # SE of 3 shocks

Now define the model matrices ‘long hand’ and some variable names, which we put in labels.

labels <- c("e^1","e^2","i","y","pi")

E <- matrix(0,ns,ns)
A <- matrix(0,ns,ns)
B <- diag(1,ns,ne)

# Now put the equations in matrix form
diag(E[1:2,1:2]) <- 1
diag(A[1:2,1:2]) <- c(rho_1, rho_2)

E[3,3]             <- 1 
E[4,c(1, 3, 4, 5)] <- c(1, -1/sigma, 1, 1/sigma)
E[5,c(2, 5)]       <- c(1, beta)

A[3,c(3, 5)]       <- c(gamma, (1-gamma)*delta)
A[4,4]             <- 1
A[5,c(4,5)]        <- c(-kappa, 1)

where for example, \(E\) and \(A\) are \[\begin{equation} E = \left[\begin{matrix}1 &0 &0 &0 &0 \\0 &1 &0 &0 &0 \\0 &0 &1 &0 &0 \\1 &0 &-0.5 &1 &0.5 \\0 &1 &0 &0 &0.99 \\\end{matrix}\right] \end{equation}\] \[\begin{equation} A = \left[\begin{matrix}0.9 &0 &0 &0 &0 \\0 &0.8 &0 &0 &0 \\0 &0 &0.75 &0 &0.375 \\0 &0 &0 &1 &0 \\0 &0 &0 &-0.075 &1 \\\end{matrix}\right] \end{equation}\] Calculate the reduced form state-space model \[\begin{equation} \begin{bmatrix} z_t \\ x_{t+1}^e \end{bmatrix} = C \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} + D \varepsilon_t \end{equation}\] which is done in R very simply as

C <- solve(E,A)
D <- solve(E,B)

Why can’t we solve this for impulse responses?

The following function simulates the impulse responses of a model in a loop within a loop1 and returns the time series in a suitably organised data frame.

impulse_responses <- function(P, Q, Omega, labels, T) {
  s   <- matrix(0, ncol(Q), 1)
  z   <- matrix(0, nrow(Q), T)
  rownames(z) <- labels
  dza <- NULL
  for (j in 1:ncol(Q)) {
    s[j]  <- Omega[j,j]
    z[,1] <- Q %*% s
    for (i in 1:(T-1)) {
      z[,i+1] <- P %*% z[,i]
    }
    s[j] <- 0
    dz <- as_tibble(t(z)) %>% 
      mutate(Period = 1:T, Shock = paste0("epsilon^",j))
    dza <- bind_rows(dza,dz)
  }
  return(dza)
}

A function to plot the impulses will be useful, so we create one.

response_plot <- function(series, title) {
  return(pivot_longer(series, cols = -c(Period,Shock), names_to="Var", values_to = "Val") %>%
           ggplot() +
           geom_line(aes(x=Period, y=Val, group=Shock, colour=Var), show.legend=FALSE) +
           facet_grid(Shock~Var, scales="free", labeller=label_parsed) +
           scale_x_continuous(expand=c(0,0)) +
           theme_minimal() +
           labs(title=title, x="",y=""))
}

Call the impulse response function using the model \(C\) and \(D\).

T <- 25
z <- impulse_responses(C, D, Omega, labels, T)

and plot

response_plot(z, "Impulse responses: Taylor rule")

Oh! That’s not looking good. Let’s try a few more periods.

T <- 150
z <- impulse_responses(C, D, Omega, labels, T)
response_plot(z, "Impulse responses: Taylor rule")

This is clearly exploding. But it’s rational – we’re solving forward so expectations are always fulfilled. This is a key the insight of the early rational expectations modellers – rational isn’t enough, non-explosive is necessary too. Fortunately we know how to find this.

14.3 Blanchard and Kahn (1980)

To solve this model to give a unique stable rational expectations equilibrium, we appeal to the following. Consider the eigenvalue decomposition \[ MC=\Lambda M \] where \(\Lambda\) is a diagonal matrix of eigenvalues in increasing absolute value and \(M\) is a non-singular matrix of left eigenvectors. Note that computer routines (including the one in R) usually calculate right eigenvectors such that \(CV=V\Lambda\) and that \(M=V^{-1}\), so be aware of this in what follows.

We can diagonalise \(C\) and write it as \(C=M^{-1}\Lambda M\). So pre-multiplying the reduced form model by \(M\) gives \[ M \begin{bmatrix} z_t \\ x_{t+1}^e \end{bmatrix} = \Lambda M \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} + M D \varepsilon_t \] Blanchard and Kahn (1980) (following Vaughan (1970)) show uniqueness requires as many unstable eigenvalues as jump variables. To see this, define \[ \begin{bmatrix} \xi_{t-1}^{s} \\ \xi_t^{u} \end{bmatrix} = \begin{bmatrix} M_{11} & M_{12} \\ M_{21} & M_{22} \end{bmatrix} \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} \] Write the normalized model as \[ \begin{bmatrix} \xi_t^s \\ \xi_{t+1}^u \end{bmatrix} = \begin{bmatrix} \Lambda_s & 0 \\ 0 & \Lambda_u \end{bmatrix} \begin{bmatrix} \xi_{t-1}^s \\ \xi_t^u \end{bmatrix} + \begin{bmatrix} M_1 \\ M_2 \end{bmatrix} D\varepsilon_t \] where the eigenvalues are split into stable (\(\Lambda_s\)) and unstable (\(\Lambda_u\)). If we ignore the stochastic bit for a moment \[ \begin{bmatrix} \xi_t^s \\ \xi_{t+1}^u \end{bmatrix} = \begin{bmatrix} \Lambda_s & 0 \\ 0 & \Lambda_u \end{bmatrix} \begin{bmatrix} \xi_{t-1}^s \\ \xi_t^u \end{bmatrix} \]

We seek a non-explosive solution, and this turns out to be easy to find using the following

  • The dynamics of \(\xi_t^u\) are determined by \(\Lambda_u\) and nothing else;
  • If they don’t start at \(0\) they must explode;
  • This implies they must start at \(0\) and are always \(0\).

Thus the definition of the canonical variables necessarily implies \[ \begin{bmatrix} \xi_{t-1}^s \\ 0 \end{bmatrix} = \begin{bmatrix} M_{11} & M_{12} \\ M_{21} & M_{22} \end{bmatrix} \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} \]

From this it is clear that the jump variables themselves are only on the saddle path if \[ M_{21} z_{t-1} + M_{22} x_t = 0 \]

The rational solution implies that the jump variables are linearly related to the predetermined ones through \[\begin{align} x_t &= -M_{22}^{-1} M_{21}z_{t-1} \\ &= N z_{t-1} \end{align}\] We’ll deal with the shocks in a moment.

How do we do this in R? First, find the eigenvalue decomposition of \(C\) using

m <- eigen(C, symmetric=FALSE)

which yields

eigen() decomposition
$values
[1] 1.0715518+0.092734i 1.0715518-0.092734i 0.9000000+0.000000i
[4] 0.8000000+0.000000i 0.6548762+0.000000i

$vectors
                      [,1]                  [,2]         [,3]           [,4]
[1,]  0.0000000+0.0000000i  0.0000000+0.0000000i 0.2854942+0i  0.00000000+0i
[2,]  0.0000000+0.0000000i  0.0000000+0.0000000i 0.0000000+0i  0.09783896+0i
[3,]  0.1599159-0.5089425i  0.1599159+0.5089425i 0.7830500+0i  0.49622464+0i
[4,] -0.6991064+0.0000000i -0.6991064+0.0000000i 0.4552131+0i -0.86012270+0i
[5,]  0.2629802-0.3968579i  0.2629802+0.3968579i 0.3132200+0i  0.06616328+0i
              [,5]
[1,]  0.0000000+0i
[2,]  0.0000000+0i
[3,]  0.6351203+0i
[4,] -0.7554249+0i
[5,] -0.1611069+0i

However this calculates right eigenvectors. We will need to invert it for left ones. Given the number of jump variables in the model satisfies the Blanchard-Kahn conditions of as many unstable roots (1.072+0.093i, 1.072-0.093i) as jump variables (2) we can calculate the reaction function from the eigenvectors

iz <- 1:np
ix <- (np+1):ns
M  <- solve(m$vectors[,ns:1])        # Invert & reverse order for increasing abs value
N  <- -Re(solve(M[ix,ix], M[ix,iz])) # Drop tiny complex bits (if any)

where iz are the indices of the first np variables and ix those of the remaining nf ones.

14.3.1 Stochastic part

What about the shocks? Assume the stochastic reaction function is \[ x_t = N z_{t-1} + G \varepsilon_t \] Following Blake (2004), note that \(x_{t+1}^e = N z_t\) as the expected value of \(\varepsilon_{t+1}=0\), meaning we can write \[ Nz_t = C_{21}z_{t-1} + C_{22} x_t + D_2 \varepsilon_t \] or \[ N\left( C_{11}z_{t-1} + C_{12}x_t + D_1 \varepsilon_t\right) = C_{21}z_{t-1} + C_{22} x_t + D_2 \varepsilon_t \] Gathering terms we obtain \[ (C_{22} - N C_{12}) x_t = (NC_{11} - C_{21}) z_{t-1} + (N D_1 - D_2) \varepsilon_t \] which implies \[ G=(C_{22} - N C_{12})^{-1}(N D_1 - D_2) \] Notice it also implies \(N = (C_{22} - N C_{12})^{-1}(NC_{11} - C_{21})\). It is this fixed point nature of the solution for \(N\) – which in turn implies the quadratic matrix equation \(C_{21} = NC_{11} - C_{22}N + N C_{12}N\) – that means we need to use the Blanchard and Kahn (1980) method in the first place.

All of this means that

G <- solve((C[ix,ix] - N %*% C[iz,ix]), (N %*% D[iz,]- D[ix,]))

so for our model and parameters \(N\) and \(G\) are

\[\begin{equation} N = \left[\begin{matrix}4.8568 &-2.7586 \\-1.1894 &1.7929 \\1.9628 &-0.2537 \\\end{matrix}\right] \end{equation}\] \[\begin{equation} G = \left[\begin{matrix}5.3964 &-3.4483 \\-1.5859 &1.9921 \\2.4535 &-0.3382 \\\end{matrix}\right] \end{equation}\]

The ‘fixed point’ check is that the following should be the same as \(N\)

solve((C[ix,ix] - N %*% C[iz,ix]), (N %*% C[iz,iz]- C[ix,iz]))
        [,1]      [,2]       [,3]
[1,] 4.85680 -2.758647 -1.1894200
[2,] 1.79286  1.962790 -0.2536635

which it is.

The solved model is finally \[\begin{align} \begin{bmatrix} z_t \\ x_t \end{bmatrix} &= \begin{bmatrix} C_{11}+C_{12}N & 0 \\ N & 0 \end{bmatrix} \begin{bmatrix} z_{t-1} \\ x_{t-1} \end{bmatrix} + \begin{bmatrix} D_1+C_{12}G \\ G \end{bmatrix} \varepsilon_t \\ &= P \begin{bmatrix} z_{t-1} \\ x_{t-1} \end{bmatrix} + Q \varepsilon_t \end{align}\] which can be coded as

P  <- cbind(rbind((C[iz,iz] + C[iz,ix] %*% N), N), matrix(0,ns,nf))
Q  <- rbind(D[iz,] + C[iz,ix] %*% G, G)

14.3.2 Digression – right eigenvector version

It turns out that we could use the output from the standard eigenvalue/vector routine directly by exploiting the following. This time, let \(M\) be the matrix of right eigenvectors so \[ C M = M \Lambda \text{ or } C = M\Lambda M^{-1} \]
and \[ \begin{bmatrix} M_{11} & M_{12} \\ M_{21} & M_{22} \end{bmatrix} \begin{bmatrix} \xi_{t-1}^s \\ \xi_t^u \end{bmatrix} = \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} \]

Written this way around, if \(\xi_t^{u}=0\) \(\forall\ t\) then (again ignoring stochastics)

\[ M_{11} \xi_{t-1}^s = z_{t-1}, \ M_{21}\xi_t^s = x_t \]

\[ \Rightarrow x_t = M_{21} M_{11}^{-1} z_t \] so

M <- m$vectors[,ns:1]            # Don't invert as already right vectors, but reorder
Re(M[ix,iz] %*% solve(M[iz,iz])) # Again, drop tiny complex bits
        [,1]      [,2]       [,3]
[1,] 4.85680 -2.758647 -1.1894200
[2,] 1.79286  1.962790 -0.2536635

The result is identical. This method is particularly useful if there are fewer predetermined variables than jumps as the matrix we need to invert is of the same dimension as the predetermined variables this way round.

14.3.3 Impulse responses

We now call the impulse response function using the model solved for rational expectations.

T <- 25
z <- impulse_responses(P, Q, Omega, labels, T)

Now plot these responses

response_plot(z, "Impulse responses: Taylor rule")

Now, that looks better! It is no longer explosive. It also makes complete economic sense, which you can verify by going through the dynamics of the different demand, supply and monetary shocks.

14.4 Generalized solution

Sometimes for a model \(E\) is singular. A more general solution was proposed by Klein (2000), that doesn’t require \(E\) to be non-singular. This uses a generalized Schur decomposition instead of an eigenvalue one and is applied to the structural model represented by the matrix pencil \((A,E)\), and is considered much more numerically stable (see Pappas, Laub, and Sandell (1980)). The generalized Schur form of \((A,E)\) is \((QTZ', QSZ')\), so we can write the model as \[ E \begin{bmatrix} z_t \\ x_{t+1}^e \end{bmatrix} \equiv QTZ' \begin{bmatrix} z_t \\ x_{t+1}^e \end{bmatrix} \equiv QT \begin{bmatrix} \xi_t^s \\ \xi_{t+1}^u \end{bmatrix} \] and \[ A \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} \equiv QSZ' \begin{bmatrix} z_{t-1} \\ x_t \end{bmatrix} \equiv QS\begin{bmatrix} \xi_{t-1}^s \\ \xi_t^u \end{bmatrix} \] so the model pre-multiplied by \(Q'\) is \[ T \begin{bmatrix} \xi_{t+1}^s \\ \xi_{t+1}^u \end{bmatrix} = S \begin{bmatrix} \xi_t^s \\ \xi_t^u \end{bmatrix} + Q'B\varepsilon_t \]

We use the function gqz from the library geigen for this

d <- geigen::gqz(A, E, sort="S") # Option "S" puts the stable roots first

We can check that this is actually saddle path using gevalues() to get all the eigenvalues from the generalized Schur decomposition, and the unstable ones are

e <- geigen::gevalues(d)
e[abs(e) > 1]
[1] 1.071552+0.092734i 1.071552-0.092734i

The number of stable roots is returned in d$sdim which is 3.

We then modify our solution function to calculate Ns and Gs using the matrix Z and a generalized version of the formula for \(G\) and calculate the reduced form model Ps and `Q which are \[\begin{align} N_s &= Z_{21} Z_{11}^{-1} \\ H &= (E_{11} + E_{12} N_s)^{-1} \\ W &= (E_{21} + E_{22} N_s) H\\ G_s &= (A_{22} - W A_{12})^{-1} (W B_1 - B_2) \\ P_s &= H (A_{11} + A_{12} N_s) \\ Q_s &= H (B_1 + A_{12} G_s) \end{align}\] Verify this yourself with a bit of matrix algebra!

The R code for this is

solveGenBK <- function(E,A,B,n) {
  d  <- geigen::gqz(A, E, sort="S") 
  np <- d$sdim
  ns <- nrow(E)
  print(paste("Number of unstable roots is", ns-np))
  if (n == np) {
    iz <- 1:n
    ix <- (n+1):ns
    Ns <- d$Z[ix,iz] %*% solve(d$Z[iz,iz])
    H  <- solve(E[iz,iz] + E[iz,ix] %*% Ns)
    W  <- (E[ix,iz] + E[ix,ix] %*% Ns) %*% H
    Gs <- solve((A[ix,ix] - W %*% A[iz,ix]), (W %*% B[iz,] - B[ix,]))
    As <- H %*% (A[iz,iz] + A[iz,ix] %*% Ns)
    Bs <- H %*% (B[iz,] + A[iz,ix] %*% Gs)
    return(list(P=cbind(rbind(As,Ns),matrix(0,ns,ns-n)), Q=rbind(Bs, Gs)))
    } 
  else { 
    return(-1) 
    }
}

Using this on our original model gives

S  <- solveGenBK(E,A,B,np)
[1] "Number of unstable roots is 2"
Ps <- S$P
Qs <- S$Q

and comparing Ps and Qs with P and Q obtained using Blanchard-Kahn we find

round(max(abs(P-Ps), abs(Q-Qs)), 12)
[1] 0

They are, as expected, the same – at least up to 12 decimal places, which should be enough.

14.5 Singular models: optimal policy

However, this is an easy test. What we need is to use a model that can’t be solved using the BK method. Under optimal policy, the interest rate instrument rule is replaced with a targeting rule, so that \[ \pi_t = -\mu \Delta y_t - \varepsilon^3_t \] for some value of \(\mu\) that reflects the optimal trade-off between output (gap) growth and inflation, and we’ve included a disturbance which we can loosely describe as a monetary policy shock. We modify the model above by dropping the Taylor rule in favour of the targeting rule. This requires a lagged value of \(y\) to be created. The following does the trick

nf <- 2
ne <- 3
ns <- 6      # One extra state
np <- ns-nf
mu <- 0.75   # Representative trade-off

labels <- c("e^1","e^2","ylag","i","y","pi") # New variable order

E <- matrix(0,ns,ns)
A <- E
B <- matrix(0,ns,ne)
B[1,1] <- 1
B[2,2] <- 1
B[4,3] <- -1

diag(E[1:3,1:3]) <- 1
diag(A[1:2,1:2]) <- c(rho_1, rho_2)
A[3,5]           <- 1

E[4,3]           <- 1
A[4,c(3, 6)]     <- c(1, -1/mu)

E[5,c(1, 4, 5, 6)] <- c(1, -1/sigma, 1, 1/sigma)
A[5,5]           <- 1

E[6,c(2, 6)]     <- c(1, beta)
A[6,c(5, 6)]     <- c(-kappa, 1)

The new \(E\) and \(A\) system matrices are then \[ E = \left[\begin{matrix}1 &0 &0 &0 &0 &0 \\0 &1 &0 &0 &0 &0 \\0 &0 &1 &0 &0 &0 \\0 &0 &1 &0 &0 &0 \\1 &0 &0 &-0.5 &1 &0.5 \\0 &1 &0 &0 &0 &0.99 \\\end{matrix}\right] \] \[ A = \left[\begin{matrix}0.9 &0 &0 &0 &0 &0 \\0 &0.8 &0 &0 &0 &0 \\0 &0 &0 &0 &1 &0 \\0 &0 &1 &0 &0 &-1.333 \\0 &0 &0 &0 &1 &0 \\0 &0 &0 &0 &-0.075 &1 \\\end{matrix}\right] \] Now we have a singular model. The matrix \(E\) is clearly singular as rows 3 and 4 are identical. But we have a problem using the code above. To use it we need the matrices \(H\) and \((A_{22} - W A_{21})\) to be non-singular. What to do?

There are two ways out. Klein (2000) gives a solution that depends on the decomposed matrix pencil, which is what is typically implemented, but you don’t actually need it although it is easiest. Instead, all you need to do is reorder the equations.

The real problem is that with a targeting rule that doesn’t include the interest rate, and the interest rate is now only determined by the IS curve. But we can swap the location of any two rows of the model arbitrarily. If we swap the positions of the equations for the IS curve and the targeting rule (rows 4 and 5) using the following

E[4:5,] <- E[5:4,]
A[4:5,] <- A[5:4,]
B[4:5,] <- B[5:4,]

then the model is unchanged but now we have \[ E_{11} = \left[\begin{matrix}1 &0 &0 &0 \\0 &1 &0 &0 \\0 &0 &1 &0 \\1 &0 &0 &-0.5 \\\end{matrix}\right] \] so \(E_{11} + E_{12}N\) is likely non-singular (it is). Also, note after the re-ordering \(A_{22}\) is \[ A_{22} = \left[\begin{matrix}0 &-1.33 \\-0.07 &1 \\\end{matrix}\right] \] which is guaranteed non-singular for zero \(W\). We can now proceed as before. First, check for saddle path stability

e <- geigen::gevalues(geigen::gqz(A, E, sort="S"))
e[abs(e) > 1]
[1] 1.378195     -Inf

which confirms that it has a unique saddle path stable solution. This is

So <- solveGenBK(E,A,B,np)
[1] "Number of unstable roots is 2"
Po <- So$P
Qo <- So$Q

The solved model is then

Po
     [,1]      [,2]       [,3] [,4] [,5] [,6]
[1,]  0.9  0.000000  0.0000000    0    0    0
[2,]  0.0  0.800000  0.0000000    0    0    0
[3,]  0.0 -1.863455  0.7329156    0    0    0
[4,]  1.8 -1.241330 -0.2446879    0    0    0
[5,]  0.0 -1.863455  0.7329156    0    0    0
[6,]  0.0  1.397591  0.2003133    0    0    0
Qo
     [,1]      [,2]       [,3]
[1,]    1  0.000000  0.0000000
[2,]    0  1.000000  0.0000000
[3,]    0 -2.329318 -0.7329156
[4,]    2 -1.551663  0.2446879
[5,]    0 -2.329318 -0.7329156
[6,]    0  1.746989 -0.2003133

14.5.1 Optimal impulse responses

We can now simulate the model under optimal policy and plot using

zo <- impulse_responses(Po, Qo, Omega, labels, T) %>%
  select(-ylag) # Drop duplicate series
response_plot(zo, "Impulse responses: Optimal policy")

14.6 Dummy jumps

But this isn’t the only way to get this to work. Effectively what we just did was create an extra predetermined variable and reorder the system to give us non-singularity. What if instead of including an unused \(i_{t-1}\) on the right hand side, we instead include an unused \(i^e_{t+1}\) on the left hand side? So we swap to having one more jump variable, one less predetermined one?

Compare the following to the previous model. When we pick out the interest rate we do so on the right hand side of the matrix equation, not the left as before.

ns <- 6      # One extra state
nf <- 3      # And one extra jump
np <- ns-nf
labels <- c("e^1","e^2","ylag","i","y","pi") # New variable order

E <- matrix(0,ns,ns)
A <- E
B <- matrix(0,ns,ne)
B[1,1] <- 1
B[2,2] <- 1
B[4,3] <- -1

diag(E[1:3,1:3]) <- 1
diag(A[1:2,1:2]) <- c(rho_1, rho_2)
A[3,5]           <- 1

E[4,3]           <- 1
A[4,c(3, 6)]     <- c(1, -1/mu)

E[5,c(1, 5, 6)]  <- c(1, 1, 1/sigma) # One less coefficient
A[5,c(4, 5)]     <- c(1/sigma, 1)    # One more - nothing else changes

E[6,c(2, 6)]     <- c(1, beta)
A[6,c(5, 6)]     <- c(-kappa, 1)

This is still a singular model, as we can see from \[ E = \left[\begin{matrix}1 &0 &0 &0 &0 &0 \\0 &1 &0 &0 &0 &0 \\0 &0 &1 &0 &0 &0 \\0 &0 &1 &0 &0 &0 \\1 &0 &0 &0 &1 &0.5 \\0 &1 &0 &0 &0 &0.99 \\\end{matrix}\right] \] with column 4 all zeros. Is this model saddle path stable?

e <- geigen::gevalues(geigen::gqz(A, E, sort="S") )
e[abs(e) > 1]
[1] 4.787695e+15 1.378195e+00         -Inf

Again, it is with an extra unstable root for the extra jump variable. We could simplify the solution. As that top left 3 by 3 block, \(E_{11}\), is the identity matrix and \(E_{12}\) is all zeros this Ei is always an identity matrix. However, here we simply re-use solveGenBG

So2 <- solveGenBK(E,A,B,np)
[1] "Number of unstable roots is 3"
Po2 <- So2$P
Qo2 <- So2$Q

Now the solved model is

Po2
     [,1]      [,2]       [,3] [,4] [,5] [,6]
[1,]  0.9  0.000000  0.0000000    0    0    0
[2,]  0.0  0.800000  0.0000000    0    0    0
[3,]  0.0 -1.863455  0.7329156    0    0    0
[4,]  1.8 -1.241330 -0.2446879    0    0    0
[5,]  0.0 -1.863455  0.7329156    0    0    0
[6,]  0.0  1.397591  0.2003133    0    0    0
Qo2
     [,1]      [,2]       [,3]
[1,]    1  0.000000  0.0000000
[2,]    0  1.000000  0.0000000
[3,]    0 -2.329318 -0.7329156
[4,]    2 -1.551663  0.2446879
[5,]    0 -2.329318 -0.7329156
[6,]    0  1.746989 -0.2003133

which is actually identical to our previous solution. This is because I have preserved the order of the solved-out variables, and shows that the swap from a predetermined to a jump variable is completely arbitrary.

14.7 Substituting out

But even this doesn’t exhaust the possible re-parametrisations of the model. We can reduce the number of jump variables to 1 and find the same solution. There exist formal methods for reducing models (see King and Watson (2002)) but there is an obvious way to proceed here. From the targeting rule, it must be that \[ y^e_{t+1} = y_t - \frac{1}{\mu}\pi^e_{t+1} \] as the expected shock is zero. This means the IS curve can be rewritten \[ y_t = y_t - \frac{1}{\mu}\pi^e_{t+1} - \frac{1}{\sigma} \left (i_t - \pi_{t+1}^e \right ) + e_t^1 \] implying \[ i_t = \left (1 - \frac{\sigma}{\mu} \right )\pi_{t+1}^e + \sigma e_t^1 \] This is the required interest rate consistent with the targeting rule holding. Now the only jump variable is the inflation rate as we have eliminated the expected output gap. \[\begin{align} y_t &= y_{t-1} -\frac{1}{\mu} \pi_t + \frac{1}{\mu} \varepsilon^3_t \\ \pi_t &= \beta \pi_{t+1}^e + \kappa y_t + e_t^2 \\ i_t &= \left (1 - \frac{\sigma}{\mu} \right ) \pi_{t+1}^e + \sigma e_t^1 \\ e_t^1 &= \rho_1 e_{t-1}^1 + \varepsilon_t^1 \\ e_t^2 &= \rho_2 e_{t-1}^2 + \varepsilon_t^2 \end{align}\]

We can code this

ns <- 5      # Back to 5 states
nf <- 1      # Now only one jump
np <- ns-nf

labels <- c("e^1","e^2","i","y","pi") # Lose a y

E <- matrix(0,ns,ns)
A <- E
B <- matrix(0,ns,ne)
B[1,1] <- 1
B[2,2] <- 1
B[4,3] <- -1

diag(E[1:4,1:4]) <- 1
diag(A[1:2,1:2]) <- c(rho_1, rho_2)

E[3,c(1, 3, 5)]  <- c(-sigma, 1, sigma/mu-1)

A[4,c(4,5)]      <- c(1, -1/mu)

E[5,c(2, 4, 5)]  <- c(1, kappa, beta)
A[5,5]           <- 1

and solve it using

Ss <- solveGenBK(E,A,B,np)
[1] "Number of unstable roots is 1"
Ps <- Ss$P
Qs <- Ss$Q

Compare the realized of Ps

Ps
     [,1]      [,2] [,3]       [,4] [,5]
[1,]  0.9  0.000000    0  0.0000000    0
[2,]  0.0  0.800000    0  0.0000000    0
[3,]  1.8 -1.241330    0 -0.2446879    0
[4,]  0.0 -1.863455    0  0.7329156    0
[5,]  0.0  1.397591    0  0.2003133    0

with Po above, say. This is the most ‘efficient’ way of programming the model, in that we have only five states, and indeed the repeated behavioural equations we had before have disappeared in the reduced form solution. Just to confirm this, simulating and plotting this version gives

response_plot(impulse_responses(Ps,Qs,Omega,labels,T), "Optimal, substituted out")

which are identical results to those above. But of course \(E\) is now invertible so we could solve this using the simplest Blanchard-Kahn variant. Try it!


  1. Sometimes a loop is the right way to do something.↩︎