Skip to content

Commit 4a6dd4e

Browse files
committed
update numpy code to remove vectorizations
1 parent a2989a4 commit 4a6dd4e

File tree

1 file changed

+45
-111
lines changed

1 file changed

+45
-111
lines changed

lectures/equalizing_difference.md

+45-111
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ jupytext:
44
extension: .md
55
format_name: myst
66
format_version: 0.13
7-
jupytext_version: 1.14.4
7+
jupytext_version: 1.16.1
88
kernelspec:
99
display_name: Python 3 (ipykernel)
1010
language: python
@@ -29,7 +29,7 @@ To map Friedman's application into our model, think of our high school students
2929

3030
Our presentation is "incomplete" in the sense that it is based on a single equation that would be part of set equilibrium conditions of a more fully articulated model.
3131

32-
This ''equalizing difference'' equation determines a college, high-school wage ratio that equalizes present values of a high school educated worker and a college educated worker.
32+
This ''equalizing difference'' equation determines a college-high-school wage ratio that equalizes present values of a high school educated worker and a college educated worker.
3333

3434
The idea is that lifetime earnings somehow adjust to make a new high school worker indifferent between going to college and not going to college but instead going to work immmediately.
3535

@@ -50,6 +50,8 @@ As usual, we'll start by importing some Python modules.
5050
```{code-cell} ipython3
5151
import numpy as np
5252
import matplotlib.pyplot as plt
53+
from collections import namedtuple
54+
from sympy import Symbol, Lambda, symbols
5355
```
5456

