You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit f3bf096
Browse filesBrowse the repository at this point in the historyBrowse files
`aggregates.revenue` counted payroll tax revenue twice. Each household's
24
-
`income_payroll_tax_liab` already includes `T_P = tau_payroll *
25
-
labor_income`, so payroll revenue is inside `iit_payroll_tax_revenue`;
26
-
PR #1184 then added `get_payroll_tax_revenue` (the same take, re-derived
27
-
from the aggregate wage bill) into that total again when `tau_payroll`
28
-
was nonzero. Revenue was overstated, the government over-spent, and any
29
-
model with a nonzero `tau_payroll` failed the steady-state resource
30
-
constraint (OG-USA was unaffected only because its `tau_payroll` is 0).
31
-
The erroneous addition is removed; `get_payroll_tax_revenue` still
32
-
provides the income vs payroll reporting split, which is unchanged.
22
+
- Fixes Issue [#1199](https://github.com/PSLmodels/OG-Core/issues/1199): `aggregates.revenue` counted payroll tax revenue twice. Each household's `income_payroll_tax_liab` already includes `T_P = tau_payroll * labor_income`, so payroll revenue is inside `iit_payroll_tax_revenue`; PR #1184 then added `get_payroll_tax_revenue` (the same take, re-derived from the aggregate wage bill) into that total again when `tau_payroll` was nonzero. Revenue was overstated, the government over-spent, and any model with a nonzero `tau_payroll` failed the steady-state resource constraint (OG-USA was unaffected only because its `tau_payroll` is 0). The erroneous addition is removed; `get_payroll_tax_revenue` still provides the income vs payroll reporting split, which is unchanged. (See [PR #1204](https://github.com/PSLmodels/OG-Core/pull/1204) and [PR #1199](https://github.com/PSLmodels/OG-Core/pull/1199).)
33
23
34
24
## [0.19.1] - 2026-08-10 12:00:00
35
25
36
26
### Added
37
27
38
-
- Stall detection for the TPI outer loop (Issue #1177): when the best
39
-
distance has not improved over the last `TPI_stall_window` iterations
40
-
(default 50; 0 disables), `run_TPI` logs a diagnosis distinguishing a
41
-
cycling outer loop (suggesting a lower `nu` or
42
-
`TPI_outer_method="anderson"`) from a diverging economy (usually an
43
-
inconsistent fiscal block, which solver settings cannot fix). The
44
-
default `TPI_stall_action="warn"` only logs, leaving model solutions
45
-
unchanged; `"stop"` also ends the loop early, so a hopeless run fails
46
-
through the existing non-convergence checks instead of spending the
47
-
rest of `maxiter`. The window check lives in
48
-
`ogcore.solvers.diagnose_stall` and works for both the picard and
49
-
anderson update rules. The diagnosis is re-logged if it changes (e.g.
50
-
escalates from cycling to diverging), and a run that ends unconverged
51
-
while stalled carries the diagnosis in the `RuntimeError` message, so
- Stall detection for the TPI outer loop (Issue #1177): when the best distance has not improved over the last `TPI_stall_window` iterations (default 50; 0 disables), `run_TPI` logs a diagnosis distinguishing a cycling outer loop (suggesting a lower `nu` or `TPI_outer_method="anderson"`) from a diverging economy (usually an inconsistent fiscal block, which solver settings cannot fix). The default `TPI_stall_action="warn"` only logs, leaving model solutions unchanged; `"stop"` also ends the loop early, so a hopeless run fails through the existing non-convergence checks instead of spending the rest of `maxiter`. The window check lives in `ogcore.solvers.diagnose_stall` and works for both the picard and anderson update rules. The diagnosis is re-logged if it changes (e.g. escalates from cycling to diverging), and a run that ends unconverged while stalled carries the diagnosis in the `RuntimeError` message, so it reaches users who only see the traceback. [PR #1178](https://github.com/PSLmodels/OG-Core/pull/1178).
54
29
- Changes the default of `stationarized` to `False` in `output_plots.plot_aggregates` and `output_plots.plot_industry_aggregates`, so unstationarized values are plotted by default, resolving Issue [#1133](https://github.com/PSLmodels/OG-Core/issues/1133). [PR #1183](https://github.com/PSLmodels/OG-Core/pull/1183).
with demographics that vary across lifetime income groups (introduced in
60
-
PR #1165), the `use_zeta = False` branch of `household.get_bq` divided
61
-
each group's bequest pool by its birth share (`lambdas[j]`) rather than
62
-
its actual population share, so bequests received did not sum to bequests
63
-
left and the steady-state resource constraint failed. Receipts are now
64
-
divided by the group's actual population (from `omega_SS` / `omega`),
65
-
matching the `use_zeta = True` branch. Results are unchanged when
66
-
demographics are common across groups. [PR #1187](https://github.com/PSLmodels/OG-Core/pull/1187).
67
-
- Fixes Issue [#1015](https://github.com/PSLmodels/OG-Core/issues/1015): fixes escape with special characters in parameter names that caused failures when reading from JSON files. Adds a test to prevent this in the future. [PR #1193](https://github.com/PSLmodels/OG-Core/pull/1193).
33
+
- Fixes Issue [#1186](https://github.com/PSLmodels/OG-Core/issues/1186): with demographics that vary across lifetime income groups (introduced in PR #1165), the `use_zeta = False` branch of `household.get_bq` divided each group's bequest pool by its birth share (`lambdas[j]`) rather than its actual population share, so bequests received did not sum to bequests left and the steady-state resource constraint failed. Receipts are now divided by the group's actual population (from `omega_SS` / `omega`), matching the `use_zeta = True` branch. Results are unchanged when demographics are common across groups. [PR #1187](https://github.com/PSLmodels/OG-Core/pull/1187).
34
+
- Fixes Issue [#1015](https://github.com/PSLmodels/OG-Core/issues/1015): fixes escape with special characters in parameter names that caused failures when reading from JSON files. Adds a test to prevent this in the future. [PR #1193](https://github.com/PSLmodels/OG-Core/pull/1193).
68
35
- Resolve Issue [#1152](https://github.com/PSLmodels/OG-Core/issues/1152): expose same keys in the steady-state and time path dictionaries. [PR #1185](https://github.com/PSLmodels/OG-Core/pull/1185).
the previous fallback behavior). `g_ndc` and `g_dir` now handle the
82
-
scalar `r` and `g_y` of the steady state, and `delta_ret` falls back
83
-
to the steady-state mortality rates implied by `rho` (averaged over
84
-
lifetime income groups) when no `mort_rates_SS` attribute is set. The
85
-
NDC system is added to the real-`Specifications` pension test.
42
+
- Fixes Issue [#1169](https://github.com/PSLmodels/OG-Core/issues/1169): the Notional Defined Contribution pension system could not run against a real `Specifications` object because its growth-rate settings were not parameters. `ndc_growth_rate`, `dir_growth_rate`, and `points_growth_rate` are now parameters in `default_parameters.json` (choices `"r"`, `"Curr GDP"`, `"LR GDP"`; default `"LR GDP"`, matching the previous fallback behavior). `g_ndc` and `g_dir` now handle the scalar `r` and `g_y` of the steady state, and `delta_ret` falls back to the steady-state mortality rates implied by `rho` (averaged over lifetime income groups) when no `mort_rates_SS` attribute is set. The NDC system is added to the real-`Specifications` pension test.
`get_pop_objs` raised an `AssertionError` for the homogeneous case
93
-
(`income_percentiles=None` with no income-specific inputs), because
94
-
`expand_pop_obj_J` asserted before reaching its homogeneous branch.
95
-
`income_percentiles` now defaults to a single income group (J=1) when
96
-
no income-specific inputs are supplied, restoring the pre-0.18 call
97
-
signature; it remains required whenever gradients or immigrant income
98
-
shares are provided. Also removes a stray debug `print` from that
99
-
branch.
48
+
- Fixes Issue [#1180](https://github.com/PSLmodels/OG-Core/issues/1180): `get_pop_objs` raised an `AssertionError` for the homogeneous case (`income_percentiles=None` with no income-specific inputs), because `expand_pop_obj_J` asserted before reaching its homogeneous branch. `income_percentiles` now defaults to a single income group (J=1) when no income-specific inputs are supplied, restoring the pre-0.18 call signature; it remains required whenever gradients or immigrant income shares are provided. Also removes a stray debug `print` from that branch.
100
49
101
50
## [0.18.0] - 2026-07-20 12:00:00
102
51
103
52
### Added
104
53
105
-
- Demographic parameters (`rho`, `omega`, `imm_rates`) are now allowed to
106
-
vary across lifetime income groups, `J`. See PR [#1165](https://github.com/PSLmodels/OG-Core/pull/1165)
54
+
- Demographic parameters (`rho`, `omega`, `imm_rates`) are now allowed to vary across lifetime income groups, `J`. See PR [#1165](https://github.com/PSLmodels/OG-Core/pull/1165)
107
55
108
56
## [0.17.0] - 2026-07-16 12:00:00
109
57
110
58
### Bug Fixes
111
59
112
-
- Fixes the Defined Benefits and Points System pension paths so they run
113
-
against a real `Specifications` object (Issues #1014 and #1075):
114
-
`p.retire` (an array since PR #433) was passed as the scalar `S_ret`
115
-
into the numba loops, the scalar `p.g_y` was indexed as an array inside
116
-
the loops, the scalar steady-state wage was indexed as a path, and the
117
-
time-varying 3-D `e` matrix (PR #895) was sliced as 2-D. The systems
118
-
use the steady-state retirement age and earnings profile for now; full
119
-
time variation remains open in Issue #1014. The same coercions are
120
-
applied to the NDC path, but the NDC system additionally requires
121
-
growth-rate settings (`ndc_growth_rate`, `dir_growth_rate`) that are
122
-
not yet parameters in `default_parameters.json`, so it still cannot
123
-
run against a real `Specifications` object (see Issue #1169).
124
-
- Wires the pre-time-path inputs the DB/NDC/PS benefit formulas need
125
-
into the TPI: labor supplied before the time path begins comes from
126
-
the model's initial condition (the same baseline object that
127
-
initializes wealth), and pre-time-path wages are anchored to the
128
-
period-0 wage of the current path. Adds the full time-path (T x S x J)
129
-
evaluation of Defined Benefits amounts (`DB_3dim_loop`) used when the
130
-
TPI computes aggregate revenues, built from each cohort's own wage and
131
-
labor history so aggregates are consistent with household behavior.
132
-
With these changes a country model using the Defined Benefits system
133
-
solves both the steady state and the transition path.
134
-
- Adds regression tests that call `pension_amount` with a real
135
-
`Specifications` object per pension system (the existing tests
136
-
pre-scalarized the inputs and so never exercised the real interface)
137
-
and a local-marked steady-state solve test with the Defined Benefits
138
-
system. See PR [#1167](https://github.com/PSLmodels/OG-Core/pull/1167).
139
-
- Fixes the tax-liability revenue calculation using the first year's tax
140
-
noncompliance and filer rates for every period, even when those rates
141
-
are set to vary over time (Issue #1168): households responded to the
142
-
changing rates while government revenue, the budget, and debt stayed on
143
-
the first-year values. `income_tax_liab` now slices the rates over the
144
-
transition path. See PR [#1174](https://github.com/PSLmodels/OG-Core/pull/1174).
145
-
- Fixes the steady-state `etr_ss` and `mtry_ss` diagnostics using the
146
-
labor-income tax noncompliance rate in place of the capital-income rate
147
-
(`capital_noncompliance_rate_2D` in `SS.py`, Issue #1170). This affects
148
-
only the post-solve SS diagnostics -- the solution itself already used
149
-
the correct rates -- and is a no-op when the two rates are equal (the
150
-
default). See PR [#1171](https://github.com/PSLmodels/OG-Core/pull/1171).
151
-
- Fixes `alpha_FA` (direct foreign aid, added in 0.16.0) not being
152
-
extended over the model time path: it was never registered in
153
-
`tp_param_list`, so a multi-year path stayed short and broke the
154
-
transition solve. It now extends to `T + S` with the last value carried
155
-
forward, like `alpha_G`/`alpha_T`/`alpha_I`. See PR [#1166](https://github.com/PSLmodels/OG-Core/pull/1166).
60
+
- Fixes the Defined Benefits and Points System pension paths so they run against a real `Specifications` object (Issues #1014 and #1075): `p.retire` (an array since PR #433) was passed as the scalar `S_ret` into the numba loops, the scalar `p.g_y` was indexed as an array inside the loops, the scalar steady-state wage was indexed as a path, and the time-varying 3-D `e` matrix (PR #895) was sliced as 2-D. The systems use the steady-state retirement age and earnings profile for now; full time variation remains open in Issue #1014. The same coercions are applied to the NDC path, but the NDC system additionally requires growth-rate settings (`ndc_growth_rate`, `dir_growth_rate`) that are not yet parameters in `default_parameters.json`, so it still cannot run against a real `Specifications` object (see Issue #1169).
61
+
- Wires the pre-time-path inputs the DB/NDC/PS benefit formulas need into the TPI: labor supplied before the time path begins comes from the model's initial condition (the same baseline object that initializes wealth), and pre-time-path wages are anchored to the period-0 wage of the current path. Adds the full time-path (T x S x J) evaluation of Defined Benefits amounts (`DB_3dim_loop`) used when the TPI computes aggregate revenues, built from each cohort's own wage and labor history so aggregates are consistent with household behavior. With these changes a country model using the Defined Benefits system solves both the steady state and the transition path.
62
+
- Adds regression tests that call `pension_amount` with a real `Specifications` object per pension system (the existing tests pre-scalarized the inputs and so never exercised the real interface) and a local-marked steady-state solve test with the Defined Benefits system. See PR [#1167](https://github.com/PSLmodels/OG-Core/pull/1167).
63
+
- Fixes the tax-liability revenue calculation using the first year's tax noncompliance and filer rates for every period, even when those rates are set to vary over time (Issue #1168): households responded to the changing rates while government revenue, the budget, and debt stayed on the first-year values. `income_tax_liab` now slices the rates over the transition path. See PR [#1174](https://github.com/PSLmodels/OG-Core/pull/1174).
64
+
- Fixes the steady-state `etr_ss` and `mtry_ss` diagnostics using the labor-income tax noncompliance rate in place of the capital-income rate (`capital_noncompliance_rate_2D` in `SS.py`, Issue #1170). This affects only the post-solve SS diagnostics -- the solution itself already used the correct rates -- and is a no-op when the two rates are equal (the default). See PR [#1171](https://github.com/PSLmodels/OG-Core/pull/1171).
65
+
- Fixes `alpha_FA` (direct foreign aid, added in 0.16.0) not being extended over the model time path: it was never registered in `tp_param_list`, so a multi-year path stayed short and broke the transition solve. It now extends to `T + S` with the last value carried forward, like `alpha_G`/`alpha_T`/`alpha_I`. See PR [#1166](https://github.com/PSLmodels/OG-Core/pull/1166).
0 commit comments