Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
jdebacker committed Feb 25, 2025
1 parent f2a32e7 commit c3a568c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
16 changes: 11 additions & 5 deletions iot/inverse_optimal_tax.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ def sw_weights(self):
+ ((self.theta_z * self.eti * self.mtr) / (1 - self.mtr))
+ ((self.eti * self.z * self.mtr_prime) / (1 - self.mtr) ** 2)
)
integral = np.trapz(g_z * self.f, self.z) # renormalize to integrate to 1
integral = np.trapz(
g_z * self.f, self.z
) # renormalize to integrate to 1
g_z = g_z / integral

# use Lockwood and Weinzierl formula, which should be equivalent but using numerical differentiation
Expand All @@ -402,7 +404,7 @@ def sw_weights(self):
return g_z, g_z_numerical


def find_eti(iot, g_z = None, eti_0 = 0.25):
def find_eti(iot, g_z=None, eti_0=0.25):
"""
This function solves for the ETI that would result in the
policy represented via MTRs in IOT being consistent with the
Expand All @@ -420,12 +422,16 @@ def find_eti(iot, g_z = None, eti_0 = 0.25):
Returns:
eti_beliefs (array-like): vector of ETI beliefs over z
"""

if g_z is None:
g_z = iot.g_z

# we solve an ODE of the form f'(z) + P(z)f(z) = Q(z)
P_z = 1/iot.z + iot.f_prime/iot.f + iot.mtr_prime/(iot.mtr * (1-iot.mtr))
P_z = (
1 / iot.z
+ iot.f_prime / iot.f
+ iot.mtr_prime / (iot.mtr * (1 - iot.mtr))
)
# integrating factor for ODE: mu(z) * f'(z) + mu(z) * P(z) * f(z) = mu(z) * Q(z)
mu_z = np.exp(np.cumsum(P_z))
Q_z = (g_z - 1) * (1 - iot.mtr) / (iot.mtr * iot.z)
Expand Down
15 changes: 8 additions & 7 deletions iot/iot_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,12 @@ def JJZFig4(self, policy="Current Law", var="g_z", upper_bound=500_000):
g_weights = df.g_z_numerical

# g1 with mtr_prime = 0
g1 = (
((df.theta_z * self.iot[k].eti * df.mtr) / (1 - df.mtr))
+ ((self.iot[k].eti * df.z * 0) / (1 - df.mtr) ** 2)
g1 = ((df.theta_z * self.iot[k].eti * df.mtr) / (1 - df.mtr)) + (
(self.iot[k].eti * df.z * 0) / (1 - df.mtr) ** 2
)
# g2 with theta_z = 0
g2 = (
((0 * self.iot[k].eti * df.mtr) / (1 - df.mtr))
+ ((self.iot[k].eti * df.z * df.mtr_prime) / (1 - df.mtr) ** 2)
g2 = ((0 * self.iot[k].eti * df.mtr) / (1 - df.mtr)) + (
(self.iot[k].eti * df.z * df.mtr_prime) / (1 - df.mtr) ** 2
)
integral = np.trapz(g1, df.z)
# g1 = g1 / integral
Expand All @@ -244,7 +242,10 @@ def JJZFig4(self, policy="Current Law", var="g_z", upper_bound=500_000):
self.income_measure: df.z,
"Overall Weight": g_weights,
"Tax Base Elasticity": 1 + g1,
"Nonconstant MTRs": 1 + g1 + g2 + np.abs(g1) * (np.sign(g1) != np.sign(g2))
"Nonconstant MTRs": 1
+ g1
+ g2
+ np.abs(g1) * (np.sign(g1) != np.sign(g2)),
}
)

Expand Down

0 comments on commit c3a568c

Please sign in to comment.