Undergraduate Computational Macro
sum(probs) ≈ 1 = true
d = Categorical{Float64, Vector{Float64}}(support=Base.OneTo(2), p=[0.6, 0.4])
draws = [2, 1, 1, 1]
G[draws] = [20, 5, 5, 5]
Categorical
per rowX_0
alpha, lambda = 0.3, 0.6
P = [1-alpha alpha; lambda 1-lambda]
G = [100000.00, 20000.00]
X_0 = ones(Int, 100) # 100 people employed
T = 60
X = simulate_markov_chain(P, X_0, T)
X_values = G[X] # just indexes by the X
X_mean = mean(X_values;dims=1)
plot(0:T, X_mean', xlabel="t",
legend=:bottomright, label="Mean Income",
size=(600, 400))
hline!([G[1]]; label=L"x_E", linestyle=:dash)
hline!([G[2]]; label=L"x_U", linestyle=:dash)
Many macro questions involve: \(\mathbb{P}(X_{t+j} = x_i | X_t = x_j)\) etc.
The transition matrix makes it very easy to forecast the evolution of the distribution. Without proof, given \(\pi_t\) initial condition
\[ \begin{bmatrix}\mathbb{P}(X_{t+1} = x_1) &\ldots & \mathbb{P}(X_{t+1} = x_N)\end{bmatrix} \equiv \pi_{t+1} = \pi_t P \]
Inductively: for the matrix power (i.e. \(P \times P\times \ldots P\), not pointwise)
\[ \begin{bmatrix}\mathbb{P}(X_{t+j} = x_1) &\ldots & \mathbb{P}(X_{t+j} = x_N)\end{bmatrix} \equiv \pi_{t+j} = \pi_t P^j \]
Given the conditional probabilities, expectations are easy
Now assign \(X_t\) as a random variable with values \(x_1, \ldots x_N\) and pmf \(\pi_t\)
Define \(G \equiv \begin{bmatrix}x_1 & \ldots & x_N\end{bmatrix}\)
From definition of conditional expectations, where \(X_t\sim \mu_t\)
\[ \mathbb{E}[X_{t+j} \,|\, X_t] = \sum_{i=1}^N x_i \pi_{t+j,i} = G \cdot (\pi_t P^j) = G (\pi_t P^j)^{\top} \]
This works for enormous numbers of states \(N\), as long as \(P\) is sparse (i.e., the number of elements of \(P\) is significant)
\[ \mathbb{E}[X_{20} \,|\, X_0 = x_E] = G \cdot (\pi_0 P^{20}) \]
Take some \(X_t\) initial condition, does this converge?
\[ \lim_{j\to\infty} X_{t+j}\,|\,X_t = \lim_{j\to\infty} \pi_t \cdot P^j = \pi_{\infty}? \]
How does it compare to fixed point below, i.e. does \(\pi^{*} = \pi_{\infty}\) for all \(X_t\)?
\[ \pi^{*} = \pi^{*} \cdot P \]
pi_star = [0.6666666666666666, 0.3333333333333333]
pi_inf = [0.6666666666666629 0.33333333333333154]
Consider two states \(X_i\) and \(X_j\) ordered by indices \(i\) and \(j\) in \(P\),
If it is possible to move from \(X_i\) to \(X_j\) in a finite number of steps, the states are said to communicate
Formally, \(X_i\) and \(Y_j\) communicate if there exist \(l\) and \(m\) such that
\[ P^l_{ij} > 0 \quad \text{and} \quad P^m_{ji} > 0 \]
alpha, lambda = 0.3, 0.6
P = [1-alpha alpha; lambda 1-lambda]
mc = MarkovChain(P)
pi_star = stationary_distributions(mc)[1]
T = 1000
init=1
X = simulate(mc, T;init)
prop_E_t = cumsum(X.==1)./(1:length(X))
plot(1:T, prop_E_t, xlabel="t",
label=L"\frac{1}{t}\sum_{s=0}^t \mathbb{1}\{X_s = E\}",
size=(600, 400))
hline!([pi_star[1]]; label=L"\pi^{*}_E",
linestyle=:dash)
e.g. \(X_{t+1} = \rho X_t + \sigma w_{t+1}\) using Tauchen’s Method
lambda = 0.283
alpha = 0.013
T = 5000
# order U, E
P = [1-lambda lambda; alpha 1-alpha]
mc = MarkovChain(P)
@show stationary_distributions(mc)[1]
eigvals, eigvecs = eigen(P')
index = findfirst(x -> isapprox(x, 1), eigvals)
pi_star = real.(vec(eigvecs[:, index]))
pi_star = pi_star / sum(pi_star)
@show pi_star;
(stationary_distributions(mc))[1] = [0.043918918918918914, 0.956081081081081]
pi_star = [0.04391891891891895, 0.9560810810810811]
mc = MarkovChain(P, [0; 1]) # U -> 0, E -> 1
s_path = simulate(mc, T; init = 2)
u_bar, e_bar = stationary_distributions(mc)[1]
# Note mapping in MarkovChain
s_bar_e = cumsum(s_path) ./ (1:T)
s_bar_u = 1 .- s_bar_e
s_bars = [s_bar_u s_bar_e]
plot(title = "Percent of time unemployed",
1:T, s_bars[:, 1], lw = 2,
label=L"\frac{1}{t}\sum_{s=0}^t \mathbb{1}\{X_s = U\}",
legend=:topright, size=(600, 400))
hline!([u_bar], linestyle = :dash,
label = L"\pi^{*}_U")
To track distributions, a tight connection to the “adjoint” of the stochastic process for the Markov Chain
Instead, building it directly from flows, define
Of the mass of workers \(E_t\) who are employed at date \(t\),
\[ E_{t+1} = (1-d)(1-\alpha)E_t + (1-d)\lambda U_t \]
Of the mass of workers \(U_t\) workers who are currently unemployed,
\[ U_{t+1} = (1-d)\alpha E_t + (1-d)(1-\lambda)U_t + b (E_t+U_t) \]
The total stock of workers \(N_t=E_t+U_t\) evolves as
\[ N_{t+1} = (1+b-d)N_t = (1+g)N_t \]
Letting \(X_t \equiv \begin{bmatrix}U_t\\E_t\end{bmatrix}\), the law of motion for \(X\) is
\[ X_{t+1} = \underbrace{\begin{bmatrix} (1-d)(1-\lambda) + b & (1-d)\alpha + b \\ (1-d)\lambda & (1-d)(1-\alpha) \end{bmatrix}}_{\equiv A} X_t \]
Define \(x_t \equiv \begin{bmatrix}u_t\\e_t\end{bmatrix} = \begin{bmatrix}U_t/N_t\\E_t/N_t\end{bmatrix}\)
Divide both sides of \(X_{t+1} = A X_t\) by \(N_{t+1}\) and simplify to get \[ x_{t+1} = \underbrace{\frac{1}{1 + g} A}_{\equiv \hat{A}} x_t \]
function lake_model(; lambda = 0.283, alpha = 0.013, b = 0.0124, d = 0.00822)
g = b - d
A = [(1 - lambda) * (1 - d)+b (1 - d) * alpha+b
(1 - d)*lambda (1 - d)*(1 - alpha)]
A_hat = A ./ (1 + g)
x_0 = ones(size(A_hat, 1)) / size(A_hat, 1)
sol = fixedpoint(x -> A_hat * x, x_0)
converged(sol) || error("Failed to converge in $(sol.iterations) iter")
x_bar =sol.zero
return (; lambda, alpha, b, d, A, A_hat, x_bar)
end
lm = lake_model()
N_0 = 150
e_0 = 0.92
u_0 = 1 - e_0
T = 50
U_0 = u_0 * N_0
E_0 = e_0 * N_0
X_0 = [U_0; E_0]
X_path = iterate_map(X -> lm.A * X, X_0, T - 1)
x1 = X_path[1, :]
x2 = X_path[2, :]
plt_unemp = plot(1:T, X_path[1, :]; color = :blue,
label = L"U_t", xlabel="t", title = "Unemployment")
plt_emp = plot(1:T, X_path[2, :]; color = :blue,
label = L"E_t", xlabel="t", title = "Employment")
plot(plt_unemp, plt_emp, layout = (1, 2), size = (1200, 400))
u_bar, e_bar = lm.x_bar
x_0 = [u_0; e_0]
x_path = iterate_map(x -> lm.A_hat * x, x_0, T - 1)
plt_unemp = plot(1:T, x_path[1, :];title = "Unemployment rate",
color = :blue, label = L"u_t")
hline!(plt_unemp, [u_bar], color = :red, linestyle = :dash, label = L"\pi^{*}_U")
plt_emp = plot(1:T, x_path[2, :]; title = "Employment rate", color = :blue, label = L"e_t")
hline!(plt_emp, [e_bar], color = :red, linestyle = :dash,label = L"\pi^{*}_E")
plot(plt_unemp, plt_emp, layout = (1, 2), size = (1200, 400))