@@ -4,14 +4,13 @@ jupytext:
44 extension : .md
55 format_name : myst
66 format_version : 0.13
7- jupytext_version : 1.14.5
7+ jupytext_version : 1.16.1
88kernelspec :
99 display_name : Python 3 (ipykernel)
1010 language : python
1111 name : python3
1212---
1313
14- +++ {"user_expressions": [ ] }
1514
1615# Consumption Smoothing
1716
@@ -48,7 +47,6 @@ import matplotlib.pyplot as plt
4847from collections import namedtuple
4948```
5049
51- +++ {"user_expressions": [ ] }
5250
5351The model describes a consumer who lives from time $t=0, 1, \ldots, T$, receives a stream $\{ y_t\} _ {t=0}^T$ of non-financial income and chooses a consumption stream $\{ c_t\} _ {t=0}^T$.
5452
@@ -156,8 +154,6 @@ def creat_cs_model(R=1.05, g1=1, g2=1/2, T=65):
156154 β_seq=β_seq, T=65)
157155```
158156
159- +++ {"user_expressions": []}
160-
161157
162158## Friedman-Hall consumption-smoothing model
163159
@@ -206,7 +202,6 @@ $$ (eq:conssmoothing)
206202
207203Equation {eq}`eq:conssmoothing` is the consumption-smoothing model in a nutshell.
208204
209- +++ {"user_expressions": []}
210205
211206## Mechanics of Consumption smoothing model
212207
@@ -301,7 +296,7 @@ This can be interpreted as a student debt.
301296
302297The non-financial process $\{y_t\}_{t=0}^{T}$ is constant and positive up to $t=45$ and then becomes zero afterward.
303298
304- The drop in non-financial income late in life reflects retirement from work.
299+ The drop in non-financial income late in life reflects retirement from work.
305300
306301```{code-cell} ipython3
307302# Financial wealth
@@ -348,7 +343,138 @@ def welfare(model, c_seq):
348343print('Welfare:', welfare(cs_model, c_seq))
349344```
350345
351- +++ {"user_expressions": []}
346+ ### Experiments
347+
348+ In this section we experiment consumption smoothing behavior under different setups.
349+
350+ First we write a function `plot_cs` that generate graphs above based on a consumption smoothing model `cs_model`.
351+
352+ This helps us repeat the steps shown above
353+
354+ ```{code-cell} ipython3
355+ def plot_cs(model, # consumption smoothing model
356+ a0, # initial financial wealth
357+ y_seq # non-financial income process
358+ ):
359+
360+ # Compute optimal consumption
361+ c_seq, a_seq, h0 = compute_optimal(model, a0, y_seq)
362+
363+ # Sequence length
364+ T = cs_model.T
365+
366+ # Generate plot
367+ plt.plot(range(T+1), y_seq, label='non-financial income')
368+ plt.plot(range(T+1), c_seq, label='consumption')
369+ plt.plot(range(T+2), a_seq, label='financial wealth')
370+ plt.plot(range(T+2), np.zeros(T+2), '--')
371+
372+ plt.legend()
373+ plt.xlabel(r'$t$')
374+ plt.ylabel(r'$c_t,y_t,a_t$')
375+ plt.show()
376+ ```
377+
378+ #### Experiment 1: one-time gain/loss
379+
380+ We first assume a one-time windfall of $W_0$ in year 21 of the income sequence $y$.
381+
382+ We'll make $W_0$ big - positive to indicate a one-time windfall, and negative to indicate a one-time "disaster".
383+
384+ ```{code-cell} ipython3
385+ # Windfall W_0 = 20
386+ y_seq_pos = np.concatenate(
387+ [np.ones(21), np.array([20]), np.ones(44)])
388+
389+ plot_cs(cs_model, a0, y_seq_pos)
390+ ```
391+
392+ ```{code-cell} ipython3
393+ # Disaster W_0 = -20
394+ y_seq_neg = np.concatenate(
395+ [np.ones(21), np.array([-20]), np.ones(44)])
396+
397+ plot_cs(cs_model, a0, y_seq_neg)
398+ ```
399+
400+ #### Experiment 2: permanent wage gain/loss
401+
402+ Now we assume a permanent increase in income of $W$ in year 21 of the $y$-sequence.
403+
404+ Again we can study positive and negative cases
405+
406+ ```{code-cell} ipython3
407+ # Positive permanent income change W = 0.5 when t >= 21
408+ y_seq_pos = np.concatenate(
409+ [np.ones(21), np.repeat(1.5, 45)])
410+
411+ plot_cs(cs_model, a0, y_seq_pos)
412+ ```
413+
414+ ```{code-cell} ipython3
415+ # Negative permanent income change W = -0.5 when t >= 21
416+ y_seq_neg = np.concatenate(
417+ [np.ones(21), np.repeat(0.5, 45)])
418+
419+ plot_cs(cs_model, a0, y_seq_neg)
420+ ```
421+
422+ #### Experiment 3: a late starter
423+
424+ Now we simulate a $y$ sequence in which a person gets zero for 46 years, and then works and gets 1 for the last 20 years of life (a "late starter")
425+
426+ ```{code-cell} ipython3
427+ # Late starter
428+ y_seq_late = np.concatenate(
429+ [np.zeros(46), np.ones(20)])
430+
431+ plot_cs(cs_model, a0, y_seq_late)
432+ ```
433+
434+ #### Experiment 4: geometric earner
435+
436+ Now we simulate a geometric $y$ sequence in which a person gets $y_t = \lambda^t y_0$ in first 46 years.
437+
438+ We first experiment with $\lambda = 1.05$
439+
440+ ```{code-cell} ipython3
441+ # Geometric earner parameters where λ = 1.05
442+ λ = 1.05
443+ y_0 = 1
444+ t_max = 46
445+
446+ # Generate geometric y sequence
447+ geo_seq = λ ** np.arange(t_max) * y_0
448+ y_seq_geo = np.concatenate(
449+ [geo_seq, np.zeros(20)])
450+
451+ plot_cs(cs_model, a0, y_seq_geo)
452+ ```
453+
454+ Now we show the behavior when $\lambda = 0.95$
455+
456+ ```{code-cell} ipython3
457+ λ = 0.95
458+
459+ geo_seq = λ ** np.arange(t_max) * y_0
460+ y_seq_geo = np.concatenate(
461+ [geo_seq, np.zeros(20)])
462+
463+ plot_cs(cs_model, a0, y_seq_geo)
464+ ```
465+
466+ What happens when $\lambda$ is negative
467+
468+ ```{code-cell} ipython3
469+ λ = -0.05
470+
471+ geo_seq = λ ** np.arange(t_max) * y_0
472+ y_seq_geo = np.concatenate(
473+ [geo_seq, np.zeros(20)])
474+
475+ plot_cs(cs_model, a0, y_seq_geo)
476+ ```
477+
352478
353479### Feasible consumption variations
354480
@@ -435,7 +561,6 @@ def compute_variation(model, ξ1, ϕ, a0, y_seq, verbose=1):
435561 return cvar_seq
436562```
437563
438- +++ {"user_expressions": []}
439564
440565We visualize variations for $\xi_1 \in \{.01, .05\}$ and $\phi \in \{.95, 1.02\}$
441566
@@ -473,7 +598,6 @@ plt.ylabel(r'$c_t$')
473598plt.show()
474599```
475600
476- +++ {"user_expressions": []}
477601
478602We can even use the Python `np.gradient` command to compute derivatives of welfare with respect to our two parameters.
479603
@@ -498,7 +622,6 @@ def welfare_rel(ξ1, ϕ):
498622welfare_vec = np.vectorize(welfare_rel)
499623```
500624
501- +++ {"user_expressions": []}
502625
503626Then we can visualize the relationship between welfare and $\xi_1$ and compute its derivatives
504627
@@ -518,7 +641,6 @@ plt.xlabel(r'$\xi_1$')
518641plt.show()
519642```
520643
521- +++ {"user_expressions": []}
522644
523645The same can be done on $\phi$
524646
0 commit comments