This notebook develops two foundational models of intertemporal choice. Part I covers the Fisher two-period consumption problem: a consumer allocates resources across two periods of life, and the solution yields the Euler equation, the consumption function, and the principle of Fisherian separation. Part II extends the framework to include a labor-leisure choice, introducing Cobb-Douglas preferences over consumption and leisure and confronting the theory with the empirical puzzle of the intertemporal elasticity of labor supply.
The treatment follows Fisher (1930) for the basic framework, Samuelson (1937) for time-separable utility, Summers (1981) for the decomposition of interest rate effects, King et al. (1988) for the choice of preferences consistent with balanced growth, and Ramey & Francis (2009) for long-run evidence on leisure.
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
import sympy as sp
import pandas as pdfrom collections import namedtuple
FisherModel = namedtuple('FisherModel', ['b1', 'y1', 'y2', 'R', 'beta', 'rho'])
LaborModel = namedtuple('LaborModel', ['R', 'beta', 'eta_s', 'W1', 'W2'])Part I: The Fisher Two-Period Problem¶
Budget Constraints and Human Wealth¶
A consumer lives for two periods. In period 1 the consumer begins with bank balances and earns income . Total resources are split between consumption and end-of-period assets :
Assets earn a gross interest factor , so beginning-of-period-2 resources are . In the last period of life, the consumer spends everything: . Since for all , an additional unit of consumption always raises utility. It follows that the consumer exhausts all resources in the final period and both budget constraints bind at the optimum. The IBC therefore holds with equality.
Combining the two period budget constraints gives the intertemporal budget constraint (IBC):
The right-hand side is total wealth. It is convenient to define human wealth as the present discounted value of labor income:
so total wealth is .
def human_wealth(y1, y2, R):
"""Present discounted value of labor income."""
return y1 + y2 / R
def budget_set(b1, y1, y2, R, n_points=200):
"""Return (c1, c2) pairs on the intertemporal budget line."""
total_wealth = b1 + human_wealth(y1, y2, R)
c1 = np.linspace(0, total_wealth, n_points)
c2 = (total_wealth - c1) * R
return c1, c2Optimization and the Euler Equation¶
The consumer maximizes lifetime utility
subject to the IBC, where is the discount factor. The Lagrangian is
The first-order conditions and yield and . Eliminating produces the Euler equation:
The left side is the marginal utility cost of saving one more unit today. The right side is the discounted marginal utility benefit of consuming the gross return tomorrow. At the optimum, the consumer is indifferent at the margin between consuming today and saving for tomorrow.
# Symbolic derivation of the Euler equation
c1, c2, lam, R_s, beta_s, rho_s = sp.symbols(
'c_1 c_2 lambda R beta rho', positive=True
)
b1_s, h1_s = sp.symbols('b_1 h_1', positive=True)
# Lagrangian
L = sp.Function('u')(c1) + beta_s * sp.Function('u')(c2) + lam * (b1_s + h1_s - c1 - c2 / R_s)
# First-order conditions
foc1 = sp.diff(L, c1) # u'(c1) - lambda = 0
foc2 = sp.diff(L, c2) # beta*u'(c2) - lambda/R = 0
display(sp.Eq(foc1, 0), sp.Eq(foc2, 0))
# CRRA specialization: u(c) = c^(1-rho)/(1-rho)
u_crra = lambda c: c ** (1 - rho_s) / (1 - rho_s)
euler_crra = sp.Eq(c1 ** (-rho_s), R_s * beta_s * c2 ** (-rho_s))
growth = sp.solve(euler_crra, c2)[0] / c1
display(sp.Eq(c2 / c1, sp.simplify(growth)))
# Limit as rho -> 1 (log utility)
log_limit = sp.limit(R_s ** (-1) * (R_s * beta_s) ** (1 / rho_s), rho_s, 1)
print("lim_{rho->1} R^{-1}(R*beta)^{1/rho} =", log_limit)CRRA Utility¶
We specialize to constant relative risk aversion (CRRA) utility:
with marginal utility . Substituting into the Euler equation:
The parameter is the intertemporal elasticity of substitution (IES): it measures the percent change in the consumption ratio in response to a percent change in the intertemporal price .
The Consumption Function¶
Using the Euler equation to substitute in the IBC and solving for :
This is the consumption function: it maps total wealth and parameters to the optimal level of first-period consumption.
def consumption_growth(R, beta, rho):
"""Optimal ratio c2/c1 from the Euler equation with CRRA utility."""
return (R * beta) ** (1 / rho)
def consumption_function(b1, h1, R, beta, rho):
"""Optimal c1 from the two-period CRRA consumption problem."""
g = consumption_growth(R, beta, rho)
return (b1 + h1) / (1 + g / R)
def solve_two_period(b1, y1, y2, R, beta, rho):
"""Solve the two-period problem; return c1, c2, a1."""
h1 = human_wealth(y1, y2, R)
c1 = consumption_function(b1, h1, R, beta, rho)
a1 = b1 + y1 - c1
c2 = R * a1 + y2
return c1, c2, a1Fisherian Separation¶
A striking property of the solution is Fisherian separation: the growth rate of consumption depends only on , , and , not on the timing of income. Two consumers with the same total wealth but different income profiles will choose the same consumption levels.
model = FisherModel(b1=0, y1=100, y2=0, R=1.04, beta=0.96, rho=2.0)
R, beta, rho = model.R, model.beta, model.rho
# Three income profiles with identical total wealth
profiles = [
{"label": "All income in period 1", "b1": 0, "y1": 100, "y2": 0},
{"label": "Equal income", "b1": 0, "y1": 50, "y2": 52},
{"label": "All income in period 2", "b1": 0, "y1": 0, "y2": 104},
]
rows = []
for p in profiles:
h1 = human_wealth(p["y1"], p["y2"], R)
c1, c2, a1 = solve_two_period(p["b1"], p["y1"], p["y2"], R, beta, rho)
rows.append({"Profile": p["label"], "c1": c1, "c2": c2, "a1": a1, "h1": h1})
pd.DataFrame(rows).set_index("Profile").round(3)All three profiles yield the same , , confirming Fisherian separation.
Log Utility Special Case¶
When , CRRA utility reduces to . The consumption function simplifies to
which is independent of the interest rate . This happens because with log utility the income and substitution effects of a change in exactly offset each other. This simplification follows from the general formula by taking , since .
# Verify the log-utility formula
b1, y1, y2 = 0, 80, 40
R_test = 1.05
h1 = human_wealth(y1, y2, R_test)
c1_formula = (b1 + h1) / (1 + beta)
c1_general = consumption_function(b1, h1, R_test, beta, rho=1.0)
print(f"Log-utility formula: c1 = {c1_formula:.6f}")
print(f"General formula: c1 = {c1_general:.6f}")Fisher Diagram¶
The classic Fisher diagram plots the budget constraint in space together with indifference curves. We reproduce the analysis for two cases: income concentrated in period 1 (saver) and income concentrated in period 2 (borrower).
def indifference_curve(c1_grid, c_ref1, c_ref2, beta, rho):
"""Compute c2 on the indifference curve through (c_ref1, c_ref2)."""
if rho == 1.0:
target = np.log(c_ref1) + beta * np.log(c_ref2)
c2 = np.exp((target - np.log(c1_grid)) / beta)
else:
u = lambda c: c ** (1 - rho) / (1 - rho)
target = u(c_ref1) + beta * u(c_ref2)
c2 = np.empty_like(c1_grid)
for i, c1v in enumerate(c1_grid):
residual = target - u(c1v)
try:
c2[i] = optimize.brentq(
lambda c: u(c) * beta - residual, 1e-10, c_ref2 * 20
)
except ValueError:
c2[i] = np.nan
return c2
def fisher_diagram(b1, y1, y2, R_low, R_high, beta, rho, title=""):
"""Plot the Fisher diagram with two interest rates."""
fig, ax = plt.subplots(figsize=(7, 7))
# Budget lines
for R_val, ls, lbl in [(R_low, '-', f'$\\mathsf{{R}} = {R_low}$'),
(R_high, '--', f'$\\mathsf{{R}} = {R_high}$')]:
c1_line, c2_line = budget_set(b1, y1, y2, R_val)
ax.plot(c1_line, c2_line, 'k', ls=ls, lw=1.5, label=lbl)
# Optimal points
c1_A, c2_A, _ = solve_two_period(b1, y1, y2, R_low, beta, rho)
c1_C, c2_C, _ = solve_two_period(b1, y1, y2, R_high, beta, rho)
# Indifference curves
c1_grid = np.linspace(0.01, (b1 + human_wealth(y1, y2, R_high)) * 1.1, 500)
ic_A = indifference_curve(c1_grid, c1_A, c2_A, beta, rho)
ic_C = indifference_curve(c1_grid, c1_C, c2_C, beta, rho)
ax.plot(c1_grid, ic_A, 'b-', lw=1, alpha=0.6)
ax.plot(c1_grid, ic_C, 'r-', lw=1, alpha=0.6)
ax.plot(c1_A, c2_A, 'bo', ms=9, zorder=5, label=f'A ($c_1={c1_A:.1f}$)')
ax.plot(c1_C, c2_C, 'rs', ms=9, zorder=5, label=f'C ($c_1={c1_C:.1f}$)')
# Endowment point
ax.plot(b1 + y1, y2, 'k^', ms=10, zorder=5, label='Endowment')
ymax = max(c2_A, c2_C, y2) * 1.3
xmax = (b1 + human_wealth(y1, y2, R_low)) * 1.1
ax.set_xlim(0, xmax)
ax.set_ylim(0, ymax)
ax.set_xlabel('$c_1$')
ax.set_ylabel('$c_2$')
ax.legend(frameon=False, fontsize=9)
ax.grid(True, alpha=0.3)
if title:
ax.set_title(title)
plt.show()Case 1: Income in Period 1 (Saver)¶
When all income arrives in period 1, the consumer saves part of it. An increase in is unambiguously beneficial: the consumption possibility set expands.
fisher_diagram(b1=0, y1=100, y2=0, R_low=1.02, R_high=1.10,
beta=0.96, rho=2.0,
title="Income in period 1 (saver)")Case 2: Income in Period 2 (Borrower)¶
When income is concentrated in period 2, the consumer must borrow. An increase in is unambiguously harmful: the available consumption set shrinks.
fisher_diagram(b1=0, y1=0, y2=104, R_low=1.02, R_high=1.10,
beta=0.96, rho=2.0,
title="Income in period 2 (borrower)")Following Summers (1981), the effect of a change in on first-period consumption can be decomposed into three components:
Substitution effect: a higher makes future consumption cheaper, encouraging the consumer to shift spending toward period 2 ( falls).
Income effect: a higher makes savers richer, enabling more consumption in both periods ( rises for savers).
Human wealth effect: a higher reduces the present value of future income ( falls for anyone with ).
For most consumers, future labor income is the largest component of wealth, so the human wealth effect typically dominates.
Comparative Statics¶
How do , , and savings respond to changes in the interest rate? The answer depends critically on .
b1, y1, y2, beta = 0, 80, 40, 0.96
R_grid = np.linspace(1.0, 1.15, 200)
rho_values = [0.5, 1.0, 2.0, 5.0]
fig, axes = plt.subplots(1, 3, figsize=(14, 4.5))
for rho_val in rho_values:
results = np.array([solve_two_period(b1, y1, y2, R_val, beta, rho_val)
for R_val in R_grid])
axes[0].plot(R_grid, results[:, 0], lw=2, label=rf'$\rho = {rho_val}$')
axes[1].plot(R_grid, results[:, 1], lw=2)
axes[2].plot(R_grid, results[:, 2], lw=2)
titles = ['$c_1$', '$c_2$', '$a_1 = b_1 + y_1 - c_1$']
for ax, t in zip(axes, titles):
ax.set_xlabel(r'$\mathsf{R}$')
ax.set_ylabel(t)
ax.grid(True, alpha=0.3)
axes[0].legend(frameon=False, fontsize=9)
fig.tight_layout()
plt.show()When is small (high IES), the substitution effect dominates: falls sharply as rises. When is large (low IES), income and human wealth effects dominate: is relatively insensitive to , or may even increase.
Part II: Consumption and Labor Supply¶
Intratemporal Choice¶
Now suppose the consumer also chooses how much to work. Utility depends on consumption and leisure :
Time is normalized so that , where is labor supply. The wage per unit of labor is , so labor income is .
Given total expenditure in period , the static budget constraint is
The price of leisure is the wage : each unit of leisure costs the consumer in foregone earnings. The first-order condition for the optimal leisure choice is
The wage equals the marginal rate of substitution between leisure and consumption.
Cobb-Douglas Preferences¶
Assume an “outer” utility function that depends on a Cobb-Douglas aggregate of consumption and leisure:
where is the leisure share. Define . Substituting into the Cobb-Douglas composite and differentiating with respect to , the first-order condition equates with . Simplifying yields
# Symbolic derivation: Cobb-Douglas FOC => W*z = eta*c
c_s, z_s, W_s, eta_s_sym = sp.symbols('c z W eta_s', positive=True)
eta_sym = eta_s_sym / (1 - eta_s_sym)
x_s = c_s + W_s * z_s # total expenditure
# Cobb-Douglas composite
composite = c_s ** (1 - eta_s_sym) * z_s ** eta_s_sym
# Differentiate composite w.r.t. z, set MRS = W
MU_z = sp.diff(composite, z_s)
MU_c = sp.diff(composite, c_s)
foc_ratio = sp.simplify(MU_z / MU_c)
display(sp.Eq(W_s, foc_ratio))
# Solve for W*z in terms of c
sol = sp.solve(sp.Eq(W_s, foc_ratio), W_s * z_s)
display(sp.Eq(W_s * z_s, sp.simplify(eta_s_sym / (1 - eta_s_sym) * c_s)))Spending on leisure is a constant fraction of consumption spending. Substituting back, utility becomes .
Constant Leisure Share¶
The Cobb-Douglas specification implies that the fraction of time spent in leisure does not depend on the level of wages. To see this, consider a single-period model where the budget constraint is . Then and , a constant.
This is the key reason for adopting Cobb-Douglas inner preferences: Ramey & Francis (2009) document that the fraction of time Americans spend working has changed little over a century of rising wages. King et al. (1988) show that other functional forms would produce counterfactual trends in leisure.
eta_s = 0.4 # leisure share parameter
eta = eta_s / (1 - eta_s)
W_grid = np.linspace(5, 50, 200)
z_star = eta / (1 + eta)
c_star = W_grid / (1 + eta)
fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
axes[0].plot(W_grid, c_star, lw=2, color='steelblue')
axes[0].set_xlabel(r'Wage $\mathsf{W}$')
axes[0].set_ylabel('$c$')
axes[0].set_title('Consumption rises with wages')
axes[0].grid(True, alpha=0.3)
axes[1].axhline(z_star, lw=2, color='indianred',
label=rf'$z = \eta/(1+\eta) = {z_star:.3f}$')
axes[1].set_xlabel(r'Wage $\mathsf{W}$')
axes[1].set_ylabel('$z$ (leisure)')
axes[1].set_title('Leisure is constant')
axes[1].set_ylim(0, 1)
axes[1].legend(frameon=False)
axes[1].grid(True, alpha=0.3)
fig.tight_layout()
plt.show()Two-Period Lifetime with Labor¶
Now embed the intratemporal choice in a two-period lifetime. The consumer maximizes
subject to the lifetime budget constraint
With the CRRA outer function and Cobb-Douglas inner preferences, the Euler equation for consumption becomes
Consumption growth depends not only on but also on wage growth . To derive this expression, note that the Cobb-Douglas utility simplification gives as the marginal utility of . The Euler equation is . Rearranging for yields (19).
Log Utility and Labor Supply¶
With log utility (), the wage-growth term in (19) vanishes and regardless of wage growth. This is Fisherian separation for the consumption profile.
Using , the leisure profile satisfies
Leisure in period 2 relative to period 1 falls when wages grow (), meaning labor supply rises. Intuitively, you work harder when work pays better.
def labor_supply_log(ell1, R, beta, W1, W2):
"""Period-2 labor supply under log utility given period-1 labor supply."""
z1 = 1 - ell1
z2 = z1 * R * beta * W1 / W2
return np.clip(1 - z2, 0, 1) # bound labor supply to [0, 1]
# Baseline: R*beta = 1, W2/W1 = 1 => ell2 = ell1
labor_model = LaborModel(R=1.04, beta=1 / 1.04, eta_s=0.4, W1=1.0, W2=1.0)
ell1 = 0.5
R, beta = labor_model.R, labor_model.beta
Wgrowth_grid = np.linspace(1.0, 4.0, 200)
ell2_vals = np.array([labor_supply_log(ell1, R, beta, 1.0, Wg)
for Wg in Wgrowth_grid])
fig, ax = plt.subplots(figsize=(7, 4.5))
ax.plot(Wgrowth_grid, ell2_vals, lw=2, color='steelblue',
label=r'$\ell_2$')
ax.axhline(ell1, ls='--', color='gray', alpha=0.6, label=r'$\ell_1 = 0.5$')
ax.set_xlabel(r'Wage growth $\mathsf{W}_2 / \mathsf{W}_1$')
ax.set_ylabel('Labor supply')
ax.legend(frameon=False)
ax.grid(True, alpha=0.3)
ax.set_title(r'Period-2 labor supply vs wage growth ($\mathsf{R}\beta=1$)')
plt.show()The Intertemporal Elasticity of Labor Supply Puzzle¶
Assume and . Under log utility, equation (20) with gives
Empirically, wages in the U.S. grow by a factor of to 4 between youth and middle age (depending on occupation and education), yet labor supply is roughly constant across these ages.
ell1 = 0.5
rows = []
for Gamma in [1.0, 1.5, 2.0, 3.0, 4.0]:
ell2 = 1 - 0.5 / Gamma
rows.append({"Gamma (wage growth)": Gamma, "ell2 (theory)": ell2, "ell1": ell1, "Delta ell": ell2 - ell1})
pd.DataFrame(rows).set_index("Gamma (wage growth)").round(3)With , the theory predicts , meaning workers spend 75% of their time working in middle age, compared to 50% in youth. With , the prediction is . These predictions are far from the data: labor supply varies little with age despite large predictable changes in wages.
Variation Across Occupations¶
Suppose aggregate wage growth is and we set (so ) to match the fact that average consumption doubles. For occupation with relative wage growth , the effective wage growth is and
ell1 = 0.5
Gamma_values = [0.5, 0.75, 1.0, 1.25, 1.5]
labels = ["Manual laborer", "Service worker", "Average",
"Professional", "Doctor/Lawyer"]
rows = []
for label, Gi in zip(labels, Gamma_values):
z2 = (1 - ell1) / Gi
ell2 = 1 - z2
rows.append({"Occupation": label, "Gamma_i": Gi, "ell2": round(ell2, 3) if ell2 > 0 else "<= 0 (!)"})
pd.DataFrame(rows).set_index("Occupation")For manual laborers (), the theory predicts : they would stop working entirely in middle age. For doctors (), : they would work much harder. In reality, labor supply varies little across occupations at any given age.
This is the intertemporal elasticity of labor supply puzzle: the theory with log utility (IES = 1) predicts enormous variation in labor supply in response to predictable wage variation, while the data show very little.
fig, ax = plt.subplots(figsize=(8, 5))
Gamma_i_grid = np.linspace(0.3, 2.0, 200)
ell2_theory = 1 - (1 - ell1) / Gamma_i_grid
ax.plot(Gamma_i_grid, ell2_theory, lw=2, color='steelblue',
label=r'Theory: $\ell_2 = 1 - (1-\ell_1)/\Gamma_i$')
ax.axhline(ell1, ls='--', color='gray', alpha=0.6,
label=r'$\ell_1 = 0.5$')
ax.axhline(ell1, ls=':', lw=3, color='indianred', alpha=0.5,
label=r'Data: $\ell_2 \approx \ell_1$ (stylized)')
# Mark specific occupations
for Gi, lbl in [(0.5, 'Manual'), (1.0, 'Average'), (1.5, 'Doctor')]:
ell2_pt = 1 - (1 - ell1) / Gi
ax.plot(Gi, ell2_pt, 'ko', ms=7, zorder=5)
ax.annotate(lbl, (Gi, ell2_pt), textcoords="offset points",
xytext=(8, -12), fontsize=9)
ax.set_xlabel(r'Occupation-specific wage growth factor $\Gamma_i$')
ax.set_ylabel(r'Period-2 labor supply $\ell_2$')
ax.set_ylim(-0.1, 1.1)
ax.legend(frameon=False, fontsize=9, loc='lower right')
ax.grid(True, alpha=0.3)
ax.set_title('Intertemporal Elasticity of Labor Supply Puzzle')
plt.show()Exercises¶
Solution to Exercise 1
beta = 0.96
R_grid = np.linspace(0.98, 1.15, 200)
fig, ax = plt.subplots(figsize=(7, 5))
for rho_val in [0.5, 1.0, 2.0, 5.0]:
growth = (R_grid * beta) ** (1 / rho_val)
ax.plot(R_grid, growth, lw=2, label=rf'$\rho = {rho_val}$ (IES $= {1/rho_val:.1f}$)')
ax.set_xlabel(r'$\mathsf{R}$')
ax.set_ylabel(r'$c_2 / c_1$')
ax.legend(frameon=False, fontsize=9)
ax.grid(True, alpha=0.3)
ax.set_title('Consumption growth vs interest rate')
plt.show()Lower means a higher IES (), so consumption growth responds more elastically to . With (IES = 2), a 1% increase in raises by about 2%. With (IES = 0.2), the same 1% increase raises by only 0.2%.
Solution to Exercise 2
R, beta, rho = 1.04, 0.96, 2.0
total_h = 100.0
y1_grid = np.linspace(0, total_h, 11)
y2_grid = (total_h - y1_grid) * R
fig, ax = plt.subplots(figsize=(7, 4.5))
c1_vals = []
for y1v, y2v in zip(y1_grid, y2_grid):
c1v, _, _ = solve_two_period(0, y1v, y2v, R, beta, rho)
c1_vals.append(c1v)
ax.plot(y1_grid, c1_vals, 'o-', lw=2, ms=6)
ax.set_xlabel('$y_1$')
ax.set_ylabel('$c_1$')
ax.set_title(f'$c_1$ is constant at {c1_vals[0]:.4f} regardless of income timing')
ax.grid(True, alpha=0.3)
plt.show()All points lie on a horizontal line, confirming that depends only on total wealth , not on the income split.
Solution to Exercise 3
ell1 = 0.5
fig, ax = plt.subplots(figsize=(7, 5))
Gamma_vals = [1.0, 1.5, 2.0, 3.0, 4.0]
ell2_vals = [1 - 0.5 / G for G in Gamma_vals]
bars = ax.bar([f'$\\Gamma = {G}$' for G in Gamma_vals], ell2_vals,
color=['#2196F3', '#4CAF50', '#FF9800', '#F44336', '#9C27B0'],
width=0.5)
ax.axhline(ell1, ls='--', color='k', alpha=0.5, label=r'$\ell_1 = 0.5$')
for bar, v in zip(bars, ell2_vals):
ax.text(bar.get_x() + bar.get_width() / 2, v + 0.02,
f'{v:.3f}', ha='center', fontsize=10)
ax.set_ylabel(r'$\ell_2$')
ax.set_ylim(0, 1.05)
ax.legend(frameon=False)
ax.grid(True, alpha=0.3, axis='y')
ax.set_title('Predicted period-2 labor supply')
plt.tight_layout()
plt.show()The contradiction grows with . At , the model predicts , meaning the consumer works 87.5% of available time, a dramatic increase from 50% in youth. Empirically, labor supply barely changes. This illustrates the intertemporal elasticity of labor supply puzzle: the model’s implied elasticity far exceeds what is observed.
Solution to Exercise 4
ell1 = 0.5
Gamma_i_vals = [0.5, 0.75, 1.0, 1.25, 1.5]
occ_labels = ["Manual\nlaborer", "Service\nworker", "Average",
"Professional", "Doctor/\nLawyer"]
ell2_occ = [max(1 - (1 - ell1) / Gi, 0) for Gi in Gamma_i_vals]
fig, ax = plt.subplots(figsize=(8, 5))
colors = ['#F44336', '#FF9800', '#4CAF50', '#2196F3', '#9C27B0']
bars = ax.bar(occ_labels, ell2_occ, color=colors, width=0.5)
ax.axhline(ell1, ls='--', color='k', alpha=0.5,
label=r'$\ell_1 = 0.5$ (all occupations)')
for bar, v in zip(bars, ell2_occ):
ax.text(bar.get_x() + bar.get_width() / 2, v + 0.02,
f'{v:.2f}', ha='center', fontsize=10)
ax.set_ylabel(r'$\ell_2$ (middle age)')
ax.set_ylim(0, 1.05)
ax.legend(frameon=False, fontsize=9)
ax.grid(True, alpha=0.3, axis='y')
ax.set_title(r'Cross-occupation variation in middle-age labor supply ($\Gamma = 2$)')
plt.tight_layout()
plt.show()The model predicts enormous cross-occupation variation: manual laborers () would work 0% of the time in middle age, while doctors () would work 67%. In reality, labor supply at any given age varies little across occupations. This is further evidence that the log-utility model’s implied intertemporal elasticity of labor supply is far too large.
- Fisher, I. (1930). The Theory of Interest. Macmillan.
- Samuelson, P. A. (1937). A Note on Measurement of Utility. Review of Economic Studies, 4(2), 155–161.
- Summers, L. H. (1981). Capital Taxation and Accumulation in a Life Cycle Growth Model. American Economic Review, 71(4), 533–544.
- King, R. G., Plosser, C. I., & Rebelo, S. T. (1988). Production, Growth and Business Cycles: I. The Basic Neoclassical Model. Journal of Monetary Economics, 21(2–3), 195–232.
- Ramey, V. A., & Francis, N. (2009). A Century of Work and Leisure. American Economic Journal: Macroeconomics, 1(2), 189–224.