Skip to content

Commit 470e8c5

Browse files
committed
add a plot and make clear design
1 parent 3b03fbb commit 470e8c5

File tree

1 file changed

+75
-33
lines changed

1 file changed

+75
-33
lines changed

lectures/olg.md

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ kernelspec:
1212
---
1313

1414

15-
1615
# The Overlapping Generations Model
1716

1817
In this lecture we study the overlapping generations (OLG) model.
@@ -53,12 +52,12 @@ Let's start with some imports.
5352
import numpy as np
5453
from scipy import optimize
5554
from collections import namedtuple
55+
from functools import partial
5656
import matplotlib.pyplot as plt
5757
plt.rcParams["figure.figsize"] = (11, 5) #set default figure size
5858
```
5959

6060

61-
6261
## Environment
6362

6463
TODO add timing and basic ideas of OLG
@@ -275,10 +274,11 @@ Plugging it into either the demand or the supply function gives the equilibrium
275274
```
276275

277276
```{code-cell} ipython3
278-
Model = namedtuple('Model', ['α', # output elasticity of capital in the Cobb-Douglas production function
279-
'β', # discount factor
280-
'u', # parameter which defines the flow utility
281-
'L'] # population size
277+
Model = namedtuple('Model', ['α', # output elasticity of capital in the Cobb-Douglas production function
278+
'β', # discount factor
279+
'u', # parameter which defines the flow utility
280+
'L', # population size
281+
'u_params'] # other params used to define u
282282
)
283283
```
284284