5557
## The indifference condition
@@ -206,34 +208,34 @@ prominently including $\gamma_h, \gamma_c, R$.
206208
207209
Now let's write some Python code to compute $\phi$ and plot it as a function of some of its determinants.
208210
209-
210211
```{code-cell} ipython3
211-
class equalizing_diff:
212-
"""
213-
A class of the equalizing difference model
214-
"""
212+
# Define the namedtuple for the equalizing difference model
213+
EqDiffModel = namedtuple('EqDiffModel', 'R T γ_h γ_c w_h0 D π')
214+
215+
def create_edm(R=1.05, # Gross rate of return
216+
T=40, # Time horizon
217+
γ_h=1.01, # High-school wage growth
218+
γ_c=1.01, # College wage growth
219+
w_h0=1, # Initial wage (high school)
220+
D=10, # Cost for college
221+
π=None):
222+
223+
return EqDiffModel(R, T, γ_h, γ_c, w_h0, D, π)
224+
225+
def compute_gap(model):
226+
R, T, γ_h, γ_c, w_h0, D, π = model
227+
228+
A_h = (1 - (γ_h/R)**(T+1)) / (1 - γ_h/R)
229+
A_c = (1 - (γ_c/R)**(T-3)) / (1 - γ_c/R) * (γ_c/R)**4
215230
216-
def __init__(self, R, T, γ_h, γ_c, w_h0, D=0, π=None):
217-
# one switches to the weak model by setting π
218-
self.R, self.γ_h, self.γ_c, self.w_h0, self.D = R, γ_h, γ_c, w_h0, D
219-
self.T, self.π = T, π
231+
# Tweaked model
232+
if π is not None:
233+
A_c = π * A_c
220234
221-
def compute_gap(self):
222-
R, γ_h, γ_c, w_h0, D = self.R, self.γ_h, self.γ_c, self.w_h0, self.D
223-
T, π = self.T, self.π
224-
225-
A_h = (1 - (γ_h/R)**(T+1)) / (1 - γ_h/R)
226-
A_c = (1 - (γ_c/R)**(T-3)) / (1 - γ_c/R) * (γ_c/R)**4
227-
228-
# tweaked model
229-
if π!=None:
230-
A_c = π*A_c
231-
232-
ϕ = A_h/A_c + D/(w_h0*A_c)
233-
return ϕ
235+
ϕ = A_h / A_c + D / (w_h0 * A_c)
236+
return ϕ
234237
```
235238
236-
237239
Using vectorization instead of loops,
238240
we build some functions to help do comparative statics .
239241
@@ -242,75 +244,30 @@ For a given instance of the class, we want to recompute $\phi$ when one paramete
242244
Let's do an example.
243245
244246
```{code-cell} ipython3
245-
# ϕ_R
246-
def ϕ_R(mc, R_new):
247-
mc_new = equalizing_diff(R_new, mc.T, mc.γ_h, mc.γ_c, mc.w_h0, mc.D, mc.π)
248-
return mc_new.compute_gap()
249-
250-
ϕ_R = np.vectorize(ϕ_R)
251-
252-
# ϕ_γh
253-
def ϕ_γh(mc, γh_new):
254-
mc_new = equalizing_diff(mc.R, mc.T, γh_new, mc.γ_c, mc.w_h0, mc.D, mc.π)
255-
return mc_new.compute_gap()
256-
257-
ϕ_γh = np.vectorize(ϕ_γh)
258-
259-
# ϕ_γc
260-
def ϕ_γc(mc, γc_new):
261-
mc_new = equalizing_diff(mc.R, mc.T, mc.γ_h, γc_new, mc.w_h0, mc.D, mc.π)
262-
return mc_new.compute_gap()
247+
ex1 = create_edm()
248+
gap1 = compute_gap(ex1)
263249
264-
ϕ_γc = np.vectorize(ϕ_γc)
265-
266-
# ϕ_π
267-
def ϕ_π(mc, π_new):
268-
mc_new = equalizing_diff(mc.R, mc.T, mc.γ_h, mc.γ_c, mc.w_h0, mc.D, π_new)
269-
return mc_new.compute_gap()
270-
271-
ϕ_π = np.vectorize(ϕ_π)
272-
```
273-
274-
```{code-cell} ipython3
275-
# set benchmark parameters
276-
R = 1.05
277-
T = 40
278-
γ_h, γ_c = 1.01, 1.01
279-
w_h0 = 1
280-
D = 10
281-
282-
# create an instance
283-
ex1 = equalizing_diff(R=R, T=T, γ_h=γ_h, γ_c=γ_c, w_h0=w_h0, D=D)
284-
gap1 = ex1.compute_gap()
285-
286-
print(gap1)
250+
gap1
287251
```
288252
289253
Let's not charge for college and recompute $\phi$.
290254
291255
The initial college wage premium should go down.
292256
293-
294-
295-
296257
```{code-cell} ipython3
297258
# free college
298-
ex2 = equalizing_diff(R, T, γ_h, γ_c, w_h0, D=0)
299-
gap2 = ex2.compute_gap()
300-
print(gap2)
259+
ex2 = create_edm(D=0)
260+
gap2 = compute_gap(ex2)
261+
gap2
301262
```
302263
303-
304-
305264
Let us construct some graphs that show us how the initial college-high-school wage ratio $\phi$ would change if one of its determinants were to change.
306265
307-
Let's start with the gross interest rate $R$.
308-
309-
266+
Let's start with the gross interest rate $R$.
310267
311268
```{code-cell} ipython3
312269
R_arr = np.linspace(1, 1.2, 50)
313-
plt.plot(R_arr, φ_R(ex1, R_arr))
270+
plt.plot(R_arr, compute_gap(create_edm(R=R_arr)))
314271
plt.xlabel(r'$R$')
315272
plt.ylabel(r'wage gap')
316273
plt.show()
@@ -323,11 +280,12 @@ determinants of $\phi$.
323280
324281
```{code-cell} ipython3
325282
γc_arr = np.linspace(1, 1.2, 50)
326-
plt.plot(γc_arr, φ_γc(ex1, γc_arr))
283+
plt.plot(γc_arr, compute_gap(create_edm(γ_c=γc_arr)))
327284
plt.xlabel(r'$\gamma_c$')
328285
plt.ylabel(r'wage gap')
329286
plt.show()
330287
```
288+
331289
Notice how the intitial wage gap falls when the rate of growth $\gamma_c$ of college wages rises.
332290
333291
The wage gap falls to "equalize" the present values of the two types of career, one as a high school worker, the other as a college worker.
@@ -338,33 +296,31 @@ The following graph shows what happens.
338296
339297
```{code-cell} ipython3
340298
γh_arr = np.linspace(1, 1.1, 50)
341-
plt.plot(γh_arr, φ_γh(ex1, γh_arr))
299+
plt.plot(γh_arr, compute_gap(create_edm(γ_h=γh_arr)))
342300
plt.xlabel(r'$\gamma_h$')
343301
plt.ylabel(r'wage gap')
344302
plt.show()
345303
```
346304
347-
348305
## Entrepreneur-worker interpretation
349306
350307
Now let's adopt the entrepreneur-worker interpretation of our model.
351308
352-
If the probability that a new business succeeds is $.2$, let's compute the initial wage premium for successful entrepreneurs.
309+
If the probability that a new business succeeds is $0.2$, let's compute the initial wage premium for successful entrepreneurs.
353310
354311
```{code-cell} ipython3
355312
# a model of enterpreneur
356-
ex3 = equalizing_diff(R, T, γ_h, γ_c, w_h0, π=0.2)
357-
gap3 = ex3.compute_gap()
313+
ex3 = create_edm(π=0.2)
314+
gap3 = compute_gap(ex3)
358315
359-
print(gap3)
316+
gap3
360317
```
361318
362319
Now let's study how the initial wage premium for successful entrepreneurs depend on the success probability.
363320
364-
365321
```{code-cell} ipython3
366322
π_arr = np.linspace(0.2, 1, 50)
367-
plt.plot(π_arr, φ_π(ex3, π_arr))
323+
plt.plot(π_arr, compute_gap(create_edm(π=π_arr)))
368324
plt.ylabel(r'wage gap')
369325
plt.xlabel(r'$\pi$')
370326
plt.show()
@@ -388,16 +344,10 @@ But for a reader interested in how we can get Python to do all the hard work inv
388344
389345
We'll use the Python module 'sympy' to compute partial derivatives of $\phi$ with respect to the parameters that determine it.
390346
391-
Let's import key functions from sympy.
392-
393-
```{code-cell} ipython3
394-
from sympy import Symbol, Lambda, symbols
395-
```
396-
397347
Define symbols
398348
399349
```{code-cell} ipython3
400-
γ_h, γ_c, w_h0, D = symbols('\gamma_h, \gamma_h_c, w_0^h, D', real=True)
350+
γ_h, γ_c, w_h0, D = symbols('\gamma_h, \gamma_c, w_0^h, D', real=True)
401351
R, T = Symbol('R', real=True), Symbol('T', integer=True)
402352
```
403353
@@ -450,8 +400,6 @@ Now let's compute $\frac{\partial \phi}{\partial D}$ and then evaluate it at the
450400
451401
Thus, as with our earlier graph, we find that raising $R$ increases the initial college wage premium $\phi$.
452402
453-
+++
454-
455403
Compute $\frac{\partial \phi}{\partial T}$ and evaluate it a default parameters
456404
457405
```{code-cell} ipython3
@@ -469,8 +417,6 @@ We find that raising $T$ decreases the initial college wage premium $\phi$.
469417
470418
This is because college graduates now have longer career lengths to "pay off" the time and other costs they paid to go to college
471419
472-
+++
473-
474420
Let's compute $\frac{\partial \phi}{\partial γ_h}$ and evaluate it at default parameters.
475421
476422
```{code-cell} ipython3
@@ -486,8 +432,6 @@ Let's compute $\frac{\partial \phi}{\partial γ_h}$ and evaluate it at default p
486432
487433
We find that raising $\gamma_h$ increases the initial college wage premium $\phi$, as we did with our earlier graphical analysis.
488434
489-
+++
490-
491435
Compute $\frac{\partial \phi}{\partial γ_c}$ and evaluate it numerically at default parameter values
492436
493437
```{code-cell} ipython3
@@ -503,8 +447,6 @@ Compute $\frac{\partial \phi}{\partial γ_c}$ and evaluate it numerically at def
503447
504448
We find that raising $\gamma_c$ decreases the initial college wage premium $\phi$, as we did with our graphical analysis earlier
505449
506-
+++
507-
508450
Let's compute $\frac{\partial \phi}{\partial R}$ and evaluate it numerically at default parameter values
509451
510452
```{code-cell} ipython3
@@ -518,12 +460,4 @@ Let's compute $\frac{\partial \phi}{\partial R}$ and evaluate it numerically at
518460
ϕ_R_func(D_value, γ_h_value, γ_c_value, R_value, T_value, w_h0_value)
519461
```
520462
521-
+++ {"tags": []}
522-
523-
We find that raising the gross interest rate $R$ increases the initial college wage premium $\phi$, as we did with our graphical analysis earlier
524-
525-
526-
527-
```{code-cell} ipython3
528-
529-
```
463+
We find that raising the gross interest rate $R$ increases the initial college wage premium $\phi$, as we did with our graphical analysis earlier

0 commit comments

Comments
 (0)