@@ -3,6 +3,8 @@ jupytext:
33 text_representation :
44 extension : .md
55 format_name : myst
6+ format_version : 0.13
7+ jupytext_version : 1.17.2
68kernelspec :
79 display_name : Python 3
810 language : python
@@ -25,10 +27,9 @@ kernelspec:
2527
2628In addition to what's in Anaconda, this lecture will need the following libraries:
2729
28- ``` {code-cell} ipython
29- ---
30- tags: [hide-output]
31- ---
30+ ``` {code-cell} ipython3
31+ :tags: [hide-output]
32+
3233!pip install quantecon
3334```
3435
@@ -54,7 +55,7 @@ To solve the model we will use the endogenous grid method, which we found to be
5455
5556We'll need the following imports:
5657
57- ``` {code-cell} ipython
58+ ``` {code-cell} ipython3
5859import matplotlib.pyplot as plt
5960import numpy as np
6061from quantecon import MarkovChain
@@ -197,7 +198,7 @@ As shown in {cite}`ma2020income`,
197198
1981991 . For each $(a,z) \in \mathsf S$, a unique optimal consumption path from $(a,z)$ exists
1992001 . This path is the unique feasible path from $(a,z)$ satisfying the
200- Euler equality {eq}` eqeul0 ` and the transversality condition
201+ Euler equations {eq}` ee00 ` -{eq} ` ee01 ` and the transversality condition
201202
202203``` {math}
203204:label: eqtv
217218 a_{t+1} = R (a_t - c_t) + Y_{t+1}
218219$$
219220
220- satisfies both {eq}` eqeul0 ` and {eq}` eqtv ` , and hence is the unique optimal
221+ satisfies both the Euler equations {eq}` ee00 ` -{eq} ` ee01 ` and {eq}` eqtv ` , and hence is the unique optimal
221222path from $(a,z)$.
222223
223224Thus, to solve the optimization problem, we need to compute the policy $\sigma^* $.
306307
307308Here we build a class called ` IFP ` that stores the model primitives.
308309
309- ``` {code-cell} ipython
310+ ``` {code-cell} ipython3
310311class IFP(NamedTuple):
311312 R: float # Gross interest rate R = 1 + r
312313 β: float # Discount factor
@@ -340,16 +341,15 @@ with transition matrix $\Pi$.
340341
341342We define utility globally:
342343
343- ``` {code-cell} ipython
344+ ``` {code-cell} ipython3
344345# Define utility function derivatives
345346u_prime = lambda c, γ: c**(-γ)
346347u_prime_inv = lambda c, γ: c**(-1/γ)
347348```
348349
349-
350350### Solver
351351
352- ``` {code-cell} ipython
352+ ``` {code-cell} ipython3
353353def K(σ: jnp.ndarray, ifp: IFP) -> jnp.ndarray:
354354 """
355355 The Coleman-Reffett operator for the IFP model using the
@@ -423,9 +423,7 @@ def K(σ: jnp.ndarray, ifp: IFP) -> jnp.ndarray:
423423 return σ_new.T # Transpose to get (n_a, n_z)
424424```
425425
426-
427-
428- ``` {code-cell} ipython
426+ ``` {code-cell} ipython3
429427@jax.jit
430428def solve_model(ifp: IFP,
431429 σ_init: jnp.ndarray,
@@ -459,7 +457,7 @@ def solve_model(ifp: IFP,
459457
460458Let's road test the EGM code.
461459
462- ``` {code-cell} ipython
460+ ``` {code-cell} ipython3
463461ifp = create_ifp()
464462R, β, γ, Π, z_grid, asset_grid = ifp
465463σ_init = R * asset_grid[:, None] + y(z_grid)
@@ -468,8 +466,7 @@ R, β, γ, Π, z_grid, asset_grid = ifp
468466
469467Here's a plot of the optimal policy for each $z$ state
470468
471-
472- ``` {code-cell} ipython
469+ ``` {code-cell} ipython3
473470fig, ax = plt.subplots()
474471ax.plot(asset_grid, σ_star[:, 0], label='bad state')
475472ax.plot(asset_grid, σ_star[:, 1], label='good state')
@@ -478,8 +475,6 @@ ax.legend()
478475plt.show()
479476```
480477
481-
482-
483478### A Sanity Check
484479
485480One way to check our results is to
@@ -491,7 +486,7 @@ In this case, our income fluctuation problem is just a CRRA cake eating problem.
491486
492487Then the value function and optimal consumption policy are given by
493488
494- ``` {code-cell} ipython
489+ ``` {code-cell} ipython3
495490def c_star(x, β, γ):
496491 return (1 - β ** (1/γ)) * x
497492
@@ -502,7 +497,7 @@ def v_star(x, β, γ):
502497
503498Let's see if we match up:
504499
505- ``` {code-cell} ipython
500+ ``` {code-cell} ipython3
506501ifp_cake_eating = create_ifp(r=0.0, z_grid=(-jnp.inf, -jnp.inf))
507502R, β, γ, Π, z_grid, asset_grid = ifp_cake_eating
508503σ_init = R * asset_grid[:, None] + y(z_grid)
@@ -518,7 +513,6 @@ ax.legend()
518513plt.show()
519514```
520515
521-
522516This looks pretty good.
523517
524518
@@ -545,7 +539,7 @@ Your figure should show that higher interest rates boost savings and suppress co
545539
546540Here's one solution:
547541
548- ``` {code-cell} ipython
542+ ``` {code-cell} ipython3
549543# With β=0.98, we need R*β < 1, so r < 0.0204
550544r_vals = np.linspace(0, 0.015, 4)
551545
@@ -575,7 +569,7 @@ default parameters.
575569
576570The following figure is a 45 degree diagram showing the law of motion for assets when consumption is optimal
577571
578- ``` {code-cell} ipython
572+ ``` {code-cell} ipython3
579573ifp = create_ifp()
580574R, β, γ, Π, z_grid, asset_grid = ifp
581575σ_init = R * asset_grid[:, None] + y(z_grid)
@@ -630,7 +624,7 @@ Your task is to generate such a histogram.
630624
631625First we write a function to simulate many households in parallel using JAX.
632626
633- ``` {code-cell} ipython
627+ ``` {code-cell} ipython3
634628def compute_asset_stationary(ifp, σ_star, num_households=50_000, T=500, seed=1234):
635629 """
636630 Simulates num_households households for T periods to approximate
@@ -681,7 +675,7 @@ def compute_asset_stationary(ifp, σ_star, num_households=50_000, T=500, seed=12
681675
682676Now we call the function, generate the asset distribution and histogram it:
683677
684- ``` {code-cell} ipython
678+ ``` {code-cell} ipython3
685679ifp = create_ifp()
686680R, β, γ, Π, z_grid, asset_grid = ifp
687681σ_init = R * asset_grid[:, None] + y(z_grid)
@@ -738,7 +732,7 @@ stationary distribution given the interest rate.
738732
739733Here's one solution
740734
741- ``` {code-cell} ipython
735+ ``` {code-cell} ipython3
742736M = 25
743737# With β=0.98, we need R*β < 1, so R < 1/0.98 ≈ 1.0204, thus r < 0.0204
744738r_vals = np.linspace(0, 0.015, M)
0 commit comments