Skip to content

Commit

Permalink
Merge pull request PSLmodels#886 from jdebacker/surv_rate
Browse files Browse the repository at this point in the history
Remove `surv_rate` parameter object
  • Loading branch information
jdebacker authored Oct 21, 2023
2 parents 0dfe9c7 + 75ec1cf commit aa8c933
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 130 deletions.
4 changes: 2 additions & 2 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.9, 3.10]
name: Build and test [Python 3.9, 3.10, 3.11]

on: [push, pull_request]
# paths:
Expand All @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10"]
python-version: ["3.9", "3.10", "3.11"]

steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion ogcore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
from ogcore.txfunc import *
from ogcore.utils import *

__version__ = "0.10.9"
__version__ = "0.10.10"
19 changes: 0 additions & 19 deletions ogcore/default_parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -3560,25 +3560,6 @@
}
}
},
"surv_rate": {
"title": "Age-specific survival rates.",
"description": "Age-specific survival rates.",
"section_1": "Demographic Parameters",
"notes": "",
"type": "float",
"number_dims": 1,
"value": [
{
"value": [0.9992671466037937, 0.9991828802577581, 0.9991211270330613, 0.9990883474791409, 0.9990770197674355, 0.9990726593185169, 0.9990642897606029, 0.9990499046296879, 0.9990240264434502, 0.9989896445418176, 0.9989502540254145, 0.998910349441698, 0.998870943541464, 0.9988345543962669, 0.9987956760741559, 0.9987488226134084, 0.9986889954653082, 0.9986171744272776, 0.9985303646213153, 0.998427079774127, 0.9983098400876006, 0.9981746848684268, 0.9980121413191697, 0.9978177515814708, 0.997594541650623, 0.9973505043019144, 0.9970876400979336, 0.9968034781080352, 0.9964985595886034, 0.9961734146946981, 0.9958240228000609, 0.995453999920133, 0.9950706133080164, 0.9946765593201183, 0.9942678373891507, 0.9938170507984443, 0.9933349369903478, 0.9928571072472757, 0.9923946652766062, 0.991920706393161, 0.9913928161973069, 0.9907804595728024, 0.9900830226826921, 0.989286205338525, 0.9883813193193698, 0.9873488243699589, 0.9861937992775882, 0.9849307685778957, 0.983560091293199, 0.982053714634729, 0.9803171600092101, 0.9783569087279551, 0.9762533665241926, 0.9740162807067863, 0.9715717265593735, 0.9687414019675059, 0.965488871011245, 0.9619129374942117, 0.9580075267785504, 0.9536731613575886, 0.9486689819644183, 0.9429581421788265, 0.9366798451956814, 0.9298230368449151, 0.9222311641627915, 0.9137096685771553, 0.9040938100791817, 0.8932757445596693, 0.8812014250865317, 0.8678747435632396, 0.8533171772195793, 0.8375675224210112, 0.8206730335100753, 0.8026865855423447, 0.7836605522031078, 0.764642367296632, 0.7459401555112076, 0.7278808285655526, 0.7108048201866021, 0.0]
}
],
"validators": {
"range": {
"min": 0.0,
"max": 1.0
}
}
},
"etr_params": {
"title": "Effective tax rate function parameters.",
"description": "Effective tax rate function parameters.",
Expand Down
33 changes: 21 additions & 12 deletions ogcore/output_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,18 +605,27 @@ def dynamic_revenue_decomposition(
year_list.append("SS")
table_dict = {"Year": year_list}
T, S, J = base_params.T, base_params.S, base_params.J
base_etr_params_4D = np.tile(
base_params.etr_params[:T, :, :].reshape(
T, S, 1, base_params.etr_params.shape[2]
),
(1, 1, J, 1),
)
reform_etr_params_4D = np.tile(
reform_params.etr_params[:T, :, :].reshape(
T, S, 1, reform_params.etr_params.shape[2]
),
(1, 1, J, 1),
)
num_params = len(base_params.etr_params[0][0])
base_etr_params_4D = [
[
[
[base_params.etr_params[t][s][i] for i in range(num_params)]
for j in range(J)
]
for s in range(S)
]
for t in range(T)
]
reform_etr_params_4D = [
[
[
[reform_params.etr_params[t][s][i] for i in range(num_params)]
for j in range(J)
]
for s in range(S)
]
for t in range(T)
]
tax_rev_dict = {"indiv": {}, "biz": {}, "total": {}}
indiv_liab = {}
# Baseline IIT + payroll tax liability
Expand Down
3 changes: 2 additions & 1 deletion ogcore/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,9 @@ def compute_default_params(self):
if self.constant_demographics:
self.g_n_ss = 0.0
self.g_n = np.zeros(self.T + self.S)
surv_rate = np.ones_like(self.rho) - self.rho
surv_rate1 = np.ones((self.S,)) # prob start at age S
surv_rate1[1:] = np.cumprod(self.surv_rate[:-1], dtype=float)
surv_rate1[1:] = np.cumprod(surv_rate[-1, :-1], dtype=float)
# number of each age alive at any time
omega_SS = np.ones(self.S) * surv_rate1
self.omega_SS = omega_SS / omega_SS.sum()
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="ogcore",
version="0.10.9",
version="0.10.10",
author="Jason DeBacker and Richard W. Evans",
license="CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
description="A general equilibribum overlapping generations model for fiscal policy analysis",
Expand Down
93 changes: 59 additions & 34 deletions tests/test_TPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pickle
import numpy as np
import os
import sys
import json
from ogcore import SS, TPI, utils
import ogcore.aggregates as aggr
Expand Down Expand Up @@ -570,38 +571,36 @@ def test_run_TPI(baseline, param_updates, filename, tmpdir, dask_client):
CUR_PATH, "test_io_data", "run_TPI_outputs_baseline_Kg_nonzero_2.pkl"
)
# read in mono tax funcs (not age specific)
dict_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TxFuncEst_mono_nonage.pkl")
)
p = Specifications()
etr_params = [[None] * p.S] * p.T
mtrx_params = [[None] * p.S] * p.T
mtry_params = [[None] * p.S] * p.T
for s in range(p.S):
for t in range(p.T):
if t < p.BW:
etr_params[t][s] = dict_params["tfunc_etr_params_S"][t][s]
mtrx_params[t][s] = dict_params["tfunc_mtrx_params_S"][t][s]
mtry_params[t][s] = dict_params["tfunc_mtry_params_S"][t][s]
else:
etr_params[t][s] = dict_params["tfunc_etr_params_S"][-1][s]
mtrx_params[t][s] = dict_params["tfunc_mtrx_params_S"][-1][s]
mtry_params[t][s] = dict_params["tfunc_mtry_params_S"][-1][s]
param_updates9 = {
"tax_func_type": "mono",
"etr_params": etr_params,
"mtrx_params": mtrx_params,
"mtry_params": mtry_params,
}
filename9 = os.path.join(
CUR_PATH, "test_io_data", "run_TPI_outputs_mono_2.pkl"
)

