From 06b2d9bcf14db8a8a44a80d3170895319560c6cc Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 00:46:44 -0400 Subject: [PATCH 01/27] add all output_plot functions to api docs --- docs/book/content/api/output_plots.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/book/content/api/output_plots.rst b/docs/book/content/api/output_plots.rst index a2e41375a..cb1d8b5ee 100644 --- a/docs/book/content/api/output_plots.rst +++ b/docs/book/content/api/output_plots.rst @@ -9,5 +9,6 @@ ogcore.output_plots ------------------------------------------ .. automodule:: ogcore.output_plots - :members: plot_aggregates, plot_gdp_ratio, ability_bar, ability_bar_ss, - ss_profiles, tpi_profiles, plot_all + :members: plot_aggregates, plot_industry_aggregates, ss_3Dplot, + plot_gdp_ratio, ability_bar, ability_bar_ss, + tpi_profiles, ss_profiles, plot_all, inequality_plot, lambda_labels From 84b20fdcae124b01000f2ce1b00b62f62541f1cc Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 00:48:00 -0400 Subject: [PATCH 02/27] wrap line --- docs/book/content/api/output_tables.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/book/content/api/output_tables.rst b/docs/book/content/api/output_tables.rst index 7d5d9c292..5cc3c0419 100644 --- a/docs/book/content/api/output_tables.rst +++ b/docs/book/content/api/output_tables.rst @@ -10,4 +10,5 @@ ogcore.output_tables .. automodule:: ogcore.output_tables :members: macro_table, macro_table_SS, ineq_table, gini_table, - wealth_moments_table, tp_output_dump_table, dynamic_revenue_decomposition + wealth_moments_table, tp_output_dump_table, + dynamic_revenue_decomposition From ef3f05f1a564ce13fdf17a9aeac33c2af83ee9dd Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 00:49:58 -0400 Subject: [PATCH 03/27] wrap line in pp --- docs/book/content/api/parameter_plots.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/book/content/api/parameter_plots.rst b/docs/book/content/api/parameter_plots.rst index 16c10f463..cd458e08b 100644 --- a/docs/book/content/api/parameter_plots.rst +++ b/docs/book/content/api/parameter_plots.rst @@ -10,8 +10,9 @@ ogcore.parameter_plots .. automodule:: ogcore.parameter_plots :members: plot_imm_rates, plot_mort_rates, plot_pop_growth, - plot_ability_profiles, plot_elliptical_u, plot_chi_n, - plot_fert_rates, plot_mort_rates_data, plot_g_n, plot_omega_fixed, - plot_imm_fixed, plot_population_path, gen_3Dscatters_hist, - txfunc_graph, txfunc_sse_plot, plot_income_data, plot_2D_taxfunc + plot_population, plot_ability_profiles, plot_elliptical_u, + plot_chi_n, plot_fert_rates, plot_mort_rates_data, plot_g_n, + plot_omega_fixed, plot_imm_fixed, plot_population_path, + gen_3Dscatters_hist, txfunc_graph, txfunc_sse_plot, + plot_income_data, plot_2D_taxfunc From eedd9cbc295202b8cb432a74c9a8b3dc3e868b24 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 00:55:05 -0400 Subject: [PATCH 04/27] change name of tp_dump_output_table to time_series_table --- docs/book/content/api/output_tables.rst | 2 +- ogcore/output_tables.py | 2 +- tests/test_output_tables.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/book/content/api/output_tables.rst b/docs/book/content/api/output_tables.rst index 5cc3c0419..dbb4c4d12 100644 --- a/docs/book/content/api/output_tables.rst +++ b/docs/book/content/api/output_tables.rst @@ -10,5 +10,5 @@ ogcore.output_tables .. automodule:: ogcore.output_tables :members: macro_table, macro_table_SS, ineq_table, gini_table, - wealth_moments_table, tp_output_dump_table, + wealth_moments_table, time_series_table, dynamic_revenue_decomposition diff --git a/ogcore/output_tables.py b/ogcore/output_tables.py index fc3311a1e..ef6cda20f 100644 --- a/ogcore/output_tables.py +++ b/ogcore/output_tables.py @@ -452,7 +452,7 @@ def wealth_moments_table( return table -def tp_output_dump_table( +def time_series_table( base_params, base_tpi, reform_params=None, diff --git a/tests/test_output_tables.py b/tests/test_output_tables.py index 1114c3a43..0de8bf161 100644 --- a/tests/test_output_tables.py +++ b/tests/test_output_tables.py @@ -135,8 +135,8 @@ def test_wealth_moments_table(): assert isinstance(df, pd.DataFrame) -def test_tp_output_dump_table(): - df = output_tables.tp_output_dump_table( +def test_time_series_table(): + df = output_tables.time_series_table( base_params, base_tpi, reform_params=reform_params, From 82d7bc30b6090213946b2b220f3840cae04642a8 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 00:58:56 -0400 Subject: [PATCH 05/27] change default for stationarized option in plot_aggregats --- ogcore/output_plots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ogcore/output_plots.py b/ogcore/output_plots.py index ee7851e57..6aab7b9f9 100644 --- a/ogcore/output_plots.py +++ b/ogcore/output_plots.py @@ -20,7 +20,7 @@ def plot_aggregates( reform_params=None, var_list=["Y", "C", "K", "L"], plot_type="pct_diff", - stationarized=True, + stationarized=False, num_years_to_plot=50, start_year=DEFAULT_START_YEAR, forecast_data=None, From 92db6e3a998ebb7251526d027e0c40935988ea7e Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 05:38:11 -0400 Subject: [PATCH 06/27] update stationary untility for new var names --- ogcore/utils.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ogcore/utils.py b/ogcore/utils.py index 7d8aab50b..e5c0ad745 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1254,9 +1254,9 @@ def pct_change_unstationarized( "I", "K_g", "I_g", - "Y_vec", - "K_vec", - "C_vec", + "Y_m", + "K_m", + "C_i", "I_total", "I_d", "BQ", @@ -1290,7 +1290,7 @@ def pct_change_unstationarized( ) elif var in [ "L", - "L_vec", + "L_m", ]: non_stationary_output["base"][var] = tpi_base[var][ :T @@ -1300,14 +1300,15 @@ def pct_change_unstationarized( ] * np.cumprod(1 + param_reform.g_n[:T]) elif var in [ "w", - "ubi_path", - "tr_path", - "bq_path", - "bmat_splus1", - "bmat_s", - "c_path", - "y_before_tax_path", - "tax_path", + "ubi", + "tr", + "bq", + "b_sp1", + "b_s", + "c", + "c_i", + "before_tax_income", + "hh_taxes", ]: non_stationary_output["base"][var] = tpi_base[var][:T] * np.exp( param_base.g_y * np.arange(param_base.T) From d5b3f5d2265f71831427f2a919116958aaa3eb41 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 05:52:09 -0400 Subject: [PATCH 07/27] generalize stationarization function --- ogcore/utils.py | 76 +++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/ogcore/utils.py b/ogcore/utils.py index e5c0ad745..ded25b0a6 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1209,39 +1209,27 @@ def shift_bio_clock( return param_out -def pct_change_unstationarized( - tpi_base, - param_base, - tpi_reform, - param_reform, - output_vars=["K", "Y", "C", "L", "r", "w"], +def unstationarize_vars( + var_name, + tpi_vars, + params, ): """ - This function takes the time paths of variables from the baseline - and reform and parameters from the baseline and reform runs and - computes percent changes for each variable in the output_vars list. - The function first unstationarizes the time paths of the variables - and then computes the percent changes. + This function takes a model variable and returns the unstationarized + value by adjusting for underlying growth in labor productivity + and population growth (where necessary). Args: - tpi_base (Numpy array): time path of the output variables from + var_name (string): name of variable to unstationarize + tpi_vars (Numpy array): time path of the output variables from the baseline run - param_base (Specifications object): dictionary of parameters + params (Specifications object): parameters from the baseline run - tpi_reform (Numpy array): time path of the output variables from - the reform run - param_reform (Specifications object): dictionary of parameters - from the reform run - output_vars (list): list of variables for which to compute - percent changes Returns: - pct_changes (dict): dictionary of percent changes for each - variable in output_vars list + pct_changes (array_like): unstationarized values for var_name """ # compute non-stationary variables - non_stationary_output = {"base": {}, "reform": {}} - pct_changes = {} T = param_base.T for var in output_vars: if var in [ @@ -1278,26 +1266,19 @@ def pct_change_unstationarized( "new_borrowing_f", "debt_service_f", ]: - non_stationary_output["base"][var] = ( - tpi_base[var][:T] - * np.cumprod(1 + param_base.g_n[:T]) - * np.exp(param_base.g_y * np.arange(param_base.T)) - ) - non_stationary_output["reform"][var] = ( - tpi_reform[var][:T] - * np.cumprod(1 + param_reform.g_n[:T]) - * np.exp(param_reform.g_y * np.arange(param_reform.T)) + non_stationary_output = ( + tpi_vars[var][:T] + * np.cumprod(1 + params.g_n[:T]) + * np.exp(params.g_y * np.arange(params.T)) ) elif var in [ "L", "L_m", ]: - non_stationary_output["base"][var] = tpi_base[var][ - :T - ] * np.cumprod(1 + param_base.g_n[:T]) - non_stationary_output["reform"][var] = tpi_reform[var][ - :T - ] * np.cumprod(1 + param_reform.g_n[:T]) + non_stationary_output = tpi_vars[var][:T] * np.cumprod( + 1 + params.g_n[:T] + ) + elif var in [ "w", "ubi", @@ -1310,24 +1291,13 @@ def pct_change_unstationarized( "before_tax_income", "hh_taxes", ]: - non_stationary_output["base"][var] = tpi_base[var][:T] * np.exp( - param_base.g_y * np.arange(param_base.T) + non_stationary_output = tpi_vars[var][:T] * np.exp( + params.g_y * np.arange(T) ) - non_stationary_output["reform"][var] = tpi_reform[var][ - :T - ] * np.exp(param_reform.g_y * np.arange(param_reform.T)) else: - non_stationary_output["base"][var] = tpi_base[var][:T] - non_stationary_output["reform"][var] = tpi_reform[var][:T] - - # calculate percent change - pct_changes[var] = ( - non_stationary_output["reform"][var] - / non_stationary_output["base"][var] - - 1 - ) + non_stationary_output = tpi_vars[var][:T] - return pct_changes + return non_stationary_output def param_dump_json(p, path=None): From f45acf8bdd0ee5beea38cfe13b74e27d3f40553f Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 05:52:29 -0400 Subject: [PATCH 08/27] expand unstationarization of vars for plots --- ogcore/output_plots.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/ogcore/output_plots.py b/ogcore/output_plots.py index 6aab7b9f9..7671ce491 100644 --- a/ogcore/output_plots.py +++ b/ogcore/output_plots.py @@ -48,8 +48,7 @@ def plot_aggregates( 'levels': plot variables in model units 'forecast': plots variables in levels relative to baseline economic forecast - stationarized (bool): whether used stationarized variables (False - only affects pct_diff right now) + stationarized (bool): whether used stationarized variables num_years_to_plot (integer): number of years to include in plot start_year (integer): year to start plot forecast_data (array_like): baseline economic forecast series, @@ -76,6 +75,13 @@ def plot_aggregates( if plot_type == "pct_diff" or plot_type == "diff": assert reform_tpi is not None fig1, ax1 = plt.subplots() + if not stationarized: + for v in var_list: + base_tpi[v] = utils.unstationarize_vars(v, base_tpi, base_params) + if reform_tpi: + reform_tpi[v] = utils.unstationarize_vars( + v, reform_tpi, reform_params + ) for i, v in enumerate(var_list): assert ( v in VAR_LABELS.keys() @@ -85,17 +91,7 @@ def plot_aggregates( # Compute just percentage point changes for rates plot_var = reform_tpi[v] - base_tpi[v] else: - if stationarized: - plot_var = (reform_tpi[v] - base_tpi[v]) / base_tpi[v] - else: - pct_changes = utils.pct_change_unstationarized( - base_tpi, - base_params, - reform_tpi, - reform_params, - output_vars=[v], - ) - plot_var = pct_changes[v] + plot_var = (reform_tpi[v] - base_tpi[v]) / base_tpi[v] ylabel = r"Pct. change" plt.plot( year_vec, @@ -182,6 +178,7 @@ def plot_industry_aggregates( var_list=["Y_m"], ind_names_list=None, plot_type="pct_diff", + stationarized=False, num_years_to_plot=50, start_year=DEFAULT_START_YEAR, forecast_data=None, @@ -201,6 +198,7 @@ def plot_industry_aggregates( reform_params (OG-Core Specifications class): reform parameters object var_list (list): names of variable to plot + plot_type (string): type of plot, can be: 'pct_diff': plots percentage difference between baseline and reform ((reform-base)/base) @@ -209,6 +207,7 @@ def plot_industry_aggregates( 'levels': plot variables in model units 'forecast': plots variables in levels relative to baseline economic forecast + stationarized (bool): whether used stationarized variables num_years_to_plot (integer): number of years to include in plot start_year (integer): year to start plot forecast_data (array_like): baseline economic forecast series, @@ -236,6 +235,14 @@ def plot_industry_aggregates( assert base_params.start_year == reform_params.start_year year_vec = np.arange(start_year, start_year + num_years_to_plot) start_index = start_year - base_params.start_year + # Unstationarize variables if needed + if not stationarized: + for v in var_list: + base_tpi[v] = utils.unstationarize_vars(v, base_tpi, base_params) + if reform_tpi: + reform_tpi[v] = utils.unstationarize_vars( + v, reform_tpi, reform_params + ) # Check that reform included if doing pct_diff or diff plot if plot_type == "pct_diff" or plot_type == "diff": assert reform_tpi is not None From fcafa182d69f3ecf3696809e6ce6e72caf634632 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:05:35 -0400 Subject: [PATCH 09/27] test passing for new unstationarize func --- ogcore/utils.py | 135 ++++++++++++++++++++++---------------------- tests/test_utils.py | 16 +++--- 2 files changed, 75 insertions(+), 76 deletions(-) diff --git a/ogcore/utils.py b/ogcore/utils.py index ded25b0a6..e6cb2e294 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1210,7 +1210,7 @@ def shift_bio_clock( def unstationarize_vars( - var_name, + var, tpi_vars, params, ): @@ -1220,82 +1220,81 @@ def unstationarize_vars( and population growth (where necessary). Args: - var_name (string): name of variable to unstationarize + var (string): name of variable to unstationarize tpi_vars (Numpy array): time path of the output variables from the baseline run params (Specifications object): parameters from the baseline run Returns: - pct_changes (array_like): unstationarized values for var_name + pct_changes (array_like): unstationarized values for var """ # compute non-stationary variables - T = param_base.T - for var in output_vars: - if var in [ - "Y", - "B", - "K", - "K_f", - "K_d", - "C", - "I", - "K_g", - "I_g", - "Y_m", - "K_m", - "C_i", - "I_total", - "I_d", - "BQ", - "TR", - "total_tax_revenue", - "business_tax_revenue", - "iit_payroll_tax_revenue", - "iit_revenue", - "payroll_tax_revenue", - "agg_pension_outlays", - "bequest_tax_revenue", - "wealth_tax_revenue", - "cons_tax_revenue", - "G", - "D", - "D_f", - "D_d", - "UBI_path", - "new_borrowing_f", - "debt_service_f", - ]: - non_stationary_output = ( - tpi_vars[var][:T] - * np.cumprod(1 + params.g_n[:T]) - * np.exp(params.g_y * np.arange(params.T)) - ) - elif var in [ - "L", - "L_m", - ]: - non_stationary_output = tpi_vars[var][:T] * np.cumprod( - 1 + params.g_n[:T] - ) + T = params.T + if var in [ + "Y", + "B", + "K", + "K_f", + "K_d", + "C", + "I", + "K_g", + "I_g", + "Y_m", + "K_m", + "C_i", + "I_total", + "I_d", + "BQ", + "TR", + "total_tax_revenue", + "business_tax_revenue", + "iit_payroll_tax_revenue", + "iit_revenue", + "payroll_tax_revenue", + "agg_pension_outlays", + "bequest_tax_revenue", + "wealth_tax_revenue", + "cons_tax_revenue", + "G", + "D", + "D_f", + "D_d", + "UBI_path", + "new_borrowing_f", + "debt_service_f", + ]: + non_stationary_output = ( + tpi_vars[var][:T] + * np.cumprod(1 + params.g_n[:T]) + * np.exp(params.g_y * np.arange(params.T)) + ) + elif var in [ + "L", + "L_m", + ]: + non_stationary_output = tpi_vars[var][:T] * np.cumprod( + 1 + params.g_n[:T] + ) - elif var in [ - "w", - "ubi", - "tr", - "bq", - "b_sp1", - "b_s", - "c", - "c_i", - "before_tax_income", - "hh_taxes", - ]: - non_stationary_output = tpi_vars[var][:T] * np.exp( - params.g_y * np.arange(T) - ) - else: - non_stationary_output = tpi_vars[var][:T] + elif var in [ + "w", + "ubi", + "tr", + "bq", + "b_sp1", + "b_s", + "c", + "c_i", + "before_tax_income", + "hh_taxes", + ]: + non_stationary_output = tpi_vars[var][:T] * np.exp( + params.g_y * np.arange(T) + ) + else: + non_stationary_output = tpi_vars[var][:T] return non_stationary_output diff --git a/tests/test_utils.py b/tests/test_utils.py index b73284ba2..2e0e6b0cb 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -942,7 +942,7 @@ def test_shift_bio_clock(start_period, end_period, total_effect, expected): "Different growth rates", ], ) -def test_pct_change_unstationarized(p1, p2, expected): +def test_unstationarize_vars(p1, p2, expected): """ A test of the percentage change calculation function """ @@ -962,13 +962,13 @@ def test_pct_change_unstationarized(p1, p2, expected): "r": np.ones(p2.T) * 0.06, "w": np.ones(p2.T) * 1.3, } - pct_change = utils.pct_change_unstationarized( - base_tpi, - p1, - reform_tpi, - p2, - output_vars=["K", "Y", "C", "L", "r", "w"], - ) + pct_change = {} + for k in base_tpi.keys(): + base_unstationarized = utils.unstationarize_vars(k, base_tpi, p1) + reform_unstationarized = utils.unstationarize_vars(k, reform_tpi, p2) + pct_change[k] = ( + reform_unstationarized - base_unstationarized + ) / base_unstationarized for key in pct_change.keys(): print("Checking ", key) From 73971bc817c4b858274fc706bcba730063192224 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:08:34 -0400 Subject: [PATCH 10/27] allows stationarization option for time series table --- ogcore/output_tables.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ogcore/output_tables.py b/ogcore/output_tables.py index ef6cda20f..36b6cbd7a 100644 --- a/ogcore/output_tables.py +++ b/ogcore/output_tables.py @@ -4,7 +4,7 @@ from ogcore.constants import VAR_LABELS, DEFAULT_START_YEAR from ogcore import tax from ogcore.utils import save_return_table, Inequality -from ogcore.utils import pct_change_unstationarized +from ogcore.utils import unstationarize_vars cur_path = os.path.split(os.path.abspath(__file__))[0] @@ -457,6 +457,7 @@ def time_series_table( base_tpi, reform_params=None, reform_tpi=None, + stationarized=True, table_format=None, path=None, ): @@ -471,6 +472,7 @@ def time_series_table( reform_params (OG-Core Specifications class): reform parameters object reform_tpi (dictionary): TP output from reform run + stationarized (bool): whether to report stationarized output table_format (string): format to return table in: 'csv', 'tex', 'excel', 'json', if None, a DataFrame is returned path (string): path to save table to @@ -501,6 +503,14 @@ def time_series_table( "total_tax_revenue", "business_tax_revenue", ] + # unsationarize variables if needed + if not stationarized: + for v in vars_to_keep: + base_tpi[v] = unstationarize_vars(v, base_tpi, base_params) + if reform_tpi: + reform_tpi[v] = unstationarize_vars( + v, reform_tpi, reform_params + ) base_dict = {k: base_tpi[k] for k in vars_to_keep} # update key names base_dict_final = dict( From 77b2226c9c3e9fb4947e55438a61dd22f10b6bbc Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:10:37 -0400 Subject: [PATCH 11/27] use new stationarization func --- ogcore/output_tables.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/ogcore/output_tables.py b/ogcore/output_tables.py index 36b6cbd7a..31973e066 100644 --- a/ogcore/output_tables.py +++ b/ogcore/output_tables.py @@ -64,6 +64,13 @@ def macro_table( assert base_params.start_year == reform_params.start_year year_vec = np.arange(start_year, start_year + num_years) start_index = start_year - base_params.start_year + if not stationarized: + for v in var_list: + base_tpi[v] = unstationarize_vars(v, base_tpi, base_params) + if reform_tpi: + reform_tpi[v] = unstationarize_vars( + v, reform_tpi, reform_params + ) # Check that reform included if doing pct_diff or diff plot if output_type == "pct_diff" or output_type == "diff": assert reform_tpi is not None @@ -76,24 +83,14 @@ def macro_table( for i, v in enumerate(var_list): if output_type == "pct_diff": # multiple by 100 so in percentage points - if stationarized: - results = ((reform_tpi[v] - base_tpi[v]) / base_tpi[v]) * 100 - else: - pct_changes = pct_change_unstationarized( - base_tpi, - base_params, - reform_tpi, - reform_params, - output_vars=[v], - ) - results = pct_changes[v] * 100 - results_years = results[start_index : start_index + num_years] + results = ((reform_tpi[v] - base_tpi[v]) / base_tpi[v]) * 100 + results_years = results[start_index: start_index + num_years] results_overall = ( ( - reform_tpi[v][start_index : start_index + num_years].sum() - - base_tpi[v][start_index : start_index + num_years].sum() + reform_tpi[v][start_index: start_index + num_years].sum() + - base_tpi[v][start_index: start_index + num_years].sum() ) - / base_tpi[v][start_index : start_index + num_years].sum() + / base_tpi[v][start_index: start_index + num_years].sum() ) * 100 results_SS = results[-1] results_for_table = results_years @@ -106,10 +103,10 @@ def macro_table( table_dict[VAR_LABELS[v]] = results_for_table elif output_type == "diff": results = reform_tpi[v] - base_tpi[v] - results_years = results[start_index : start_index + num_years] + results_years = results[start_index: start_index + num_years] results_overall = ( - reform_tpi[v][start_index : start_index + num_years].sum() - - base_tpi[v][start_index : start_index + num_years].sum() + reform_tpi[v][start_index: start_index + num_years].sum() + - base_tpi[v][start_index: start_index + num_years].sum() ) results_SS = results[-1] results_for_table = results_years @@ -121,7 +118,7 @@ def macro_table( results_for_table = np.append(results_for_table, results_SS) table_dict[VAR_LABELS[v]] = results_for_table else: - results_years = base_tpi[v][start_index : start_index + num_years] + results_years = base_tpi[v][start_index: start_index + num_years] results_overall = results_years.sum() results_SS = base_tpi[v][-1] results_for_table = results_years @@ -134,7 +131,7 @@ def macro_table( table_dict[VAR_LABELS[v] + " Baseline"] = results_for_table if reform_tpi is not None: results_years = reform_tpi[v][ - start_index : start_index + num_years + start_index: start_index + num_years ] results_overall = results_years.sum() results_SS = reform_tpi[v][-1] From 941a9941ba217f2c1c67c9378a1a01b9f30df549 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:20:41 -0400 Subject: [PATCH 12/27] set dim for multi sector --- ogcore/utils.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ogcore/utils.py b/ogcore/utils.py index e6cb2e294..ffe332b06 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1231,6 +1231,11 @@ def unstationarize_vars( """ # compute non-stationary variables T = params.T + pop_growth = np.cumprod(1 + params.g_n[:T]) + prod_growth = np.exp(params.g_y * np.arange(params.T)) + if ("_m" in var) or ("_i" in var): + pop_growth = pop_growth.reshape(T, 1) + prod_growth = prod_growth.reshape(T, 1) if var in [ "Y", "B", @@ -1267,16 +1272,14 @@ def unstationarize_vars( ]: non_stationary_output = ( tpi_vars[var][:T] - * np.cumprod(1 + params.g_n[:T]) - * np.exp(params.g_y * np.arange(params.T)) + * pop_growth + * prod_growth ) elif var in [ "L", "L_m", ]: - non_stationary_output = tpi_vars[var][:T] * np.cumprod( - 1 + params.g_n[:T] - ) + non_stationary_output = tpi_vars[var][:T] * pop_growth elif var in [ "w", @@ -1290,9 +1293,7 @@ def unstationarize_vars( "before_tax_income", "hh_taxes", ]: - non_stationary_output = tpi_vars[var][:T] * np.exp( - params.g_y * np.arange(T) - ) + non_stationary_output = tpi_vars[var][:T] * prod_growth else: non_stationary_output = tpi_vars[var][:T] From bebca5f58fd2f4e085138d12230c7fab27d85de6 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:25:53 -0400 Subject: [PATCH 13/27] update api docs for changes in utils.py --- docs/book/content/api/utils.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/content/api/utils.rst b/docs/book/content/api/utils.rst index 2507dec81..3d5df0f2a 100644 --- a/docs/book/content/api/utils.rst +++ b/docs/book/content/api/utils.rst @@ -22,4 +22,4 @@ ogcore.utils to_timepath_shape, get_initial_path, safe_read_pickle, rate_conversion, save_return_table, print_progress, fetch_files_from_web, not_connected, avg_by_bin, extrapolate_arrays, get_legacy_session, shift_bio_clock, - pct_change_unstationarized, param_dump_json + unstationarize_vars, param_dump_json From ca80d81595b92de89be7f919e021cc23067c331b Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 06:34:36 -0400 Subject: [PATCH 14/27] bump version and update changelog --- CHANGELOG.md | 10 ++++++++++ ogcore/__init__.py | 2 +- setup.py | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5128f071..4d65b12e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.14.2] - 2025-03-12 12:00:00 + +### Added + +- `utils.pct_changes_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utilitiy to find unstationarized values of time series output +- `output_plots.py` and `output_tables.py` are updated to all for plots and tables of unstationarized output for variables of any type, not just percentage changes. +- The `ouput_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` +- API docs have been updated to include functions left out previously and for new function names + ## [0.14.1] - 2025-03-16 12:00:00 ### Bug Fix @@ -363,6 +372,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Version [0.7.0] on August 30, 2021 was the first time that the OG-USA repository was detached from all of the core model logic, which was named OG-Core. Before this version, OG-USA was part of what is now the [`OG-Core`](https://github.com/PSLmodels/OG-Core) repository. In the next version of OG-USA, we adjusted the version numbering to begin with 0.1.0. This initial version of 0.7.0, was sequential from what OG-USA used to be when the OG-Core project was called OG-USA. - Any earlier versions of OG-USA can be found in the [`OG-Core`](https://github.com/PSLmodels/OG-Core) repository [release history](https://github.com/PSLmodels/OG-Core/releases) from [v.0.6.4](https://github.com/PSLmodels/OG-Core/releases/tag/v0.6.4) (Jul. 20, 2021) or earlier. +[0.14.2]: https://github.com/PSLmodels/OG-Core/compare/v0.14.1...v0.14.2 [0.14.1]: https://github.com/PSLmodels/OG-Core/compare/v0.14.0...v0.14.1 [0.14.0]: https://github.com/PSLmodels/OG-Core/compare/v0.13.2...v0.14.0 [0.13.2]: https://github.com/PSLmodels/OG-Core/compare/v0.13.1...v0.13.2 diff --git a/ogcore/__init__.py b/ogcore/__init__.py index 523be0821..e733effbf 100644 --- a/ogcore/__init__.py +++ b/ogcore/__init__.py @@ -20,4 +20,4 @@ from ogcore.txfunc import * from ogcore.utils import * -__version__ = "0.14.1" +__version__ = "0.14.2" diff --git a/setup.py b/setup.py index 56d7f70ff..4ad5c2b44 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="ogcore", - version="0.14.1", + version="0.14.2", author="Jason DeBacker and Richard W. Evans", license="CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", description="A general equilibrium overlapping generations model for fiscal policy analysis", From 2deb84858f1e9dc3adda5c0faf6e0de91d69d83a Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Sat, 22 Mar 2025 17:45:09 +0700 Subject: [PATCH 15/27] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae96b2ae1..3ce8d3afd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ | | | | --- | --- | | Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://pslmodels.github.io/OG-Core/) | -| Package | [![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3916/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | +| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) | From d5ca50df41df267f8c2e6a00da053166c076ff15 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 07:19:32 -0400 Subject: [PATCH 16/27] change name of function that converts parameters to json file --- docs/book/content/api/utils.rst | 2 +- ogcore/utils.py | 2 +- tests/test_utils.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/book/content/api/utils.rst b/docs/book/content/api/utils.rst index 3d5df0f2a..7292953b5 100644 --- a/docs/book/content/api/utils.rst +++ b/docs/book/content/api/utils.rst @@ -22,4 +22,4 @@ ogcore.utils to_timepath_shape, get_initial_path, safe_read_pickle, rate_conversion, save_return_table, print_progress, fetch_files_from_web, not_connected, avg_by_bin, extrapolate_arrays, get_legacy_session, shift_bio_clock, - unstationarize_vars, param_dump_json + unstationarize_vars, params_to_json diff --git a/ogcore/utils.py b/ogcore/utils.py index ffe332b06..e0d69b4e3 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1300,7 +1300,7 @@ def unstationarize_vars( return non_stationary_output -def param_dump_json(p, path=None): +def params_to_json(p, path=None): """ This function creates a JSON file with the model parameters of the format used for the default_parameters.json file. diff --git a/tests/test_utils.py b/tests/test_utils.py index 2e0e6b0cb..a0f0b85ab 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -975,9 +975,9 @@ def test_unstationarize_vars(p1, p2, expected): assert np.allclose(pct_change[key], expected[key]) -def test_param_dump_json(): +def test_params_to_json(): """ - Test of the param_dump_json function + Test of the params_to_json function """ p = Specifications() j_str = utils.param_dump_json(p) From 048eea6541bb0eeb9cca58b664df42bee4717e94 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 07:54:57 -0400 Subject: [PATCH 17/27] format --- ogcore/output_tables.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ogcore/output_tables.py b/ogcore/output_tables.py index 31973e066..e9546999e 100644 --- a/ogcore/output_tables.py +++ b/ogcore/output_tables.py @@ -84,13 +84,13 @@ def macro_table( if output_type == "pct_diff": # multiple by 100 so in percentage points results = ((reform_tpi[v] - base_tpi[v]) / base_tpi[v]) * 100 - results_years = results[start_index: start_index + num_years] + results_years = results[start_index : start_index + num_years] results_overall = ( ( - reform_tpi[v][start_index: start_index + num_years].sum() - - base_tpi[v][start_index: start_index + num_years].sum() + reform_tpi[v][start_index : start_index + num_years].sum() + - base_tpi[v][start_index : start_index + num_years].sum() ) - / base_tpi[v][start_index: start_index + num_years].sum() + / base_tpi[v][start_index : start_index + num_years].sum() ) * 100 results_SS = results[-1] results_for_table = results_years @@ -103,10 +103,10 @@ def macro_table( table_dict[VAR_LABELS[v]] = results_for_table elif output_type == "diff": results = reform_tpi[v] - base_tpi[v] - results_years = results[start_index: start_index + num_years] + results_years = results[start_index : start_index + num_years] results_overall = ( - reform_tpi[v][start_index: start_index + num_years].sum() - - base_tpi[v][start_index: start_index + num_years].sum() + reform_tpi[v][start_index : start_index + num_years].sum() + - base_tpi[v][start_index : start_index + num_years].sum() ) results_SS = results[-1] results_for_table = results_years @@ -118,7 +118,7 @@ def macro_table( results_for_table = np.append(results_for_table, results_SS) table_dict[VAR_LABELS[v]] = results_for_table else: - results_years = base_tpi[v][start_index: start_index + num_years] + results_years = base_tpi[v][start_index : start_index + num_years] results_overall = results_years.sum() results_SS = base_tpi[v][-1] results_for_table = results_years @@ -131,7 +131,7 @@ def macro_table( table_dict[VAR_LABELS[v] + " Baseline"] = results_for_table if reform_tpi is not None: results_years = reform_tpi[v][ - start_index: start_index + num_years + start_index : start_index + num_years ] results_overall = results_years.sum() results_SS = reform_tpi[v][-1] From 02d519606d7292cbe629adc3e7710532f4658385 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 07:55:21 -0400 Subject: [PATCH 18/27] proparly handle annual rates --- CHANGELOG.md | 3 ++- ogcore/utils.py | 32 ++++++++++++++++++++------------ tests/test_utils.py | 8 ++++---- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d65b12e9..b0af35b84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `utils.pct_changes_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utilitiy to find unstationarized values of time series output - `output_plots.py` and `output_tables.py` are updated to all for plots and tables of unstationarized output for variables of any type, not just percentage changes. -- The `ouput_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` +- `ouput_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` +- `utils.param_dump_json` has been renamed `utils.params_to_json` - API docs have been updated to include functions left out previously and for new function names ## [0.14.1] - 2025-03-16 12:00:00 diff --git a/ogcore/utils.py b/ogcore/utils.py index e0d69b4e3..a58e2d4f2 100644 --- a/ogcore/utils.py +++ b/ogcore/utils.py @@ -1270,11 +1270,7 @@ def unstationarize_vars( "new_borrowing_f", "debt_service_f", ]: - non_stationary_output = ( - tpi_vars[var][:T] - * pop_growth - * prod_growth - ) + non_stationary_output = tpi_vars[var][:T] * pop_growth * prod_growth elif var in [ "L", "L_m", @@ -1323,13 +1319,25 @@ def params_to_json(p, path=None): else: converted_data[key] = val - # Parameters that need to be turned into annual rates for default_parameters.json - # g_y_annual - # beta_annual - # delta_annual - # delta_tau_annual - # delta_g_annual - # world_int_rate_annual + # Parameters that need to be turned into annual rates for + # default_parameters.json + annual_list = [ + "g_y_annual", + "beta_annual", + "delta_annual", + "delta_tau_annual", + "delta_g_annual", + "world_int_rate_annual", + ] + for v in annual_list: + val = getattr(p, v.replace("_annual", "")) + annual_value = (1 + val) ** ( + p.S / ((p.ending_age - p.starting_age)) + ) - 1 + if isinstance(annual_value, np.ndarray): + converted_data[v] = annual_value.tolist() + else: + converted_data[v] = annual_value # Convert to JSON string json_str = json.dumps(converted_data, indent=4) diff --git a/tests/test_utils.py b/tests/test_utils.py index a0f0b85ab..669d8f2fb 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -980,16 +980,16 @@ def test_params_to_json(): Test of the params_to_json function """ p = Specifications() - j_str = utils.param_dump_json(p) + j_str = utils.params_to_json(p) assert isinstance(j_str, str) -def test_param_dump_json_save(tmpdir): +def test_params_to_json_save(tmpdir): """ - Test of the param_dump_json function + Test of the params_to_json function """ p = Specifications() - utils.param_dump_json(p, path=os.path.join(tmpdir, "test.json")) + utils.params_to_json(p, path=os.path.join(tmpdir, "test.json")) # read in file with open(os.path.join(tmpdir, "test.json"), "r") as f: j_str = f.read() From 5f8aa7bfe1481eb02d3e6bd70b2eafa0130813a8 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 22 Mar 2025 17:43:29 -0400 Subject: [PATCH 19/27] clean up changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0af35b84..522cb566b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `utils.pct_changes_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utilitiy to find unstationarized values of time series output +- `utils.pct_change_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utility to find unstationarized values of time series output - `output_plots.py` and `output_tables.py` are updated to all for plots and tables of unstationarized output for variables of any type, not just percentage changes. -- `ouput_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` +- `ouput_tables.tp_output_dump_table` has been renamed `output_tables.time_series_table` - `utils.param_dump_json` has been renamed `utils.params_to_json` - API docs have been updated to include functions left out previously and for new function names From cee20bc4cd2ed93c1eee0bfee572fd8b5863932f Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 20:49:06 -0600 Subject: [PATCH 20/27] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ce8d3afd..ec4e2cc65 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,18 @@ | | | | --- | --- | | Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://pslmodels.github.io/OG-Core/) | -| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | +| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) | -OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG models, such as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core). +OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core). + +**Country calibrations of OG-Core** +| | | | +| :-----------: | :---------: | :-----:| +| United States, OG-USA, https://github.com/PSLmodels/OG-USA | United Kingdom, OG-UK, https://github.com/PSLmodels/OG-USA | | +| Phillipines, OG-PHL, https://github.com/EAPD-DRB/OG-PHL | South Africa, OG-ZAF, https://github.com/EAPD-DRB/OG-ZAF | Indonesia, OG-IDN, https://github.com/EAPD-DRB/OG-IDN | +| India, OG-IND, https://github.com/OpenSourceEcon/OG-IND | Malaysia, OG-MYS, https://github.com/OpenSourceEcon/OG-MYS | | ## Disclaimer From f769362fc6b799ae856e894c00cdd3efbbffa862 Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 20:56:33 -0600 Subject: [PATCH 21/27] Updated README.md --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ec4e2cc65..e7ef58b9f 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@ OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core). **Country calibrations of OG-Core** -| | | | -| :-----------: | :---------: | :-----:| -| United States, OG-USA, https://github.com/PSLmodels/OG-USA | United Kingdom, OG-UK, https://github.com/PSLmodels/OG-USA | | -| Phillipines, OG-PHL, https://github.com/EAPD-DRB/OG-PHL | South Africa, OG-ZAF, https://github.com/EAPD-DRB/OG-ZAF | Indonesia, OG-IDN, https://github.com/EAPD-DRB/OG-IDN | -| India, OG-IND, https://github.com/OpenSourceEcon/OG-IND | Malaysia, OG-MYS, https://github.com/OpenSourceEcon/OG-MYS | | +| | | +| :-----------: | :---------: | +| United States, OG-USA, https://github.com/PSLmodels/OG-USA | United Kingdom, OG-UK, https://github.com/PSLmodels/OG-USA | +| Phillipines, OG-PHL, https://github.com/EAPD-DRB/OG-PHL | South Africa, OG-ZAF, https://github.com/EAPD-DRB/OG-ZAF | +| Indonesia, OG-IDN, https://github.com/EAPD-DRB/OG-IDN | | +| India, OG-IND, https://github.com/OpenSourceEcon/OG-IND | Malaysia, OG-MYS, https://github.com/OpenSourceEcon/OG-MYS | ## Disclaimer From c244c77dcdd50806e50f63035c999d859a5bcfe2 Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 21:00:52 -0600 Subject: [PATCH 22/27] Updated README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e7ef58b9f..b659aace0 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ OG-Core is an overlapping-generations (OG) model core theory, logic, and solutio **Country calibrations of OG-Core** | | | | :-----------: | :---------: | -| United States, OG-USA, https://github.com/PSLmodels/OG-USA | United Kingdom, OG-UK, https://github.com/PSLmodels/OG-USA | -| Phillipines, OG-PHL, https://github.com/EAPD-DRB/OG-PHL | South Africa, OG-ZAF, https://github.com/EAPD-DRB/OG-ZAF | -| Indonesia, OG-IDN, https://github.com/EAPD-DRB/OG-IDN | | -| India, OG-IND, https://github.com/OpenSourceEcon/OG-IND | Malaysia, OG-MYS, https://github.com/OpenSourceEcon/OG-MYS | +| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | +| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | +| Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) | | +| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | ## Disclaimer From 843fc40e977eb528d5c8d6c741212d9394cbcc96 Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 21:04:38 -0600 Subject: [PATCH 23/27] Updated README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b659aace0..61950a5ea 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,11 @@ OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core). **Country calibrations of OG-Core** -| | | -| :-----------: | :---------: | -| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | -| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | -| Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) | | -| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | +| | | | +| :-----------: | :---------: | :---------: | +| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | | +| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) | +| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | | ## Disclaimer From bdce30f4521ab832fbd6a0ffcb52d0ca05806a9d Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 21:09:50 -0600 Subject: [PATCH 24/27] Update ogcore/output_tables.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ogcore/output_tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ogcore/output_tables.py b/ogcore/output_tables.py index e9546999e..0e857a4e0 100644 --- a/ogcore/output_tables.py +++ b/ogcore/output_tables.py @@ -500,7 +500,7 @@ def time_series_table( "total_tax_revenue", "business_tax_revenue", ] - # unsationarize variables if needed + # unstationarize variables if needed if not stationarized: for v in vars_to_keep: base_tpi[v] = unstationarize_vars(v, base_tpi, base_params) From 4f74cbdad6707c2c6ea5a5bc270ccfdfb5219161 Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 21:11:30 -0600 Subject: [PATCH 25/27] Update CHANGELOG.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0af35b84..ec3e3284e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `utils.pct_changes_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utilitiy to find unstationarized values of time series output - `output_plots.py` and `output_tables.py` are updated to all for plots and tables of unstationarized output for variables of any type, not just percentage changes. -- `ouput_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` +- `output_tables.tp_dump_ XXX` has been renamed `output_tables.time_series_table` - `utils.param_dump_json` has been renamed `utils.params_to_json` - API docs have been updated to include functions left out previously and for new function names From bf75ac7b9cc55fb87d0e5ba50df23ccbda167542 Mon Sep 17 00:00:00 2001 From: Richard Evans Date: Thu, 3 Apr 2025 21:19:52 -0600 Subject: [PATCH 26/27] Updated intro.md --- docs/book/content/intro/intro.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/book/content/intro/intro.md b/docs/book/content/intro/intro.md index 56c27f456..214452b2d 100644 --- a/docs/book/content/intro/intro.md +++ b/docs/book/content/intro/intro.md @@ -4,11 +4,18 @@ | | | | --- | --- | | Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://pslmodels.github.io/OG-Core/) | -| Package | [![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3916/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | +| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) | `OG-Core` is the core logic for a country-agnostic overlapping-generations (OG) model of an economy that allows for dynamic general equilibrium analysis of fiscal policy. The source code is openly available for download or collaboration at the GitHub repository [www.github.com/PSLmodels/OG-Core](https://github.com/PSLmodels/OG-Core), or you can click on the GitHub icon at the top right of this page. +**Country calibrations of OG-Core** +| | | | +| :-----------: | :---------: | :---------: | +| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | | +| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) | +| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | | + The model output focuses changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Although `OG-Core` can be run independently based on default parameter values (currently representing something similar to the United States), it is meant to be a dependency of a country-specific calibration. This documentation contains the following major sections, which are regularly updated. * Contributing to `OG-Core` From 70c107f6c6f86870eda35eed00a6d54f78e1ecb3 Mon Sep 17 00:00:00 2001 From: Jason DeBacker Date: Sat, 5 Apr 2025 16:35:27 -0400 Subject: [PATCH 27/27] set stationarized to true as default for all plots/tables --- ogcore/output_plots.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ogcore/output_plots.py b/ogcore/output_plots.py index 7671ce491..09c8f2adb 100644 --- a/ogcore/output_plots.py +++ b/ogcore/output_plots.py @@ -20,7 +20,7 @@ def plot_aggregates( reform_params=None, var_list=["Y", "C", "K", "L"], plot_type="pct_diff", - stationarized=False, + stationarized=True, num_years_to_plot=50, start_year=DEFAULT_START_YEAR, forecast_data=None, @@ -178,7 +178,7 @@ def plot_industry_aggregates( var_list=["Y_m"], ind_names_list=None, plot_type="pct_diff", - stationarized=False, + stationarized=True, num_years_to_plot=50, start_year=DEFAULT_START_YEAR, forecast_data=None,