Skip to content

Commit 3fc1cd2

Browse files
committed
Merge remote-tracking branch 'upstream/master' into prepop
2 parents 06b56b0 + 6e17d5d commit 3fc1cd2

44 files changed

Lines changed: 1051377 additions & 1049569 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build_and_test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030

3131
steps:
3232
- name: Checkout
33-
uses: actions/checkout@v6
33+
uses: actions/checkout@v7
3434
with:
3535
persist-credentials: false
3636
- name: Install uv
@@ -43,7 +43,7 @@ jobs:
4343
run: uv run python -m pytest -m "not local and not benchmark" --cov=./ --cov-report=xml
4444
- name: Upload coverage to Codecov
4545
if: matrix.os == 'ubuntu-latest' && contains(github.repository, 'PSLmodels/OG-Core') && github.actor != 'dependabot[bot]'
46-
uses: codecov/codecov-action@v6
46+
uses: codecov/codecov-action@v7
4747
with:
4848
files: ./coverage.xml
4949
flags: unittests

.github/workflows/check_ruff.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
lint:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v6
9+
- uses: actions/checkout@v7
1010
- uses: astral-sh/setup-uv@v7
1111
- name: Check formatting with Ruff
1212
run: uvx ruff format --check .

.github/workflows/deploy_docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- name: Checkout
20-
uses: actions/checkout@v6
20+
uses: actions/checkout@v7
2121
with:
2222
persist-credentials: false
2323

.github/workflows/docs_check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout
18-
uses: actions/checkout@v6
18+
uses: actions/checkout@v7
1919
with:
2020
persist-credentials: false
2121

