In this lecture we describe the structure of a class of models that build on work by Truman Bewley [Bew77]
We begin by discussing an example of a Bewley model due to Rao Aiyagari
The model features
The Aiyagari model has been used to investigate many topics, including
Infinitely lived households / consumers face idiosyncratic income shocks
A unit interval of ex ante identical households face a common borrowing constraint
The savings problem faced by a typical household is
$$ \max \mathbb E \sum_{t=0}^{\infty} \beta^t u(c_t) $$subject to
$$ a_{t+1} + c_t \leq w z_t + (1 + r) a_t \quad c_t \geq 0, \quad \text{and} \quad a_t \geq -B $$where
The exogenous process $ \{z_t\} $ follows a finite state Markov chain with given stochastic matrix $ P $
The wage and interest rate are fixed over time
In this simple version of the model, households supply labor inelastically because they do not value leisure
Firms produce output by hiring capital and labor
Firms act competitively and face constant returns to scale
Since returns to scale are constant the number of firms does not matter
Hence we can consider a single (but nonetheless competitive) representative firm
The firm’s output is
$$ Y_t = A K_t^{\alpha} N^{1 - \alpha} $$where
The firm’s problem is
$$ max_{K, N} \left\{ A K_t^{\alpha} N^{1 - \alpha} - (r + \delta) K - w N \right\} $$The parameter $ \delta $ is the depreciation rate
From the first-order condition with respect to capital, the firm’s inverse demand for capital is
$$ r = A \alpha \left( \frac{N}{K} \right)^{1 - \alpha} - \delta \tag{1} $$
Using this expression and the firm’s first-order condition for labor, we can pin down the equilibrium wage rate as a function of $ r $ as
$$ w(r) = A (1 - \alpha) (A \alpha / (r + \delta))^{\alpha / (1 - \alpha)} \tag{2} $$
We construct a stationary rational expectations equilibrium (SREE)
In such an equilibrium
In more detail, an SREE lists a set of prices, savings and production policies such that
In practice, once parameter values are set, we can check for an SREE by the following steps
If this final quantity agrees with $ K $ then we have a SREE
Let’s look at how we might compute such an equilibrium in practice
To solve the household’s dynamic programming problem we’ll use the DiscreteDP type from QuantEcon.jl
Our first task is the least exciting one: write code that maps parameters for a household problem into the R
and Q
matrices needed to generate an instance of DiscreteDP
Below is a piece of boilerplate code that does just this
In reading the code, the following information will be helpful
R
needs to be a matrix where R[s, a]
is the reward at state s
under action a
Q
needs to be a three dimensional array where Q[s, a, s']
is the probability of transitioning to state s'
when the current state is s
and the current action is a
(For a detailed discussion of DiscreteDP
see this lecture)
Here we take the state to be $ s_t := (a_t, z_t) $, where $ a_t $ is assets and $ z_t $ is the shock
The action is the choice of next period asset level $ a_{t+1} $
The object also includes a default set of parameters that we’ll adopt unless otherwise specified
using InstantiateFromURL
github_project("QuantEcon/quantecon-notebooks-julia", version = "0.2.0")
using LinearAlgebra, Statistics, Compat
using Parameters, Plots, QuantEcon
gr(fmt = :png);
Household = @with_kw (r = 0.01,
w = 1.0,
σ = 1.0,
β = 0.96,
z_chain = MarkovChain([0.9 0.1; 0.1 0.9], [0.1; 1.0]),
a_min = 1e-10,
a_max = 18.0,
a_size = 200,
a_vals = range(a_min, a_max, length = a_size),
z_size = length(z_chain.state_values),
n = a_size * z_size,
s_vals = gridmake(a_vals, z_chain.state_values),
s_i_vals = gridmake(1:a_size, 1:z_size),
u = σ == 1 ? x -> log(x) : x -> (x^(1 - σ) - 1) / (1 - σ),
R = setup_R!(fill(-Inf, n, a_size), a_vals, s_vals, r, w, u),
# -Inf is the utility of dying (0 consumption)
Q = setup_Q!(zeros(n, a_size, n), s_i_vals, z_chain))
function setup_Q!(Q, s_i_vals, z_chain)
for next_s_i in 1:size(Q, 3)
for a_i in 1:size(Q, 2)
for s_i in 1:size(Q, 1)
z_i = s_i_vals[s_i, 2]
next_z_i = s_i_vals[next_s_i, 2]
next_a_i = s_i_vals[next_s_i, 1]
if next_a_i == a_i
Q[s_i, a_i, next_s_i] = z_chain.p[z_i, next_z_i]
end
end
end
end
return Q
end
function setup_R!(R, a_vals, s_vals, r, w, u)
for new_a_i in 1:size(R, 2)
a_new = a_vals[new_a_i]
for s_i in 1:size(R, 1)
a = s_vals[s_i, 1]
z = s_vals[s_i, 2]
c = w * z + (1 + r) * a - a_new
if c > 0
R[s_i, new_a_i] = u(c)
end
end
end
return R
end
As a first example of what we can do, let’s compute and plot an optimal accumulation policy at fixed prices
# Create an instance of Household
am = Household(a_max = 20.0, r = 0.03, w = 0.956)
# Use the instance to build a discrete dynamic program
am_ddp = DiscreteDP(am.R, am.Q, am.β)
# Solve using policy function iteration
results = solve(am_ddp, PFI)
# Simplify names
@unpack z_size, a_size, n, a_vals = am
z_vals = am.z_chain.state_values
# Get all optimal actions across the set of
# a indices with z fixed in each column
a_star = reshape([a_vals[results.sigma[s_i]] for s_i in 1:n], a_size, z_size)
labels = ["z = z_vals[1]", "z = z_vals[2]"]
plot(a_vals, a_star, label = labels, lw = 2, alpha = 0.6)
plot!(a_vals, a_vals, label = "", color = :black, linestyle = :dash)
plot!(xlabel = "current assets", ylabel = "next period assets", grid = false)
The plot shows asset accumulation policies at different values of the exogenous state
Now we want to calculate the equilibrium
Let’s do this visually as a first pass
The following code draws aggregate supply and demand curves
The intersection gives equilibrium interest rates and capital
# Firms' parameters
const A = 1
const N = 1
const α = 0.33
const β = 0.96
const δ = 0.05
function r_to_w(r)
return A * (1 - α) * (A * α / (r + δ)) ^ (α / (1 - α))
end
function rd(K)
return A * α * (N / K) ^ (1 - α) - δ
end
function prices_to_capital_stock(am, r)
# Set up problem
w = r_to_w(r)
@unpack a_vals, s_vals, u = am
setup_R!(am.R, a_vals, s_vals, r, w, u)
aiyagari_ddp = DiscreteDP(am.R, am.Q, am.β)
# Compute the optimal policy
results = solve(aiyagari_ddp, PFI)
# Compute the stationary distribution
stationary_probs = stationary_distributions(results.mc)[:, 1][1]
# Return K
return dot(am.s_vals[:, 1], stationary_probs)
end
# Create an instance of Household
am = Household(β = β, a_max = 20.0)
# Create a grid of r values at which to compute demand and supply of capital
r_vals = range(0.005, 0.04, length = 20)
# Compute supply of capital
k_vals = prices_to_capital_stock.(Ref(am), r_vals)
# Plot against demand for capital by firms
demand = rd.(k_vals)
labels = ["demand for capital" "supply of capital"]
plot(k_vals, [demand r_vals], label = labels, lw = 2, alpha = 0.6)
plot!(xlabel = "capital", ylabel = "interest rate", xlim = (2, 14), ylim = (0.0, 0.1))