Skip to content

Commit 4a512e8

Browse files
hmgaudeckertimmens
andauthored
Restructure package (#301)
Co-authored-by: timmens <mensingertim@gmail.com>
1 parent 4c70a64 commit 4a512e8

103 files changed

Lines changed: 2547 additions & 2489 deletions

File tree

Some content is hidden

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

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,7 @@ repos:
9595
- --wrap
9696
- '88'
9797
files: (docs/.)
98+
# mdformat-myst mangles sphinx-design grid-item-card directives
99+
exclude: docs/index\.md
98100
ci:
99101
autoupdate_schedule: monthly

AGENTS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ automation. Python 3.14+ is required.
4242

4343
- `InternalRegime`: Internal representation after processing user regime
4444
- `StateActionSpace`: Manages state-action combinations for solution/simulation
45-
- `StateSpaceInfo`: Metadata for working with function outputs on state spaces
4645
- `PeriodRegimeSimulationData`: Raw simulation results for one period in one regime
4746

47+
**Value Function Representation (`src/lcm/regime_building/V.py`)**
48+
49+
- `VInterpolationInfo`: Metadata for working with function outputs on state spaces
50+
4851
**Solution (`src/lcm/solution/`)**
4952

5053
- `solve_brute.py`: Brute force dynamic programming solver using backward induction
@@ -109,7 +112,7 @@ to transition functions for target-dependent transitions.
109112
- `tests/test_models/`: Shared test models (deterministic, stochastic variants)
110113
- `tests/solution/`: Tests for solution algorithms
111114
- `tests/simulation/`: Tests for simulation functionality
112-
- `tests/input_processing/`: Tests for model processing pipeline
115+
- `tests/regime_building/`: Tests for regime compilation pipeline
113116
- `tests/data/`: Analytical solutions and regression test data
114117

115118
## Model and Regime Interface

docs/development/benchmarking.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ title: Benchmarking
44

55
# Benchmarking
66

7-
pylcm uses [ASV (Airspeed Velocity)](https://asv.readthedocs.io/) to track
8-
performance across commits. Benchmarks run locally on GPU hardware and results are
9-
published to a [dashboard](https://open-econ.org/pylcm-benchmarks/).
7+
pylcm uses [ASV (Airspeed Velocity)](https://asv.readthedocs.io/) to track performance
8+
across commits. Benchmarks run locally on GPU hardware and results are published to a
9+
[dashboard](https://open-econ.org/pylcm-benchmarks/).
1010

1111
## Machine Setup
1212

@@ -61,16 +61,16 @@ pixi run asv-publish
6161
```
6262

6363
The `asv-run` and `asv-quick` tasks set `XLA_PYTHON_CLIENT_PREALLOCATE=false` and
64-
`XLA_PYTHON_CLIENT_MEM_FRACTION=0.3` automatically to prevent JAX from grabbing all
65-
GPU memory.
64+
`XLA_PYTHON_CLIENT_MEM_FRACTION=0.3` automatically to prevent JAX from grabbing all GPU
65+
memory.
6666

6767
## Benchmark Scenarios
6868

69-
| File | What it benchmarks |
70-
|---|---|
69+
| File | What it benchmarks |
70+
| -------------------------------- | ----------------------------------------------------------------------------------------------------- |
7171
| `bench_precautionary_savings.py` | Solve (varying grid sizes), simulate (varying subjects), solve+simulate, lin vs irreg grid comparison |
72-
| `bench_mortality.py` | Mortality model — solve + simulate |
73-
| `bench_mahler_yum.py` | Mahler & Yum (2024) replication (GPU only) |
72+
| `bench_mortality.py` | Mortality model — solve + simulate |
73+
| `bench_mahler_yum.py` | Mahler & Yum (2024) replication (GPU only) |
7474

7575
Each benchmark tracks three metrics:
7676

docs/development/setup.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ title: Setup & Workflow
66

77
## Setup
88

9-
pylcm uses [pixi](https://pixi.sh/) for dependency management. Python 3.14+ is
10-
required.
9+
pylcm uses [pixi](https://pixi.sh/) for dependency management. Python 3.14+ is required.
1110

1211
```bash
1312
# Clone the repository

docs/examples/index.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@ title: Examples
44

55
# Examples
66

7-
Complete example models built with pylcm, ordered from simplest to most complex.
8-
All models live in the `lcm_examples` package and can be imported directly.
7+
Complete example models built with pylcm, ordered from simplest to most complex. All
8+
models live in the `lcm_examples` package and can be imported directly.
99

10-
1. **[Tiny Consumption-Savings](tiny.md)**`lcm_examples.tiny`
11-
Minimal 2-regime model. 3 periods, discrete labor, log-spaced grids,
12-
tax-and-transfer system.
10+
1. **[Tiny Consumption-Savings](tiny.md)**`lcm_examples.tiny` Minimal 2-regime model.
11+
3 periods, discrete labor, log-spaced grids, tax-and-transfer system.
1312

14-
2. **[Mortality](mortality.md)**`lcm_examples.mortality`
15-
3-regime model with death. Discrete labor, borrowing constraint.
13+
1. **[Mortality](mortality.md)**`lcm_examples.mortality` 3-regime model with death.
14+
Discrete labor, borrowing constraint.
1615

17-
3. **[Precautionary Savings](precautionary_savings.md)**`lcm_examples.precautionary_savings`
18-
2-regime model with income shocks. IID, Rouwenhorst, and Tauchen shock types.
16+
1. **[Precautionary Savings](precautionary_savings.md)**
17+
`lcm_examples.precautionary_savings` 2-regime model with income shocks. IID,
18+
Rouwenhorst, and Tauchen shock types.
1919

20-
4. **[Precautionary Savings with Health](precautionary_savings_health.md)** `lcm_examples.precautionary_savings_health`
21-
2-regime model with health & exercise. Multiple continuous states and actions,
22-
auxiliary functions, constraints.
20+
1. **[Precautionary Savings with Health](precautionary_savings_health.md)**
21+
`lcm_examples.precautionary_savings_health` 2-regime model with health & exercise.
22+
Multiple continuous states and actions, auxiliary functions, constraints.
2323

24-
5. **[Mahler & Yum (2024)](mahler_yum_2024.md)**`lcm_examples.mahler_yum_2024`
25-
Full Econometrica replication. 8 states, stochastic transitions, data files,
24+
1. **[Mahler & Yum (2024)](mahler_yum_2024.md)**`lcm_examples.mahler_yum_2024` Full
25+
Econometrica replication. 8 states, stochastic transitions, data files,
2626
discount-factor heterogeneity. **Requires GPU.**
2727

2828
## Customizing models

docs/examples/mahler_yum_2024.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ title: Mahler & Yum (2024)
66

77
Full replication of the lifecycle model from @mahler2024.
88

9-
Two regimes (alive/dead), 8 states including health, education, productivity type,
10-
and health type. Three actions: labor supply, saving, and health effort. Features
11-
stochastic health and regime transitions, AR(1) productivity shocks, and
12-
discount-factor heterogeneity. Ships with calibrated data files for survival
13-
probabilities and initial distributions.
9+
Two regimes (alive/dead), 8 states including health, education, productivity type, and
10+
health type. Three actions: labor supply, saving, and health effort. Features stochastic
11+
health and regime transitions, AR(1) productivity shocks, and discount-factor
12+
heterogeneity. Ships with calibrated data files for survival probabilities and initial
13+
distributions.
1414

15-
::::{important}
16-
This model is computationally intensive and requires GPU acceleration. Run it in a CUDA
17-
environment (e.g., `pixi run -e cuda13 python your_script.py`).
18-
::::
15+
::::\{important} This model is computationally intensive and requires GPU acceleration.
16+
Run it in a CUDA environment (e.g., `pixi run -e cuda13 python your_script.py`). ::::
1917

2018
[View source on GitHub](https://github.com/OpenSourceEconomics/pylcm/blob/main/src/lcm_examples/mahler_yum_2024/_model.py)
2119

@@ -42,10 +40,9 @@ beta_std = START_PARAMS["beta"]["std"]
4240

4341
# Select initial states with high discount factor type
4442
selected_ids_high = jnp.flatnonzero(discount_factor_types)
45-
initial_states_high = {
46-
state: values[selected_ids_high] for state, values
47-
in initial_states.items()
48-
}
43+
initial_states_high = {
44+
state: values[selected_ids_high] for state, values in initial_states.items()
45+
}
4946

5047
# Solve and simulate for high discount factor type
5148
result = MAHLER_YUM_MODEL.simulate(

docs/examples/mortality.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ title: Mortality
55
# Mortality
66

77
A three-regime consumption-savings model with stochastic mortality: working life,
8-
retirement, and death. The agent chooses labor supply and consumption. Log utility
9-
with work disutility and a borrowing constraint. Mortality is age-dependent: a vector
10-
of per-period survival probabilities (last entry = 0.0 for certain death) governs the
8+
retirement, and death. The agent chooses labor supply and consumption. Log utility with
9+
work disutility and a borrowing constraint. Mortality is age-dependent: a vector of
10+
per-period survival probabilities (last entry = 0.0 for certain death) governs the
1111
transition to the dead regime.
1212

1313
[View source on GitHub](https://github.com/OpenSourceEconomics/pylcm/blob/main/src/lcm_examples/mortality.py)

docs/examples/precautionary_savings.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ title: Precautionary Savings
44

55
# Precautionary Savings
66

7-
A two-regime consumption-savings model with income shocks (alive + dead). Supports
8-
IID shocks (Normal Gauss-Hermite) and persistent AR(1) shocks (Rouwenhorst, Tauchen).
7+
A two-regime consumption-savings model with income shocks (alive + dead). Supports IID
8+
shocks (Normal Gauss-Hermite) and persistent AR(1) shocks (Rouwenhorst, Tauchen).
99
Configurable interest rate and wealth grid type.
1010

11-
With FGP-calibrated parameters, this replicates the simplified benchmark of
12-
@fella2019.
11+
With FGP-calibrated parameters, this replicates the simplified benchmark of @fella2019.
1312

1413
[View source on GitHub](https://github.com/OpenSourceEconomics/pylcm/blob/main/src/lcm_examples/precautionary_savings.py)
1514

docs/examples/precautionary_savings_health.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ where utility depends only on remaining wealth and health.
1212
This model demonstrates multiple continuous states, multiple continuous actions,
1313
auxiliary functions (wage, labor income), constraints, and regime transitions.
1414

15-
:::{note}
16-
The parameterization is chosen to showcase pylcm's features, not to match any empirical
17-
calibration.
18-
:::
15+
:::\{note} The parameterization is chosen to showcase pylcm's features, not to match any
16+
empirical calibration. :::
1917

2018
[View source on GitHub](https://github.com/OpenSourceEconomics/pylcm/blob/main/src/lcm_examples/precautionary_savings_health.py)
2119

docs/examples/tiny.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ title: Tiny Consumption-Savings
44

55
# Tiny Consumption-Savings
66

7-
A minimal two-regime consumption-savings model with working life and retirement.
8-
Three periods, discrete labor supply, log-spaced consumption grid, and a simple
7+
A minimal two-regime consumption-savings model with working life and retirement. Three
8+
periods, discrete labor supply, log-spaced consumption grid, and a simple
99
tax-and-transfer system that guarantees a consumption floor.
1010

1111
This is the simplest complete model in `lcm_examples` and a good starting point for
@@ -23,11 +23,13 @@ from lcm_examples.tiny import get_model, get_params
2323
model = get_model()
2424
params = get_params()
2525

26-
initial_df = pd.DataFrame({
27-
"regime": "working_life",
28-
"age": model.ages.values[0],
29-
"wealth": np.linspace(1, 20, 100),
30-
})
26+
initial_df = pd.DataFrame(
27+
{
28+
"regime": "working_life",
29+
"age": model.ages.values[0],
30+
"wealth": np.linspace(1, 20, 100),
31+
}
32+
)
3133

3234
result = model.simulate(
3335
params=params,

0 commit comments

Comments
 (0)