@@ -288,8 +288,8 @@ def u(c):
288288
```
289289

290290
```{code-cell} ipython3
291-
def create_olg_model(α=0.3, β=0.9, u=u, L=10.0):
292-
return Model(α=α, β=β, u=u, L=L)
291+
def create_olg_model(α=0.3, β=0.9, u=u, L=10.0, u_params=dict()):
292+
return Model(α=α, β=β, u=u, L=L, u_params=u_params)
293293
```
294294

295295
```{code-cell} ipython3
@@ -360,7 +360,6 @@ plot_ad_as(aggregate_capital_demand, aggregate_capital_supply, m, K_prev=50, E_s
360360
```
361361

362362

363-
364363
Let's observe the dynamics of the equilibrium price $R^*_{t+1}$.
365364

366365
```{code-cell} ipython3
@@ -377,7 +376,6 @@ plt.show()
377376
```
378377

379378

380-
381379
## Dynamics and steady state
382380

383381
Let $k_t := K_t / L$.
@@ -479,7 +477,6 @@ plot_45(m, k_update, kstar=k_star(m))
479477
```
480478

481479

482-
483480
## Another special case: CRRA preference
484481

485482

@@ -492,11 +489,9 @@ def crra(c, γ=0.5):
492489
```
493490

494491
```{code-cell} ipython3
495-
m_crra = create_olg_model(u=crra)
492+
m_crra = create_olg_model(u=crra, u_params={'γ': 0.5})
496493
```
497494

498-
499-
500495
### New aggregate supply
501496

502497

@@ -560,7 +555,7 @@ Below we just show a plot of the equilibrium.
560555

561556
```{code-cell} ipython3
562557
def aggregate_supply_capital_crra(R, model, K_prev):
563-
α, β, γ, L = model.α, model.β, model.u.__defaults__[0], model.L
558+
α, β, γ, L = model.α, model.β, model.u_params['γ'], model.L
564559
return L**(1-α) * (1-α) * K_prev**α / ( 1 + β**(-1/γ) * R**((γ-1)/γ) )
565560
```
566561

@@ -569,12 +564,33 @@ plot_ad_as(aggregate_capital_demand, aggregate_supply_capital_crra, m_crra, K_pr
569564
```
570565

571566

567+
Let's plot the aggregate supply with different values of utility parameter $\gamma$ and observe it's behaviour.
568+
569+
```{code-cell} ipython3
570+
γ_vals = [0.1, 0.5, 1.5, 2.0]
571+
K_prev = 50
572+
573+
574+
fig, ax = plt.subplots()
575+
R_vals = np.linspace(0.3, 1)
576+
577+
for γ in γ_vals:
578+
m = create_olg_model(u=partial(crra, γ=γ), u_params={'γ': γ})
579+
ax.plot(R_vals, aggregate_supply_capital_crra(R_vals, m, K_prev),
580+
label=r"$\gamma=$" + str(γ))
581+
582+
ax.set_xlabel("$R_{t+1}$")
583+
ax.set_title("Aggregate Supply")
584+
ax.legend()
585+
plt.show()
586+
```
572587

573-
TODO add a discussion or plot about how the slope of aggregate supply for capital varies according to the utility parameter $\gamma$.
574588

575-
TODO When $\gamma <1$ the supply curve is downward sloping. When $\gamma >1$ the supply curve is upward sloping.
589+
When $\gamma <1$ the supply curve is downward sloping. When $\gamma > 1$ the supply curve is upward sloping.
576590

591+
TODO: Do we need to add some explanation?
577592

593+
+++
578594

579595
### Dynamics and steady state
580596

@@ -625,7 +641,7 @@ First let define $f(\cdot)$.
625641

626642
```{code-cell} ipython3
627643
def f(k_prime, k, model):
628-
α, β, γ = model.α, model.β, model.u.__defaults__[0]
644+
α, β, γ = model.α, model.β, model.u_params['γ']
629645
z = (1 - α) * k**α
630646
R1 = α ** (1-1/γ)
631647
R2 = k_prime**((α * γ - α + 1) / γ)
@@ -634,7 +650,6 @@ def f(k_prime, k, model):
634650
```
635651

636652

637-
638653
Let's define a function `k_next` that finds the value of $k_{t+1}$.
639654

640655
```{code-cell} ipython3
@@ -647,7 +662,6 @@ plot_45(m_crra, k_next, kstar=None)
647662
```
648663

649664

650-
651665
Unlike the log preference case now a steady state cannot be solved analytically.
652666

653667
To see this recall that, a steady state can be obtained by setting [](law_of_motion_capital_crra) to $k_{t+1} = k_t = k^*$, i.e.,
@@ -668,7 +682,7 @@ Suppose that
668682

669683
```{code-cell} ipython3
670684
def g(k_star, model):
671-
α, β, γ = model.α, model.β, model.u.__defaults__[0]
685+
α, β, γ = model.α, model.β, model.u_params['γ']
672686
z = (1 - α) * k_star**α
673687
R1 = α ** (1-1/γ)
674688
R2 = k_star**((α * γ - α + 1) / γ)
@@ -686,11 +700,10 @@ plot_45(m_crra, k_next, k_star)
686700
```
687701

688702

689-
690703
The next figure shows three time paths for capital, from
691704
three distinct initial conditions, under the parameterization listed above.
692705

693-
At this parameterization, $k^* \approx 0.161$.
706+
At this parameterization, $k^* \approx 0.314$.
694707

695708
Let's define the constants and three distinct intital conditions
696709

@@ -714,7 +727,7 @@ def simulate_ts(m, x0_values, ts_length):
714727
ts[t] = k_next(ts[t-1], m)
715728
ax.plot(np.arange(ts_length), ts, '-o', ms=4, alpha=0.6,
716729
label=r'$k_0=%g$' %x_init)
717-
ax.plot(np.arange(ts_length), np.full(ts_length,k_star),
730+
ax.plot(np.arange(ts_length), np.full(ts_length, k_star),
718731
alpha=0.6, color='red', label=r'$k^*$')
719732
ax.legend(fontsize=10)
720733
@@ -729,7 +742,6 @@ simulate_ts(m_crra, x0, ts_length)
729742
```
730743

731744

732-
733745
## Exercises
734746

735747

@@ -756,7 +768,7 @@ Similary, `find_Kstar` finds the equilibrium quantity $K^*_{t+1}$ using the valu
756768

757769
```{code-cell} ipython3
758770
def find_Rstar_newton(x, K_prev, model):
759-
α, β, γ, L = model.α, model.β, model.u.__defaults__[0], model.L
771+
α, β, γ, L = model.α, model.β, model.u_params['γ'], model.L
760772
lhs = L * (1-α) * (K_prev / L)**α
761773
lhs /= (1 + β**(-1/γ) * x**((γ-1)/γ))
762774
rhs = L * (x / α)**(1/(α-1))
@@ -771,6 +783,7 @@ def find_Kstar(R_star, model):
771783
return model.L * (R_star / model.α)**(1/(model.α-1))
772784
```
773785

786+
774787
The following function plots the equilibrium quantity and equilibrium price.
775788

776789
```{code-cell} ipython3
@@ -788,17 +801,28 @@ def plot_ks_rs(K_t_vals, model):
788801
ax.plot(K_t_vals, R_star, label="equilibrium price")
789802
ax.plot(K_t_vals, K_star, label="equilibrium quantity")
790803
791-
ax.set_xlabel("$K^{t}$")
804+
ax.set_xlabel("$K_{t}$")
792805
ax.legend()
793806
plt.show()
794807
```
795808

796809
```{code-cell} ipython3
810+
---
811+
mystnb:
812+
figure:
813+
caption: "Equilibrium price and quantity\n"
814+
name: equi_ps_q_crra
815+
image:
816+
alt: equi_ps_q_crra
817+
classes: shadow bg-primary
818+
width: 200px
819+
---
797820
K_t_vals = np.linspace(0.1, 50, 50)
798-
m_crra = create_olg_model(u=crra)
821+
m_crra = create_olg_model(u=crra, u_params={'γ': 0.5})
799822
plot_ks_rs(K_t_vals, m_crra)
800823
```
801824

825+
802826
```{solution-end}
803827
```
804828

@@ -848,11 +872,11 @@ def u_quasilinear(c, θ=4):
848872

849873
The function `find_k_next` is used to find $k_{t+1}$ by finding
850874
the root of equation [](euler_quasilinear1) using the helper
851-
function `solve_for_k_t1` for a given value of $k_t$.
875+
function `solve_for_k_next` for a given value of $k_t$.
852876

853877
```{code-cell} ipython3
854-
def solve_for_k_t1(x, k_t, model):
855-
α, β, L, θ = model.α, model.β, model.L, model.u.__defaults__[0]
878+
def solve_for_k_next(x, k_t, model):
879+
α, β, L, θ = model.α, model.β, model.L, model.u_params['θ']
856880
l = 1 + θ * ((1 - α) * k_t**α - x)**(θ - 1)
857881
r = β * α * k_t**(α - 1)
858882
r += β * (α * k_t**(α - 1))**θ * θ * x**(θ - 1)
@@ -861,14 +885,30 @@ def solve_for_k_t1(x, k_t, model):
861885

862886
```{code-cell} ipython3
863887
def find_k_next(k_t, model):
864-
return optimize.newton(solve_for_k_t1, k_t, args=(k_t, model))
888+
return optimize.newton(solve_for_k_next, k_t, args=(k_t, model))
889+
```
890+
891+
```{code-cell} ipython3
892+
def solve_for_k_star_q(x, model):
893+
α, β, L, θ = model.α, model.β, model.L, model.u_params['θ']
894+
l = 1 + θ * ((1 - α) * x**α - x)**(θ - 1)
895+
r = β * α * x**(α - 1)
896+
r += β * (α * x**(α - 1))**θ * θ * x**(θ - 1)
897+
return l - r
898+
899+
def find_k_star_q(model):
900+
return optimize.newton(solve_for_k_star_q, 0.3, args=(model,))
901+
865902
```
866903

904+
867905
Let's simulate and plot the time path capital $\{k_t\}$.
868906

869907
```{code-cell} ipython3
870908
def simulate_ts(k0_values, model, ts_length=10):
909+
k_star = find_k_star_q(model)
871910
911+
print("k_star:", k_star)
872912
fig, ax = plt.subplots(figsize=(10, 5))
873913
874914
ts = np.zeros(ts_length)
@@ -880,6 +920,8 @@ def simulate_ts(k0_values, model, ts_length=10):
880920
ts[t] = find_k_next(ts[t-1], model)
881921
ax.plot(np.arange(ts_length), ts, '-o', ms=4, alpha=0.6,
882922
label=r'$k_0=%g$' %x_init)
923+
ax.plot(np.arange(ts_length), np.full(ts_length, k_star),
924+
alpha=0.6, linestyle='dashed', color='black', label=r'$k^*$')
883925
ax.legend(fontsize=10)
884926
885927
ax.set_xlabel(r'$t$', fontsize=14)
@@ -890,7 +932,7 @@ def simulate_ts(k0_values, model, ts_length=10):
890932

891933
```{code-cell} ipython3
892934
k0_values = [0.2, 10, 50, 100]
893-
m_quasilinear = create_olg_model(u=u_quasilinear)
935+
m_quasilinear = create_olg_model(u=u_quasilinear, u_params={'θ': 4})
894936
simulate_ts(k0_values, m_quasilinear)
895937
```
896938

0 commit comments

Comments
 (0)