Skip to content

Commit

Permalink
Merge pull request #1 from jdebacker/pr-26
Browse files Browse the repository at this point in the history
Updates to IOT PR PSLmodels#26 for formatting and testing
john-p-ryan authored Jun 26, 2024
2 parents 3f478ec + 35a3e41 commit 634d1af
Showing 8 changed files with 740 additions and 26 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and test [Python 3.7, 3.8, 3.9]
name: Build and test [Python 3.9, 3.10, 3.11]

on: [push, pull_request]

@@ -7,11 +7,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: [3.9, "3.10", "3.11"]

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@master
with:
persist-credentials: false

@@ -35,8 +35,10 @@ jobs:
run: |
pytest -m 'not full_run and not regression' --cov=./ --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
if: contains(github.repository, 'PSLmodels/InverseOptimalTax')
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
2 changes: 1 addition & 1 deletion .github/workflows/check_black.yml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@master
- uses: psf/black@stable
with:
options: "--line-length 79 --check --verbose"
6 changes: 2 additions & 4 deletions .github/workflows/deploy_docs.yml
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
uses: actions/checkout@master
with:
persist-credentials: false

@@ -18,14 +18,12 @@ jobs:
with:
activate-environment: iot-dev
environment-file: environment.yml
python-version: 3.8
python-version: 3.11
auto-activate-base: false

- name: Build # Build Jupyter Book
shell: bash -l {0}
run: |
pip install jupyter-book
pip install sphinxcontrib-bibtex==2.2.0
pip install -e .
cd docs
jb build ./book
6 changes: 2 additions & 4 deletions .github/workflows/docs_check.yml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
uses: actions/checkout@master
with:
persist-credentials: false

@@ -15,14 +15,12 @@ jobs:
with:
activate-environment: iot-dev
environment-file: environment.yml
python-version: 3.8
python-version: 3.11
auto-activate-base: false

- name: Build # Build Jupyter Book
shell: bash -l {0}
run: |
pip install jupyter-book
pip install sphinxcontrib-bibtex==2.2.0
pip install -e .
cd docs
jb build ./book
29 changes: 29 additions & 0 deletions PSL_catalog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "Inverse Optimal Tax",
"img": "",
"banner_title": "Inverse Optimal Tax",
"banner_subtitle": "A model of inverse optimal taxation.",
"detailed_description": "A model of inverse optimal taxation.",
"policy_area": "Optimal Taxation, Inverse Optimal Taxation, Individual Income Tax",
"geography": "United States",
"language": "Python",
"maintainers": [
{
"name": "Jason DeBacker",
"image": "https://avatars.githubusercontent.com/u/10715924?v=4",
"link": "https://github.com/jdebacker/"
},
{
"name": "John P. Ryan",
"image": "https://avatars.githubusercontent.com/u/83313096?v=4",
"link": "https://github.com/john-p-ryan"
}
],
"links": {
"code_repository": "https://github.com/PSLmodels/InverseOptimalTax",
"user_documentation": "https://pslmodels.github.io/InverseOptimalTax/content/intro/intro.html",
"contributor_documentation": "https://pslmodels.github.io/InverseOptimalTax/content/intro/contributing.html",
"webapp": "",
"recent_changes": ""
}
}
5 changes: 4 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
@@ -18,4 +18,7 @@ dependencies:
- jupyter-book>=0.9.1
- black
- plotly-express
- kaleido
- kaleido
- typing_extensions
- jupyter-book
- sphinxcontrib-bibtex
673 changes: 673 additions & 0 deletions examples/NTA_presentation_figures.ipynb

Large diffs are not rendered by default.

35 changes: 23 additions & 12 deletions iot/inverse_optimal_tax.py
Original file line number Diff line number Diff line change
@@ -233,19 +233,22 @@ def compute_income_dist(
)
f = f_function.pdf(z_line)
F = np.cumsum(f)
f_prime = np.gradient(f, edge_order=2)
f_prime = np.gradient(f, edge_order=2)
elif dist_type == "Pln":

def pln_pdf(y, mu, sigma, alpha):
x1 = alpha * sigma - (np.log(y) - mu) / sigma
phi = st.norm.pdf((np.log(y) - mu) / sigma)
R = (1 - st.norm.cdf(x1)) / (st.norm.pdf(x1) + 1e-15)
R = (1 - st.norm.cdf(x1)) / (st.norm.pdf(x1) + 1e-15)
# 1e-15 to avoid division by zero
pdf = alpha / y * phi * R
return pdf

def neg_weighted_log_likelihood(params, data, weights):
mu, sigma, alpha = params
likelihood = np.sum(weights * np.log(pln_pdf(data, mu, sigma, alpha) + 1e-15))
likelihood = np.sum(
weights * np.log(pln_pdf(data, mu, sigma, alpha) + 1e-15)
)
# 1e-15 to avoid log(0)
return -likelihood

@@ -261,9 +264,8 @@ def fit_pln(data, weights, initial_guess):
return result.x

mu_initial = (
(np.log(data[income_measure]) * data[weight_var]).sum()
/ data[weight_var].sum()
)
np.log(data[income_measure]) * data[weight_var]
).sum() / data[weight_var].sum()
sigmasq = (
(
((np.log(data[income_measure]) - mu_initial) ** 2)
@@ -273,23 +275,32 @@ def fit_pln(data, weights, initial_guess):
).sum()
sigma_initial = np.sqrt(sigmasq)
# Initial guess for m, sigma, alpha
initial_guess = np.array([mu_initial, sigma_initial, 1.5])
mu, sigma, alpha = fit_pln(data[income_measure], data[weight_var], initial_guess)
initial_guess = np.array([mu_initial, sigma_initial, 1.5])
mu, sigma, alpha = fit_pln(
data[income_measure], data[weight_var], initial_guess
)

def pln_cdf(y, mu, sigma, alpha):
x1 = alpha * sigma - (np.log(y) - mu) / sigma
R = (1 - st.norm.cdf(x1)) / (st.norm.pdf(x1) + 1e-12)
CDF = (
st.norm.cdf((np.log(y) - mu) / sigma) -
st.norm.pdf((np.log(y) - mu) / sigma) * R
st.norm.cdf((np.log(y) - mu) / sigma)
- st.norm.pdf((np.log(y) - mu) / sigma) * R
)
return CDF

def pln_dpdf(y, mu, sigma, alpha):
x = (np.log(y) - mu) / sigma
R = (1 - st.norm.cdf(alpha * sigma - x)) / (st.norm.pdf(alpha * sigma - x) + 1e-15)
R = (1 - st.norm.cdf(alpha * sigma - x)) / (
st.norm.pdf(alpha * sigma - x) + 1e-15
)
left = (1 + x / sigma) * pln_pdf(y, mu, sigma, alpha)
right = alpha * st.norm.pdf(x) * ((alpha * sigma - x) * R - 1) / (sigma * y)
right = (
alpha
* st.norm.pdf(x)
* ((alpha * sigma - x) * R - 1)
/ (sigma * y)
)
return -(left + right) / y

f = pln_pdf(z_line, mu, sigma, alpha)

0 comments on commit 634d1af

Please sign in to comment.