if sys.version_info[1] < 11:
dict_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TxFuncEst_mono_nonage.pkl")
)
p = Specifications()
etr_params = [[None] * p.S] * p.T
mtrx_params = [[None] * p.S] * p.T
mtry_params = [[None] * p.S] * p.T
for s in range(p.S):
for t in range(p.T):
if t < p.BW:
etr_params[t][s] = dict_params["tfunc_etr_params_S"][t][s]
mtrx_params[t][s] = dict_params["tfunc_mtrx_params_S"][t][s]
mtry_params[t][s] = dict_params["tfunc_mtry_params_S"][t][s]
else:
etr_params[t][s] = dict_params["tfunc_etr_params_S"][-1][s]
mtrx_params[t][s] = dict_params["tfunc_mtrx_params_S"][-1][s]
mtry_params[t][s] = dict_params["tfunc_mtry_params_S"][-1][s]
param_updates9 = {
"tax_func_type": "mono",
"etr_params": etr_params,
"mtrx_params": mtrx_params,
"mtry_params": mtry_params,
}
filename9 = os.path.join(
CUR_PATH, "test_io_data", "run_TPI_outputs_mono_2.pkl"
)

@pytest.mark.local
@pytest.mark.parametrize(
"baseline,param_updates,filename",
[
if sys.version_info[1] < 11:
test_list = [
(True, param_updates2, filename2),
(True, param_updates5, filename5),
(True, param_updates6, filename6),
Expand All @@ -610,8 +609,8 @@ def test_run_TPI(baseline, param_updates, filename, tmpdir, dask_client):
(False, param_updates4, filename4),
(True, param_updates8, filename8),
(True, param_updates9, filename9),
],
ids=[
]
id_list = [
"Baseline, balanced budget",
"Baseline, small open",
"Baseline, small open for some periods",
Expand All @@ -620,7 +619,33 @@ def test_run_TPI(baseline, param_updates, filename, tmpdir, dask_client):
"Reform, baseline spending",
"Baseline, Kg>0",
"mono tax functions",
],
]
else:
test_list = [
(True, param_updates2, filename2),
(True, param_updates5, filename5),
(True, param_updates6, filename6),
(True, param_updates7, filename7),
(True, {}, filename1),
(False, param_updates4, filename4),
(True, param_updates8, filename8),
]
id_list = [
"Baseline, balanced budget",
"Baseline, small open",
"Baseline, small open for some periods",
"Baseline, delta_tau = 0",
"Baseline",
"Reform, baseline spending",
"Baseline, Kg>0",
]


@pytest.mark.local
@pytest.mark.parametrize(
"baseline,param_updates,filename",
test_list,
ids=id_list,
)
def test_run_TPI_extra(baseline, param_updates, filename, tmpdir, dask_client):
"""
Expand Down
Binary file added tests/test_io_data/model_params_baseline_v311.pkl
Binary file not shown.
Binary file added tests/test_io_data/model_params_reform_v311.pkl
Binary file not shown.
54 changes: 35 additions & 19 deletions tests/test_output_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest
import os
import sys
import numpy as np
import matplotlib.image as mpimg
from ogcore import utils, output_plots
Expand All @@ -17,18 +18,30 @@
base_tpi = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TPI_vars_baseline.pkl")
)
base_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_baseline.pkl")
)
if sys.version_info[1] < 11:
base_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_baseline.pkl")
)
else:
base_params = utils.safe_read_pickle(
os.path.join(
CUR_PATH, "test_io_data", "model_params_baseline_v311.pkl"
)
)
reform_ss = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "SS_vars_reform.pkl")
)
reform_tpi = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TPI_vars_reform.pkl")
)
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform.pkl")
)
if sys.version_info[1] < 11:
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform.pkl")
)
else:
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform_v311.pkl")
)
reform_taxfunctions = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TxFuncEst_reform.pkl")
)
Expand Down Expand Up @@ -457,17 +470,20 @@ def test_inequality_plot_save_fig(tmpdir):


def test_plot_all(tmpdir):
base_output_path = os.path.join(CUR_PATH, "test_io_data", "OUTPUT")
reform_output_path = os.path.join(CUR_PATH, "test_io_data", "OUTPUT")
output_plots.plot_all(base_output_path, reform_output_path, tmpdir)
img1 = mpimg.imread(os.path.join(tmpdir, "MacroAgg_PctChange.png"))
img2 = mpimg.imread(
os.path.join(tmpdir, "SSLifecycleProfile_Cons_Reform.png")
)
img3 = mpimg.imread(
os.path.join(tmpdir, "SSLifecycleProfile_Save_Reform.png")
)
if sys.version_info[1] < 11:
base_output_path = os.path.join(CUR_PATH, "test_io_data", "OUTPUT")
reform_output_path = os.path.join(CUR_PATH, "test_io_data", "OUTPUT")
output_plots.plot_all(base_output_path, reform_output_path, tmpdir)
img1 = mpimg.imread(os.path.join(tmpdir, "MacroAgg_PctChange.png"))
img2 = mpimg.imread(
os.path.join(tmpdir, "SSLifecycleProfile_Cons_Reform.png")
)
img3 = mpimg.imread(
os.path.join(tmpdir, "SSLifecycleProfile_Save_Reform.png")
)

assert isinstance(img1, np.ndarray)
assert isinstance(img2, np.ndarray)
assert isinstance(img3, np.ndarray)
assert isinstance(img1, np.ndarray)
assert isinstance(img2, np.ndarray)
assert isinstance(img3, np.ndarray)
else:
assert True
38 changes: 32 additions & 6 deletions tests/test_output_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest
import os
import sys
import pandas as pd
import numpy as np
from ogcore import utils, output_tables
Expand All @@ -17,18 +18,30 @@
base_tpi = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TPI_vars_baseline.pkl")
)
base_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_baseline.pkl")
)
if sys.version_info[1] < 11:
base_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_baseline.pkl")
)
else:
base_params = utils.safe_read_pickle(
os.path.join(
CUR_PATH, "test_io_data", "model_params_baseline_v311.pkl"
)
)
reform_ss = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "SS_vars_reform.pkl")
)
reform_tpi = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "TPI_vars_reform.pkl")
)
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform.pkl")
)
if sys.version_info[1] < 11:
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform.pkl")
)
else:
reform_params = utils.safe_read_pickle(
os.path.join(CUR_PATH, "test_io_data", "model_params_reform_v311.pkl")
)
# add investment tax credit parameter that not in cached parameters
base_params.inv_tax_credit = np.zeros(
(base_params.T + base_params.S, base_params.M)
Expand Down Expand Up @@ -136,6 +149,19 @@ def test_dynamic_revenue_decomposition(include_business_tax, full_break_out):
reform_params.capital_income_tax_noncompliance_rate = np.zeros(
(reform_params.T, reform_params.J)
)
# check if tax parameters are a numpy array
# this is relevant for cached parameter arrays saved before
# tax params were put in lists
if isinstance(base_params.etr_params, np.ndarray):
base_params.etr_params = base_params.etr_params.tolist()
if isinstance(reform_params.etr_params, np.ndarray):
reform_params.etr_params = reform_params.etr_params.tolist()
print("M = ", base_params.M, reform_params.M)
print(
"Shape of M implied by output = ",
base_tpi["p_m"].shape,
reform_tpi["p_m"].shape,
)
df = output_tables.dynamic_revenue_decomposition(
base_params,
base_tpi,
Expand Down
Loading

0 comments on commit aa8c933

Please sign in to comment.