.github/workflows/publish_to_pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- name: Checkout repo
15-
uses: actions/checkout@v6
15+
uses: actions/checkout@v7
1616
- name: Install uv
1717
uses: astral-sh/setup-uv@v7
1818
with:

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.16.2] - 2026-06-15 12:00:00
9+
10+
### Added
11+
12+
- Adds `output_tables.model_fit_table` function that generates a table comparing model output to data for a set of target moments, and adds a test of this function in `test_output_tables.py`. The function takes as input a list of target moment descriptions, the TPI output dictionary, and the model parameters object, and returns a pandas DataFrame with the target moment descriptions, the model values for those moments, and the data values for those moments (where applicable). The function currently supports a set of macroeconomic moments (interest rate, capital share of output, labor share of output), inequality moments (Gini coefficient for before-tax income and after-tax income), and demographic moments (fraction of population 65+ and population growth rate). See PR [#1138](https://github.com/PSLmodels/OG-Core/pull/1138).
13+
- Validates `beta_annual` and `chi_b` against `J`. ([PR #1149](https://github.com/PSLmodels/OG-Core/pull/1149))
14+
15+
### Bug Fixes
16+
- Fixes issue with reading UN data on Pandas >= 3.0 and UN token string. ([PR #1151](https://github.com/PSLmodels/OG-Core/pull/1151))
17+
- Fixes math notation for plot labels. ([PR #1148](https://github.com/PSLmodels/OG-Core/pull/1148))
18+
- Fixes reshaping issues with `J=1` parameterization. ([PR #1145](https://github.com/PSLmodels/OG-Core/pull/1145))
19+
20+
### Bug Fix
21+
22+
- Fixed math notion for tilde variables in plot labels in `output_plots.py` to be consistent with the documentation and the code. See PR [#1148](https://github.com/PSLmodels/OG-Core/pull/1148).
23+
24+
## [0.16.1] - 2026-06-04 12:00:00
25+
26+
### Added
27+
28+
- Adds a `use_sparse_FOC_jac` `Specifications` parameter (default `True`) that accelerates the time path iteration (TPI) household solve. With it on, `scipy.optimize.root` is given a sparse (banded) finite-difference Jacobian for the stacked household Euler and labor first order conditions: the sparsity pattern is auto-detected once per problem size and the solver then needs far fewer function evaluations per Jacobian build (about 20x fewer on the default S=80 cohort solve), with an automatic fallback to dense finite differences if the Jacobian is not sparse enough to benefit or if a solve fails. The result matches the legacy dense-finite-difference solution to within the model's resource-constraint accuracy floor on every calibration tested (OG-Core standard example, OG-ETH, OG-ZAF, OG-PHL, OG-IDN), giving roughly a 1.9-2.4x TPI speedup at no accuracy cost. Set `use_sparse_FOC_jac=False` to recover bit-identical agreement with v0.16.0 and earlier.
29+
30+
## [0.16.0] - 2026-06-02 12:00:00
31+
32+
### Added
33+
34+
- Adds a new parameter, `alpha_FA`, that allows the user to specify the level of direct foreign aid as a percentage of GDP. See PR [#1126](https://github.com/PSLmodels/OG-Core/pull/1126).
35+
36+
## [0.15.13] - 2026-05-15 06:00:00
37+
38+
### Added
39+
40+
- Increases the maximum value of the `mindist_TPI` parameter to 0.01 in `default_parameters.json`.
41+
- Updates the `uv.lock` with package updates.
42+
43+
## [0.15.12] - 2026-05-14 12:00:00
44+
45+
### Added
46+
47+
- Caches the `e_long` array in `household.FOC_savings` and `household.FOC_labor` rather than rebuilding it on every call. `e_long` is a pure function of `p.e`, `p.S`, and `p.J`, none of which change during a solve, so a `_get_e_long` helper now builds it once per worker and reuses it. Profiling identified this rebuild as the single most expensive operation in a TPI run. The change is a pure cache — model output is bit-for-bit identical to master — and gives roughly a 3x speedup on a single-reform TPI run. See PR [#1128](https://github.com/PSLmodels/OG-Core/pull/1128).
48+
- Builds the per-period tax-parameter slices in `TPI.inner_loop` as numpy arrays via a new `_params_to_array` helper, and switches `txfunc.get_tax_rates` to `np.asarray`, so the repeated per-call list-to-array conversion is skipped on the hot TPI path. `mono` and `mono2D` tax functions store callables rather than numbers, so their nested-list form is passed through unchanged. Profiling identified this conversion as the next hot spot after the `e_long` rebuild. Model output is bit-for-bit identical to master, and the change gives roughly a further 10% speedup on a single-reform TPI run (about 3.3x cumulative versus master). See PR [#1128](https://github.com/PSLmodels/OG-Core/pull/1128).
49+
- Changes the minimum of the allowable range for `tau_c` in `default_parameters.py` to allow for government consumption subsidies.
50+
- Fixes a bug in the `parameter_plots.plot_fert_rates` function. See PR [#1127](https://github.com/PSLmodels/OG-Core/pull/1127).
51+
52+
## [0.15.11] - 2026-05-08 12:00:00
53+
54+
### Added
55+
56+
- Updates the `uv.lock` to include dependabot upgrades PRs [#1118](https://github.com/PSLmodels/OG-Core/pull/1118), [#1119](https://github.com/PSLmodels/OG-Core/pull/1119), [#1120](https://github.com/PSLmodels/OG-Core/pull/1120), and [#1121](https://github.com/PSLmodels/OG-Core/pull/1121), as well as some other package upgrades that were available.
57+
858
## [0.15.10] - 2026-04-23 12:00:00
959

1060
### Added
@@ -553,6 +603,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
553603
- 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.
554604

555605

606+
[0.16.2]: https://github.com/PSLmodels/OG-Core/compare/v0.16.1...v0.16.2
607+
[0.16.1]: https://github.com/PSLmodels/OG-Core/compare/v0.16.0...v0.16.1
608+
[0.16.0]: https://github.com/PSLmodels/OG-Core/compare/v0.15.13...v0.16.0
609+
[0.15.13]: https://github.com/PSLmodels/OG-Core/compare/v0.15.12...v0.15.13
610+
[0.15.12]: https://github.com/PSLmodels/OG-Core/compare/v0.15.11...v0.15.12
611+
[0.15.11]: https://github.com/PSLmodels/OG-Core/compare/v0.15.10...v0.15.11
556612
[0.15.10]: https://github.com/PSLmodels/OG-Core/compare/v0.15.9...v0.15.10
557613
[0.15.9]: https://github.com/PSLmodels/OG-Core/compare/v0.15.8...v0.15.9
558614
[0.15.8]: https://github.com/PSLmodels/OG-Core/compare/v0.15.7...v0.15.8

docs/book/content/intro/parameters.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,15 @@ _Valid Range:_ min = 0.0 and max = 5.0
279279
_Out-of-Range Action:_ error
280280

281281

282+
### Fiscal Policy Parameters
283+
284+
#### `alpha_FA`
285+
_Description:_ Foreign aid payments to domestic government as a share of GDP.
286+
_Value Type:_ float
287+
_Valid Range:_ min = 0.0 and max = 1.0
288+
_Out-of-Range Action:_ error
289+
290+
282291
### Government Pension Parameters
283292

284293
#### `retirement_age`
@@ -556,7 +565,7 @@ _Out-of-Range Action:_ error
556565
_Description:_ Consumption tax rate. Set value for base year, click '+' to add value for next year. All future years not specified are set to last value entered.
557566
_Notes:_ This policy parameter represents the effective consumption tax rate from sales taxes, VATs, and excise taxes by consumption good. Tax rates cab vary over time. It is thus a TxI array.
558567
_Value Type:_ float
559-
_Valid Range:_ min = 0.0 and max = 5.0
568+
_Valid Range:_ min = -5.0 and max = 5.0
560569
_Out-of-Range Action:_ error
561570

562571

@@ -879,7 +888,7 @@ _Out-of-Range Action:_ error
879888
#### `mindist_TPI`
880889
_Description:_ Tolerance for convergence of time path solution.
881890
_Value Type:_ float
882-
_Valid Range:_ min = 1e-13 and max = 0.001
891+
_Valid Range:_ min = 1e-13 and max = 0.01
883892
_Out-of-Range Action:_ error
884893

885894

docs/book/content/theory/derivations.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,16 @@ In the Cobb-Douglas unit elasticity case ($\varepsilon=1$) of the CES production
114114
```
115115

116116
Again, even if this simple case, we cannot solve for $r$ as a function of $w$ for the reasons above.
117+
118+
119+
(SecAppDerivHHjac)=
120+
## Sparsity of the household equation Jacobian
121+
122+
Holding fixed the prices and policies a type-$j$ cohort faces, its $2S$ stationarized necessary conditions {eq}`EqStnrz_eul_n`, {eq}`EqStnrz_eul_b`, and {eq}`EqStnrz_eul_bS` in the $2S$ unknowns $\{n_{j,s},\hat b_{j,s+1}\}_{s=E+1}^{E+S}$ have a banded Jacobian. From the budget constraint {eq}`EqStnrzHHBC`, stationarized consumption at age $s$ depends on only three unknowns,
123+
124+
```{math}
125+
:label: EqAppDerivHHjac_cons
126+
\hat c_{j,s} = \frac{1}{p}\Bigl[(1+r_p)\hat b_{j,s} + \hat w\,e_{j,s}\,n_{j,s} - \widehat{tax}_{j,s} - e^{g_y}\hat b_{j,s+1}\Bigr] + X_{j,s},
127+
```
128+
129+
where $\widehat{tax}_{j,s}$ depends only on $(\hat b_{j,s}, n_{j,s})$ through labor and capital income (already in the active set, so it adds no further coupling), and $X_{j,s}$ collects terms fixed in the inner solve (bequests $\hat{bq}_{j,s}$, remittances $\hat{rm}_{j,s}$, government transfers $\hat{tr}_{j,s}$, UBI $\hat{ubi}_{j,s}$, the pension benefit $\theta_j$, and the $\hat c_{min,i}$ terms). The labor Euler equation {eq}`EqStnrz_eul_n` at age $s$ therefore depends on $\{\hat b_{j,s},\hat b_{j,s+1},n_{j,s}\}$ alone, and the savings Euler equation {eq}`EqStnrz_eul_b`---which links $\hat c_{j,s}$ to $\hat b_{j,s+1}$ and $\hat c_{j,s+1}$---depends on $\{\hat b_{j,s},\hat b_{j,s+1},\hat b_{j,s+2},n_{j,s},n_{j,s+1}\}$. The marginal tax rates $\tau^{mtrx}_s$ and $\tau^{mtry}_{s+1}$ are functions of own-age income (already in these sets), so they add no further coupling, and the terminal condition {eq}`EqStnrz_eul_bS` is sparser still. Each of the $2S$ equations therefore depends on at most five of the $2S$ unknowns, regardless of $S$, so the Jacobian has at most $10S$ nonzero entries rather than the $(2S)^2 = 4S^2$ of a fully coupled system. This is the per-cohort counterpart to the dense $2JS$ system noted at the start of Chapter {ref}`Chap_Eqm`: cohorts couple only through prices, which are held fixed in the inner solve. A finite-difference Jacobian can then be built from a number of evaluations set by the bandwidth---about seven at $S = 80$---rather than $2S$, by probing together unknowns that affect no common equation (Figure {numref}`FigHHjacSparsity`).

docs/book/content/theory/equilibrium.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ In all of the specifications of `OG-Core`, we use a two-stage fixed point algori
2525

2626
Our approach is to choose the minimum number of macroeconomic variables in an outer loop in order to be able to solve the household's $2JS$ Euler equations in terms of only the $\bar{n}_{j,s}$ and $\bar{b}_{j,s+1}$ variables directly, holding all other variables constant. The household system of Euler equations has a provable root solution and is orders of magnitude more tractable (less nonlinear) to solve holding these outer loop variables constant.
2727

28+
Moreover, with the outer-loop variables held fixed, each cohort's system of $2S$ Euler equations is not only less nonlinear but structurally sparse: every equation involves at most five of the $2S$ unknowns---a household's own age and its immediate neighbors. The root finder normally probes each unknown separately when building each step ($2S = 160$ evaluations of the system when $S = 80$), but with most equations depending on only a handful of unknowns, those affecting no common equation can be probed together, cutting the count to about seven at $S = 80$---a number set by how many neighbors couple, not by $S$. The parameter `use_sparse_FOC_jac` (default `True`) controls this; set it to `False` to use the legacy dense-finite-difference Jacobian on every call. The structure is derived in Appendix {ref}`SecAppDerivHHjac`.
29+
30+
```{figure} ./images/HH_jac_sparsity.png
31+
---
32+
name: FigHHjacSparsity
33+
---
34+
Sparsity pattern of the household equation Jacobian, at $S = 12$. Left: the standard finite-difference solve treats every entry of the $2S\times 2S$ matrix as live ($(2S)^2 = 576$ entries). Right: the actual structure---each Euler equation depends only on a household's own age and its immediate neighbors, leaving most entries zero (92 of 576 here; 636 of 25{,}600 at the default $S = 80$).
35+
```
36+
2837
The steady-state solution method for each of the cases above is associated with a solution method that has a subset of the following outer-loop variables $\Bigl\{\bar{r}_p, \bar{r}, \bar{w}, \{\bar{p}_m\}_{m=1}^{M-1}, \bar{Y}, \overline{TR}, \overline{BQ}, factor\Bigr\}$.
2938

3039

docs/book/content/theory/government.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -615,11 +615,11 @@ Note that the budget closure rule (described in Section ref{`SecUnbalGBCcloseRul
615615
(SecUnbalGBCbudgConstr)=
616616
## Government Budget Constraint
617617

618-
Let the level of government debt in period $t$ be given by $D_t$. The government budget constraint requires that government revenue $Rev_t$ plus the budget deficit ($D_{t+1} - D_t$) equal expenditures on interest on the debt, government spending on public goods $G_t$, total infrastructure investments $I_{g,t}$, total pension outlays, total transfer payments to households $TR_t$, and $UBI_t$ every period $t$,
618+
Let the level of government debt in period $t$ be given by $D_t$. The government budget constraint requires that government revenue $Rev_t$, external foreign assistance, $FA_t$, plus the budget deficit ($D_{t+1} - D_t$) equal expenditures on interest on the debt, government spending on public goods $G_t$, total infrastructure investments $I_{g,t}$, total pension outlays, total transfer payments to households $TR_t$, and $UBI_t$ every period $t$,
619619

620620
```{math}
621621
:label: EqUnbalGBCbudgConstr
622-
D_{t+1} + Rev_t = (1 + r_{gov,t})D_t + G_t + I_{g,t} + Pensions_t + TR_t + UBI_t \quad\forall t
622+
D_{t+1} + Rev_t + FA_t = (1 + r_{gov,t})D_t + G_t + I_{g,t} + Pensions_t + TR_t + UBI_t \quad\forall t
623623
```
624624

625625
where $r_{gov,t}$ is the interest rate paid by the government defined in equation {eq}`EqUnbalGBC_rate_wedge` below, $G_{t}$ is government spending on public goods, $I_{g,t}$ is total government spending on infrastructure investment, $TR_{t}$ are non-pension government transfers, and $UBI_t$ is the total UBI transfer outlays across households in time $t$. All variables in {eq}`EqUnbalGBCbudgConstr` are real variables denominated in units of current-period output in industry $M$ the numeraire ($p_{M,t}=1$ for all $t$).
@@ -713,8 +713,8 @@ Note that the budget closure rule (described in Section ref{`SecUnbalGBCcloseRul
713713
&\text{where}\quad g_{g,t} =
714714
\begin{cases}
715715
1 \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\quad\:\text{if}\quad t < T_{G1} \\
716-
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - I_{g,t} - TR_{t} - UBI_{t} + Rev_{t}}{\alpha_g Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
717-
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - I_{g,t} - TR_{t} - UBI_{t} + Rev_{t}}{\alpha_g Y_t} \qquad\qquad\quad\:\:\,\text{if}\quad t \geq T_{G2}
716+
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - I_{g,t} - TR_{t} - UBI_{t} + Rev_{t} + FA_{t}}{\alpha_g Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
717+
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - I_{g,t} - TR_{t} - UBI_{t} + Rev_{t} + FA_{t}}{\alpha_g Y_t} \qquad\qquad\quad\:\:\,\text{if}\quad t \geq T_{G2}
718718
\end{cases} \\
719719
&\text{and}\quad g_{tr,t} = 1 \quad\forall t
720720
\end{split}
@@ -735,8 +735,8 @@ Note that the budget closure rule (described in Section ref{`SecUnbalGBCcloseRul
735735
&\text{where}\quad g_{tr,t} =
736736
\begin{cases}
737737
1 \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\:\:\:\,\text{if}\quad t < T_{G1} \\
738-
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - G_{t} - I_{g,t} - UBI_{t} + Rev_{t}}{\alpha_{tr} Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
739-
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - G_{t} - I_{g,t} - UBI_{t} + Rev_{t}}{\alpha_{tr}Y_t} \qquad\qquad\quad\:\:\:\text{if}\quad t \geq T_{G2}
738+
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - G_{t} - I_{g,t} - UBI_{t} + Rev_{t} + FA_{t}}{\alpha_{tr} Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
739+
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - G_{t} - I_{g,t} - UBI_{t} + Rev_{t} + FA_{t}}{\alpha_{tr}Y_t} \qquad\qquad\quad\:\:\:\text{if}\quad t \geq T_{G2}
740740
\end{cases} \\
741741
&\text{and}\quad g_{g,t} = 1 \quad\forall t
742742
\end{split}
@@ -766,8 +766,8 @@ Note that the budget closure rule (described in Section ref{`SecUnbalGBCcloseRul
766766
&\text{where}\quad g_{trg,t} =
767767
\begin{cases}
768768
1 \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\quad\:\,\text{if}\quad t < T_{G1} \\
769-
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - I_{g,t} - UBI_{t} + Rev_{t}}{\left(\alpha_g + \alpha_{tr}\right)Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
770-
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - I_{g,t} - UBI_{t} + Rev_{t}}{\left(\alpha_g + \alpha_{tr}\right)Y_t} \qquad\qquad\quad\:\:\:\text{if}\quad t \geq T_{G2}
769+
\frac{\left[\rho_{d}\alpha_{D}Y_{t} + (1-\rho_{d})D_{t}\right] - (1+r_{gov,t})D_{t} - I_{g,t} - UBI_{t} + Rev_{t} + FA_{t}}{\left(\alpha_g + \alpha_{tr}\right)Y_t} \quad\text{if}\quad T_{G1}\leq t<T_{G2} \\
770+
\frac{\alpha_{D}Y_{t} - (1+r_{gov,t})D_{t} - I_{g,t} - UBI_{t} + Rev_{t} + FA_{t}}{\left(\alpha_g + \alpha_{tr}\right)Y_t} \qquad\qquad\quad\:\:\:\text{if}\quad t \geq T_{G2}
771771
\end{cases}
772772
\end{split}
773773
```

0 commit comments

Comments
 (0)