Skip to content

Add npv_table for net present value of flow-variable changes - #1195

Open
arihantlodha-cmd wants to merge 1 commit into
PSLmodels:masterfrom
arihantlodha-cmd:npv-output-table
Open

Add npv_table for net present value of flow-variable changes#1195
arihantlodha-cmd wants to merge 1 commit into
PSLmodels:masterfrom
arihantlodha-cmd:npv-output-table

Conversation

@arihantlodha-cmd

Copy link
Copy Markdown
Contributor

Closes #1131.

Adds output_tables.npv_table, which builds a table of the net present value of the reform-minus-baseline change in flow variables (e.g. Y) over a horizon, evaluated at a list of discount rates. For each variable:

NPV = sum_{t=0}^{num_years-1} (x_reform[t] - x_base[t]) / (1 + r)^t

This follows the pattern the issue points to from the Cost of Disease repo, generalized into a reusable table function that fits the existing output_tables.py conventions (same base_tpi/reform_tpi/*_params signature, VAR_LABELS, and save_return_table for csv/tex/excel/json output).

Design choices, flagged for review:

  • Un-stationarized by default. Discounting the stationarized (detrended) values isn't the economically meaningful object, so the variables are un-stationarized before discounting so the NPV runs over the actual trend-inclusive level path. stationarized=True keeps the model values if a caller wants them. (This is why the default differs from macro_table, which defaults to stationarized.)
  • Reform required. The table is defined on a reform-minus-baseline change, so reform_tpi is asserted to be present.
  • Model units. Results are in the variable's model units. Since Make SS and TPI output dictionaries expose the same keys #1185 added factor to the output dictionaries, a caller can scale by it for dollars; I left that to the caller rather than bake in a dollar-year assumption. Happy to add an optional dollar conversion if you'd prefer it built in.

Output layout: one row per variable, one column per discount rate.

Testing

  • test_npv_table builds the table from the cached run output and checks the shape.
  • test_npv_table_values checks the discounted sum against a hand calculation at r = 0 and r = 0.1.
  • Also verified manually on the cached baseline/reform that NPV falls as the discount rate rises, as expected.
  • pytest tests/test_output_tables.py passes (21); ruff format --check ., ruff check ., and linecheck clean.

Closes PSLmodels#1131. Adds output_tables.npv_table, which builds a table of the net
present value of the reform-minus-baseline change in flow variables (e.g. Y)
over a horizon, evaluated at a list of discount rates. Values are
un-stationarized by default so the NPV is taken over the actual level path,
which is the economically meaningful object to discount; pass
stationarized=True to use the stationarized model values instead.

Adds a DataFrame test on the cached run output and an exactness test that
checks the discounted sum against a hand calculation, plus a CHANGELOG entry.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.85%. Comparing base (a8b0232) to head (4d06c13).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1195      +/-   ##
==========================================
+ Coverage   72.74%   72.85%   +0.10%     
==========================================
  Files          22       22              
  Lines        5768     5791      +23     
==========================================
+ Hits         4196     4219      +23     
  Misses       1572     1572              
Flag Coverage Δ
unittests 72.85% <100.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
ogcore/output_tables.py 88.99% <100.00%> (+0.83%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include calculations of the net present value of flows in output_tables.py

2 participants