-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[equalizing_difference] Update numpy
code in to remove vectorization
#388
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ jupytext: | |
extension: .md | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.14.4 | ||
jupytext_version: 1.16.1 | ||
kernelspec: | ||
display_name: Python 3 (ipykernel) | ||
language: python | ||
|
@@ -29,7 +29,7 @@ To map Friedman's application into our model, think of our high school students | |
|
||
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. | ||
|
||
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. | ||
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. | ||
|
||
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. | ||
|
||
|
@@ -50,6 +50,8 @@ As usual, we'll start by importing some Python modules. | |
```{code-cell} ipython3 | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
from collections import namedtuple | ||
from sympy import Symbol, Lambda, symbols | ||
``` | ||
|
||
## The indifference condition | ||
|
@@ -206,34 +208,34 @@ prominently including $\gamma_h, \gamma_c, R$. | |
|
||
Now let's write some Python code to compute $\phi$ and plot it as a function of some of its determinants. | ||
|
||
|
||
```{code-cell} ipython3 | ||
class equalizing_diff: | ||
""" | ||
A class of the equalizing difference model | ||
""" | ||
# Define the namedtuple for the equalizing difference model | ||
EqDiffModel = namedtuple('EqDiffModel', 'R T γ_h γ_c w_h0 D π') | ||
|
||
def create_edm(R=1.05, # Gross rate of return | ||
T=40, # Time horizon | ||
γ_h=1.01, # High-school wage growth | ||
γ_c=1.01, # College wage growth | ||
w_h0=1, # Initial wage (high school) | ||
D=10, # Cost for college | ||
π=None): | ||
|
||
return EqDiffModel(R, T, γ_h, γ_c, w_h0, D, π) | ||
|
||
def compute_gap(model): | ||
R, T, γ_h, γ_c, w_h0, D, π = model | ||
|
||
A_h = (1 - (γ_h/R)**(T+1)) / (1 - γ_h/R) | ||
A_c = (1 - (γ_c/R)**(T-3)) / (1 - γ_c/R) * (γ_c/R)**4 | ||
|
||
def __init__(self, R, T, γ_h, γ_c, w_h0, D=0, π=None): | ||
# one switches to the weak model by setting π | ||
self.R, self.γ_h, self.γ_c, self.w_h0, self.D = R, γ_h, γ_c, w_h0, D | ||
self.T, self.π = T, π | ||
# Tweaked model | ||
if π is not None: | ||
A_c = π * A_c | ||
|
||
def compute_gap(self): | ||
R, γ_h, γ_c, w_h0, D = self.R, self.γ_h, self.γ_c, self.w_h0, self.D | ||
T, π = self.T, self.π | ||
|
||
A_h = (1 - (γ_h/R)**(T+1)) / (1 - γ_h/R) | ||
A_c = (1 - (γ_c/R)**(T-3)) / (1 - γ_c/R) * (γ_c/R)**4 | ||
|
||
# tweaked model | ||
if π!=None: | ||
A_c = π*A_c | ||
|
||
ϕ = A_h/A_c + D/(w_h0*A_c) | ||
return ϕ | ||
ϕ = A_h / A_c + D / (w_h0 * A_c) | ||
return ϕ | ||
``` | ||
|
||
|
||
Using vectorization instead of loops, | ||
we build some functions to help do comparative statics . | ||
|
||
|
@@ -242,75 +244,30 @@ For a given instance of the class, we want to recompute $\phi$ when one paramete | |
Let's do an example. | ||
|
||
```{code-cell} ipython3 | ||
# ϕ_R | ||
def ϕ_R(mc, R_new): | ||
mc_new = equalizing_diff(R_new, mc.T, mc.γ_h, mc.γ_c, mc.w_h0, mc.D, mc.π) | ||
return mc_new.compute_gap() | ||
|
||
ϕ_R = np.vectorize(ϕ_R) | ||
|
||
# ϕ_γh | ||
def ϕ_γh(mc, γh_new): | ||
mc_new = equalizing_diff(mc.R, mc.T, γh_new, mc.γ_c, mc.w_h0, mc.D, mc.π) | ||
return mc_new.compute_gap() | ||
|
||
ϕ_γh = np.vectorize(ϕ_γh) | ||
|
||
# ϕ_γc | ||
def ϕ_γc(mc, γc_new): | ||
mc_new = equalizing_diff(mc.R, mc.T, mc.γ_h, γc_new, mc.w_h0, mc.D, mc.π) | ||
return mc_new.compute_gap() | ||
ex1 = create_edm() | ||
gap1 = compute_gap(ex1) | ||
|
||
ϕ_γc = np.vectorize(ϕ_γc) | ||
|
||
# ϕ_π | ||
def ϕ_π(mc, π_new): | ||
mc_new = equalizing_diff(mc.R, mc.T, mc.γ_h, mc.γ_c, mc.w_h0, mc.D, π_new) | ||
return mc_new.compute_gap() | ||
|
||
ϕ_π = np.vectorize(ϕ_π) | ||
``` | ||
|
||
```{code-cell} ipython3 | ||
# set benchmark parameters | ||
R = 1.05 | ||
T = 40 | ||
γ_h, γ_c = 1.01, 1.01 | ||
w_h0 = 1 | ||
D = 10 | ||
|
||
# create an instance | ||
ex1 = equalizing_diff(R=R, T=T, γ_h=γ_h, γ_c=γ_c, w_h0=w_h0, D=D) | ||
gap1 = ex1.compute_gap() | ||
|
||
print(gap1) | ||
gap1 | ||
``` | ||
|
||
Let's not charge for college and recompute $\phi$. | ||
|
||
The initial college wage premium should go down. | ||
|
||
|
||
|
||
|
||
```{code-cell} ipython3 | ||
# free college | ||
ex2 = equalizing_diff(R, T, γ_h, γ_c, w_h0, D=0) | ||
gap2 = ex2.compute_gap() | ||
print(gap2) | ||
ex2 = create_edm(D=0) | ||
gap2 = compute_gap(ex2) | ||
gap2 | ||
``` | ||
|
||
|
||
|
||
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. | ||
|
||
Let's start with the gross interest rate $R$. | ||
|
||
|
||
Let's start with the gross interest rate $R$. | ||
|
||
```{code-cell} ipython3 | ||
R_arr = np.linspace(1, 1.2, 50) | ||
plt.plot(R_arr, φ_R(ex1, R_arr)) | ||
plt.plot(R_arr, compute_gap(create_edm(R=R_arr))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow, this actually works?? That's amazing. So This definitely needs some comments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is passing the model with parameter The
I agree! Would you think a comment like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please see my response below. |
||
plt.xlabel(r'$R$') | ||
plt.ylabel(r'wage gap') | ||
plt.show() | ||
|
@@ -323,11 +280,12 @@ determinants of $\phi$. | |
|
||
```{code-cell} ipython3 | ||
γc_arr = np.linspace(1, 1.2, 50) | ||
plt.plot(γc_arr, φ_γc(ex1, γc_arr)) | ||
plt.plot(γc_arr, compute_gap(create_edm(γ_c=γc_arr))) | ||
plt.xlabel(r'$\gamma_c$') | ||
plt.ylabel(r'wage gap') | ||
plt.show() | ||
``` | ||
|
||
Notice how the intitial wage gap falls when the rate of growth $\gamma_c$ of college wages rises. | ||
|
||
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. | |
|
||
```{code-cell} ipython3 | ||
γh_arr = np.linspace(1, 1.1, 50) | ||
plt.plot(γh_arr, φ_γh(ex1, γh_arr)) | ||
plt.plot(γh_arr, compute_gap(create_edm(γ_h=γh_arr))) | ||
plt.xlabel(r'$\gamma_h$') | ||
plt.ylabel(r'wage gap') | ||
plt.show() | ||
``` | ||
|
||
|
||
## Entrepreneur-worker interpretation | ||
|
||
Now let's adopt the entrepreneur-worker interpretation of our model. | ||
|
||
If the probability that a new business succeeds is $.2$, let's compute the initial wage premium for successful entrepreneurs. | ||
If the probability that a new business succeeds is $0.2$, let's compute the initial wage premium for successful entrepreneurs. | ||
|
||
```{code-cell} ipython3 | ||
# a model of enterpreneur | ||
ex3 = equalizing_diff(R, T, γ_h, γ_c, w_h0, π=0.2) | ||
gap3 = ex3.compute_gap() | ||
ex3 = create_edm(π=0.2) | ||
gap3 = compute_gap(ex3) | ||
|
||
print(gap3) | ||
gap3 | ||
``` | ||
|
||
Now let's study how the initial wage premium for successful entrepreneurs depend on the success probability. | ||
|
||
|
||
```{code-cell} ipython3 | ||
π_arr = np.linspace(0.2, 1, 50) | ||
plt.plot(π_arr, φ_π(ex3, π_arr)) | ||
plt.plot(π_arr, compute_gap(create_edm(π=π_arr))) | ||
plt.ylabel(r'wage gap') | ||
plt.xlabel(r'$\pi$') | ||
plt.show() | ||
|
@@ -388,16 +344,10 @@ But for a reader interested in how we can get Python to do all the hard work inv | |
|
||
We'll use the Python module 'sympy' to compute partial derivatives of $\phi$ with respect to the parameters that determine it. | ||
|
||
Let's import key functions from sympy. | ||
|
||
```{code-cell} ipython3 | ||
from sympy import Symbol, Lambda, symbols | ||
``` | ||
|
||
Define symbols | ||
|
||
```{code-cell} ipython3 | ||
γ_h, γ_c, w_h0, D = symbols('\gamma_h, \gamma_h_c, w_0^h, D', real=True) | ||
γ_h, γ_c, w_h0, D = symbols('\gamma_h, \gamma_c, w_0^h, D', real=True) | ||
R, T = Symbol('R', real=True), Symbol('T', integer=True) | ||
``` | ||
|
||
|
@@ -450,8 +400,6 @@ Now let's compute $\frac{\partial \phi}{\partial D}$ and then evaluate it at the | |
|
||
Thus, as with our earlier graph, we find that raising $R$ increases the initial college wage premium $\phi$. | ||
|
||
+++ | ||
|
||
Compute $\frac{\partial \phi}{\partial T}$ and evaluate it a default parameters | ||
|
||
```{code-cell} ipython3 | ||
|
@@ -469,8 +417,6 @@ We find that raising $T$ decreases the initial college wage premium $\phi$. | |
|
||
This is because college graduates now have longer career lengths to "pay off" the time and other costs they paid to go to college | ||
|
||
+++ | ||
|
||
Let's compute $\frac{\partial \phi}{\partial γ_h}$ and evaluate it at default parameters. | ||
|
||
```{code-cell} ipython3 | ||
|
@@ -486,8 +432,6 @@ Let's compute $\frac{\partial \phi}{\partial γ_h}$ and evaluate it at default p | |
|
||
We find that raising $\gamma_h$ increases the initial college wage premium $\phi$, as we did with our earlier graphical analysis. | ||
|
||
+++ | ||
|
||
Compute $\frac{\partial \phi}{\partial γ_c}$ and evaluate it numerically at default parameter values | ||
|
||
```{code-cell} ipython3 | ||
|
@@ -503,8 +447,6 @@ Compute $\frac{\partial \phi}{\partial γ_c}$ and evaluate it numerically at def | |
|
||
We find that raising $\gamma_c$ decreases the initial college wage premium $\phi$, as we did with our graphical analysis earlier | ||
|
||
+++ | ||
|
||
Let's compute $\frac{\partial \phi}{\partial R}$ and evaluate it numerically at default parameter values | ||
|
||
```{code-cell} ipython3 | ||
|
@@ -518,12 +460,4 @@ Let's compute $\frac{\partial \phi}{\partial R}$ and evaluate it numerically at | |
ϕ_R_func(D_value, γ_h_value, γ_c_value, R_value, T_value, w_h0_value) | ||
``` | ||
|
||
+++ {"tags": []} | ||
|
||
We find that raising the gross interest rate $R$ increases the initial college wage premium $\phi$, as we did with our graphical analysis earlier | ||
|
||
|
||
|
||
```{code-cell} ipython3 | ||
|
||
``` | ||
We find that raising the gross interest rate $R$ increases the initial college wage premium $\phi$, as we did with our graphical analysis earlier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After
π=None
put# Extra parameter (modified version)
and then replaceTweaked model
withModification for reinterpreted model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jstac,
Since$\pi$ is only used for the entrepreneur model, would it be a good idea to remove it here and create a new
namedtuple
for the entrepreneur model when moving it into the exercise?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @HumphreyYang , yes, good call. Let's do exactly that.