Skip to content

Commit 1e2d0d3

Browse files
jstacclaude
andauthored
Add labor income volatility analysis to IFP advanced lecture (#749)
Added a new exercise (Exercise 2) that analyzes how wealth inequality varies with labor income volatility (a_y), complementing the existing analysis of return volatility (a_r). Key findings: - Varying return volatility (a_r: 0.10 to 0.16) increases Gini from 0.19 to 0.79 - Varying labor income volatility (a_y: 0.125 to 0.20) only increases Gini from 0.18 to 0.19 - Demonstrates that capital income risk is a much more powerful driver of wealth inequality than labor income risk Also cleaned up the wealth distribution plotting code and removed diagnostic output. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent 57b1b34 commit 1e2d0d3

File tree

1 file changed

+97
-19
lines changed

1 file changed

+97
-19
lines changed

lectures/ifp_advanced.md

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -671,31 +671,24 @@ c_init = a_init
671671
a_vec, c_vec = solve_model_time_iter(ifp, a_init, c_init)
672672
assets = compute_asset_stationary(c_vec, a_vec, ifp, num_households=200_000)
673673
674-
# Diagnostic: Check extrapolation issues
675-
print(f"\n=== Grid and Asset Diagnostics ===")
676-
print(f"Grid max (s_grid[-1]): {ifp.s_grid[-1]:.2f}")
677-
print(f"Endogenous grid max (a_vec.max()): {a_vec.max():.2f}")
678-
print(f"Simulated assets max: {assets.max():.2f}")
679-
print(f"Simulated assets mean: {assets.mean():.2f}")
680-
print(f"Simulated assets median: {np.median(assets):.2f}")
681-
print(f"Fraction of households beyond grid: {(assets > a_vec.max()).mean():.4f}")
682-
print(f"Fraction beyond 0.9 * grid_max: {(assets > 0.9 * a_vec.max()).mean():.4f}")
683-
print()
684-
685674
# Compute Gini coefficient for the plot
686675
gini_plot = gini_coefficient(assets)
687676
688-
# Plot: Histogram with log-scale y-axis
677+
# Plot histogram of log wealth
689678
fig, ax = plt.subplots(figsize=(10, 6))
690-
ax.hist(assets, bins=40, alpha=0.5, density=True)
691-
ax.set_yscale('log')
692-
ax.set(xlabel='assets', ylabel='density (log scale)',
693-
title="Wealth Distribution")
679+
ax.hist(jnp.log(assets), bins=40, alpha=0.5, density=True)
680+
ax.set(xlabel='log assets', ylabel='density', title="Wealth Distribution")
694681
plt.tight_layout()
695682
plt.show()
696683
```
697684

698-
The histogram shows the wealth distribution with the y-axis on a log scale, allowing us to see both the mass of households at low wealth levels and the long right tail of the distribution.
685+
The histogram shows the distribution of log wealth.
686+
687+
Bearing in mind that we are looking at log values, the histogram suggests
688+
a long right tail of the distribution.
689+
690+
Below we examine this in more detail.
691+
699692

700693

701694
## Wealth Inequality
@@ -751,7 +744,7 @@ We loop over different values of `a_r`, solve the model for each, simulate the w
751744

752745
```{code-cell} ipython3
753746
# Range of a_r values to explore
754-
a_r_vals = np.linspace(0.10, 0.16, 7)
747+
a_r_vals = np.linspace(0.10, 0.16, 5)
755748
gini_vals = []
756749
757750
print("Computing Gini coefficients for different return volatilities...\n")
@@ -787,7 +780,7 @@ ax.plot(a_r_vals, gini_vals, 'o-', linewidth=2, markersize=8)
787780
ax.set(xlabel='Return volatility (a_r)',
788781
ylabel='Gini coefficient',
789782
title='Wealth Inequality vs Return Volatility')
790-
ax.axhline(y=0.8, color='r', linestyle='--', linewidth=1,
783+
ax.axhline(y=0.8, color='k', linestyle='--', linewidth=1,
791784
label='Empirical US Gini (~0.8)')
792785
ax.legend()
793786
plt.tight_layout()
@@ -803,5 +796,90 @@ high returns accumulate substantially more wealth than unlucky households,
803796
leading to greater inequality in the wealth distribution.
804797

805798

799+
```{solution-end}
800+
```
801+
802+
```{exercise}
803+
:label: ifp_advanced_ex2
804+
805+
Plot how the Gini coefficient varies with the volatility of labor income.
806+
807+
Specifically, compute the Gini coefficient for values of `a_y` ranging from
808+
0.125 to 0.20 and plot the results. Set `a_r=0.10` for this exercise.
809+
810+
What does this tell you about the relationship between labor income risk and
811+
wealth inequality? Can we achieve the same rise in inequality by varying labor
812+
income volatility as we can by varying return volatility?
813+
814+
```
815+
816+
```{solution-start} ifp_advanced_ex2
817+
:class: dropdown
818+
```
819+
820+
We loop over different values of `a_y`, solve the model for each, simulate the wealth distribution, and compute the Gini coefficient.
821+
822+
```{code-cell} ipython3
823+
# Range of a_y values to explore
824+
a_y_vals = np.linspace(0.125, 0.20, 5)
825+
gini_vals_y = []
826+
827+
print("Computing Gini coefficients for different labor income volatilities...\n")
828+
829+
for a_y in a_y_vals:
830+
print(f"a_y = {a_y:.3f}...", end=" ")
831+
832+
# Create model with this a_y value and a_r=0.10
833+
ifp_temp = create_ifp(a_y=a_y, a_r=0.10, grid_max=100)
834+
835+
# Solve the model
836+
s_grid_temp = ifp_temp.s_grid
837+
n_z_temp = len(ifp_temp.P)
838+
a_init_temp = s_grid_temp[:, None] * jnp.ones(n_z_temp)
839+
c_init_temp = a_init_temp
840+
a_vec_temp, c_vec_temp = solve_model_time_iter(
841+
ifp_temp, a_init_temp, c_init_temp, verbose=False
842+
)
843+
844+
# Simulate households
845+
assets_temp = compute_asset_stationary(
846+
c_vec_temp, a_vec_temp, ifp_temp, num_households=200_000
847+
)
848+
849+
# Compute Gini coefficient
850+
gini_temp = gini_coefficient(assets_temp)
851+
gini_vals_y.append(gini_temp)
852+
print(f"Gini = {gini_temp:.4f}")
853+
854+
# Plot the results
855+
fig, ax = plt.subplots(figsize=(10, 6))
856+
ax.plot(a_y_vals, gini_vals_y, 'o-', linewidth=2, markersize=8, color='green')
857+
ax.set(xlabel='Labor income volatility (a_y)',
858+
ylabel='Gini coefficient',
859+
title='Wealth Inequality vs Labor Income Volatility')
860+
ax.axhline(y=0.8, color='k', linestyle='--', linewidth=1,
861+
label='Empirical US Gini (~0.8)')
862+
ax.legend()
863+
plt.tight_layout()
864+
plt.show()
865+
```
866+
867+
The plot shows that wealth inequality increases with labor income volatility, but the effect is much weaker than the effect of return volatility.
868+
869+
Comparing the two exercises:
870+
871+
- When return volatility (`a_r`) varies from 0.10 to 0.16, the Gini coefficient rises dramatically from around 0.20 to 0.79
872+
- When labor income volatility (`a_y`) varies from 0.125 to 0.20, a similar amount in percentage terms, the Gini coefficient increases but by a much smaller amount
873+
874+
This suggests that capital income risk is a more important driver of wealth inequality than labor income risk.
875+
876+
The intuition is that wealth accumulation compounds over time: households who
877+
experience favorable returns on their assets can reinvest those returns, leading
878+
to exponential growth.
879+
880+
In contrast, labor income shocks, while they affect current consumption and
881+
savings, do not have the same compounding effect on wealth accumulation.
882+
883+
806884
```{solution-end}
807885
```

0 commit comments

Comments
 (0)