Skip to content

Add buffer stock model and HARK implementation - #5

Merged
mmcky merged 23 commits into
QuantEcon:mainfrom
akshayshanker:codex/buffer-stock-template
Oct 20, 2026
Merged

mmcky merged 23 commits into
QuantEcon:mainfrom
akshayshanker:codex/buffer-stock-template

Conversation

@akshayshanker

@akshayshanker akshayshanker commented Sep 13, 2026 •

Copy link
Copy Markdown
Collaborator

Adds buffer stock saving to the library with a shared model description and a runnable HARK implementation. Buffer stock is the first of a family of baseline models: each later baseline model gets the same treatment, a shared model description (the working group's baseline template) and implementations from participating toolkits, so the layout and conventions set here are the ones later models follow.

What this adds

Path Contents
models/buffer-stock/ The model description, version 0.1 (draft), covering theory, calibration and numerical solution, as Markdown with a PDF built by myst build --pdf; and the submission guide for projects.
projects/HARK/buffer-stock/ The HARK implementation: a self-contained notebook, its requirements, and example comparison tables and metadata. checks/ holds optional numerical tests, an independent EGM solver and a sensitivity study.
templates/plain_latex_wide/ The LaTeX layout for model PDFs, adapted from the working group's copy.
README.md, docs/ The README and the website describe this layout and list buffer stock first among the five proposed baseline models.

Design decisions

  1. One layout and one name for every baseline model. Shared model descriptions live in models/<model>/ and runnable implementations in projects/<toolkit>/<model>/, with the same <model> name in both, here buffer-stock. Each later baseline model gets its own directory under models/, with its implementations under projects/.
  2. A model description in place of a template notebook. Earlier plans had each project complete a template notebook for each model. Instead, the model description pins down the model and calibration, and each project chooses its prose, solution method and runnable format, such as a notebook or a MyST document.
  3. The numbers are required; the files are not. Every implementation reports consumption at the sixteen common values of m, the target and the MPC at the target with step 0.01, in a format of its choosing, and confirms that the model's conditions hold under its own shock approximation. The result tables in results/, the metadata.yml example and the comparison tolerances in the submission guide are optional and provisional. The library publishes no timings and no ranking of toolkits.
  4. Buffer stock is the first of five proposed baseline models and the first with a published description. The other four are in preparation.
  5. Publication, credit and licences. The working group publishes the baseline model descriptions under CC-BY-4.0; each implementation is authored and maintained by its project. metadata.yml credits Akshay Shanker as the author of the HARK implementation, whose code, including the notebook and checks/, is released under the Apache License 2.0, as HARK is.

Checks

  • python -m pytest -q checks passes (16 tests) in a fresh environment with HARK 0.17.1. The tests also check the committed result files and that metadata.yml credits its authors.
  • The notebook runs from a fresh kernel, and the result tables it writes match the committed files to about 1e-15.
  • The calibration and the condition factors match the tables in Carroll and Shanker, Theoretical Foundations of Buffer Stock Saving, and the limiting MPCs match its closed forms. The paper's table prints 0.071 for weak return impatience, the factor before the division by R; the description notes this beside its own value, 0.068.
  • The PDF rebuilds from model-description.md (4 pages), and CI's checks of the website's links, anchors and contents navigation pass.

Follow-ups

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It is a large domain-specific contribution whose correctness rests on an economic model, HARK numerical results, and a rendered PDF that cannot be fully executed or validated in this environment, so it warrants expert human review.

Pull request overview

This PR bootstraps the Community Library's first concrete model contribution — buffer stock saving — turning the previously abstract repository into one with a working template, a reference solver, and updated site/README content. It adds the shared lecture (Markdown + generated notebook + PDF), a HARK-based reference computation with its recorded values, an independent EGM cross-check, a test suite, a sensitivity study, and a wide-margin LaTeX export template. It also rewrites README.md and docs/index.html to describe the new "start with a model" contribution flow and to promote the model count from four to five.

Changes:

  • Adds the models/buffer-stock/ model directory: lecture (template.md/.ipynb/.pdf), submission guide (README.md), myst.yml, and a reference/ package (HARK solver, recorded results, tests, independent EGM oracle, sensitivity study).
  • Adds a vendored templates/plain_latex_wide/ jtex template (template.yml, template.tex) for the lecture PDF export.
  • Rewrites README.md and docs/index.html to describe the buffer-stock submission workflow and the five-model set.
File summaries
File Description
templates/plain_latex_wide/template.yml New jtex template manifest; restores upstream author attribution for CC-BY.
templates/plain_latex_wide/template.tex New LaTeX layout for lecture PDFs; guards most optional fields but not \date.
README.md Rewrites top-level docs around the buffer-stock model and five-model table.
models/buffer-stock/template.md The shared lecture: model, calibration, EGM steps, reference values, comparison cell.
models/buffer-stock/template.ipynb Notebook generated from the lecture; matches the Markdown source.
models/buffer-stock/reference/solve.py HARK reference solver writing reference_values.json and reference_cfunc.csv.
models/buffer-stock/reference/results/*.json,*.csv Recorded reference values consistent with the lecture and tests.
models/buffer-stock/reference/requirements.txt Pins econ-ark==0.17.1 plus numpy/scipy/pytest.
models/buffer-stock/reference/README.md Documents how the reference was computed and what the checks show.
models/buffer-stock/reference/checks/test_reference.py Tests the solver against paper formulas and the independent EGM.
models/buffer-stock/reference/checks/sensitivity.{py,md,json} Sensitivity study of results to grids and shock discretisation.
models/buffer-stock/reference/checks/independent_egm.py Independent EGM oracle used by the tests.
models/buffer-stock/README.md Submission guide: files to submit, metadata example, draft decisions.
models/buffer-stock/myst.yml MyST project config for the local lecture build.
models/buffer-stock/.gitignore Ignores _build/ and __pycache__/.
docs/index.html Adds the buffer-stock model card and rewrites template/contribute sections.

Notes from verification: relative links and in-page anchors across the READMEs resolve; the displayed reference numbers (target 1.3910, MPC 0.2696, κ bounds, condition factors) are consistent between template.md, the JSON/CSV artifacts, sensitivity.md, and the test tolerances; and the new absolute GitHub URLs in docs/index.html are not subject to the CI local-link check.

Review details
  • Files reviewed: 19/21 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread templates/plain_latex_wide/template.tex
mmcky added a commit to akshayshanker/community-library that referenced this pull request Sep 14, 2026
Drop the repeated "computational", restore "the toolkits that can solve
them", and soften "reviewed by the community" to "open to review by the
community" until a review process is defined (see QuantEcon#5).

Carry the README's framing onto the site: the h1 gains "economic", and the
host card, WG1 role card and footer now say the library is run in
collaboration with SCE Working Group 1 instead of independently of it.

Point every working-group link at econ-ark/sce-wg-1, which is now live,
instead of the interim mmcky/sce-wg1 copy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@akshayshanker akshayshanker changed the title Add buffer stock saving template and reference solver Add buffer stock model and HARK implementation Sep 14, 2026
akshayshanker and others added 5 commits September 14, 2026 18:54
Resolves the conflicts with QuantEcon#3 and QuantEcon#4. The README keeps main's title and
opening paragraphs, including the collaboration wording and the sentence
on community review; the branch's later sections stand. The site keeps
main's "run in collaboration with the group" wording in the role card and
the footer, with "templates" read as "model descriptions" now that the
descriptions live in models/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
template.yml declares date optional, but the \date block dereferenced
doc.date unconditionally, so a document without a date would hit a
LaTeX "missing number" error. Wrapped in the same guard the other
optional fields use; \maketitle then falls back to \today.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@mmcky mmcky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Akshay, this is a substantial piece of work and the numerics hold up well. I went through the model description, the HARK project and the site changes, and re-ran everything from a clean environment.

What I verified

Check Result
pytest checks in a fresh virtualenv (Python 3.14.7, HARK 0.17.1, NumPy 2.5.3) 14 passed
Headless execution of tutorial.ipynb with nbclient runs clean
Regenerated results/*.csv against the committed files identical to about 1e-15
The seven condition factors in the model description against the closed forms all match
Site checks (local references, anchors, contents rail) pass
PDF build 4 pages, renders correctly

What I pushed to the branch

Two commits, both small. A merge from main resolving the conflicts with #3 and #4: the README keeps main's title and opening paragraphs, including the "run in collaboration with the working group" wording and the sentence on community review, and the site keeps the same collaboration wording in the role card and footer. And the date guard Copilot suggested in template.tex, so a document without a date falls back to \today instead of a LaTeX error. Please pull before pushing again.

Decision on structure

The models/<model>/ and projects/<toolkit>/<model>/ layout is accepted. We will also publish the model descriptions on the library website rather than only linking to the files on GitHub, so the working group remains the publisher of the baseline set and the descriptions are available in both places. Rendering them on the site can be a follow-up PR.

Before merge

  1. Fill in authors in projects/HARK/BST/metadata.yml. The guide and the site both ask contributors to identify authors, and the example that everyone will copy currently has an empty list. The notebook preserves the field on re-run, so it only needs setting once.
  2. Expand the PR description to record the design decisions this PR makes, since future contributors will read it rather than the commit history: projects choose their own format instead of completing a template notebook, the comparison tables, metadata and tolerances are optional draft conventions, and buffer stock joins the baseline set as a fifth model.
  3. The README and site now say the working group has proposed five baseline models. If the group has adopted buffer stock, the working group site and roadmap should list it; if it is a library proposal for now, say "proposed" so the two sites agree.

Follow-ups, not blocking

  • A second CI job that runs pytest checks and executes the notebook. Together they take under a minute, and the roadmap already promises that CI runs the implementations. I can open an issue for this.
  • templates/plain_latex_wide/ is a lightly edited copy of the working group's template, so the two now diverge. Whichever repository owns the model descriptions should own the template.
  • The two software records disagree: metadata.yml records NumPy 2.2.6 and SciPy 1.14.1 while checks/expected.json records 2.3.5 and 1.17.1. Harmless, but worth regenerating from one environment.
  • nbclient is listed in requirements.txt for automated notebook execution, but nothing in the project uses it.
  • Running the notebook from the project directory rewrites metadata.yml and the CSVs with today's date and the local versions, so contributors will see a dirty tree. A sentence in the README warning about this would help.
  • The model description uses \pmb, \mathscr and \text{\textbf{Þ}}. Worth a look at GitHub's rendered view of model-description.md to confirm the math displays as intended.

Happy to merge once the three items above are in.

@mmcky
mmcky marked this pull request as ready for review September 14, 2026 23:59
Comment thread projects/HARK/BST/metadata.yml Outdated
metadata.yml is the example later projects will copy, and it listed
no authors. The notebook preserves this field when it rewrites the
file, so it only needs setting once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mmcky

mmcky commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

An update on the pre-merge items. Buffer stock is the first of a family of baseline templates and models, so the layout and conventions in this PR are the ones later models and toolkits will copy. That makes the three open items below worth settling before merge.

Done

  • authors in projects/HARK/BST/metadata.yml now lists Akshay Shanker (e045258).
  • The PR description now records the design decisions and the plan for the family of baseline models.
  • The five-model wording stands: buffer stock is the first of the family.

Still to settle before merge

  1. Reported numbers: required or optional? The model description says that "every implementation reports the MPC at the target" and that "each implementation evaluates" the conditions and the target equation, but the submission guide and the site call the result tables optional. The README and the site also still promise that implementations can be compared side by side. One option that keeps both: require the numbers but not the files. Every implementation would report c(m) at the 16 common points, the target and the MPC at the target (step 0.01) in whatever format it uses, while the CSV layout, metadata.yml and the tolerances stay optional. Whichever we choose, the model description, the guide and the PR description should say the same thing.
  2. A licence for the example code. The repository has no licence file and the HARK example doesn't state one, although the guide asks contributors to state the licence for their code and the site promises an OSI-approved licence. A line in projects/HARK/BST/README.md would do; Apache-2.0 would match HARK.
  3. One name for the model. The model lives in models/buffer-stock/ but its implementations in projects/<toolkit>/BST/, while the README's table uses <model> for both. Renaming later would break the site's links and every toolkit's directory, so let's choose one name now. Two smaller names in the example can be settled at the same time: the CSV row E_psi_1mrho (the notebook notes that it uses rho for gamma) and the metadata keys template_version and template_source, which predate the rename to model descriptions.

The follow-ups are in the next comment.

@mmcky

mmcky commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

@akshayshanker, here are the follow-ups, none of them blocking. They combine the ones from my earlier review with a few new ones. Could you look through them and flag any you disagree with? The rest can become issues after merge.

Shock approximation and the draft tolerances

I solved the model with the independent EGM solver in checks/independent_egm.py under finer shock approximations. Gauss–Hermite quadrature gives the same answer at 7, 11 and 21 nodes, and the equiprobable approximation approaches it as points are added (target 1.3994 at 21 points, 1.4018 at 101). Against that continuous-law answer, the seven-point approximation in the HARK example uses much of each threshold:

HARK example, 7 points Continuous law Gap Draft threshold
Target 1.3910 1.4022 0.011 0.02
Consumption, worst of the 16 points 0.017 0.02
MPC at the target 0.2696 0.2620 0.0076 0.01

So a toolkit using Gauss–Hermite quadrature would sit close to the thresholds against HARK with nothing wrong on either side. checks/sensitivity.md shows the trend but doesn't state the limit. It would help to publish the converged values next to the seven-point ones, or to revisit the thresholds.

Implementation

  • Software records. metadata.yml records NumPy 2.2.6 and SciPy 1.14.1, while checks/expected.json records 2.3.5 and 1.17.1. Regenerating both from one environment would make them agree.
  • Unused dependency. nbclient is listed in requirements.txt, but nothing in the project uses it.
  • Changed files after a run. Running the notebook from the project directory rewrites metadata.yml and the CSVs with the run date and local versions. A sentence in the HARK README would warn contributors about the changed files.
  • Leftover wording. A few docstrings in checks/ still say "template".

Infrastructure

  • CI. Add a job that runs pytest checks and executes the notebook. Together they take under a minute, and the site's roadmap says CI runs the implementations.
  • Rendering on the site. Publish the model descriptions on the library website as well as linking to the files on GitHub.
  • PDF template. templates/plain_latex_wide/ is an edited copy of the working group's template, and the two already differ. Whichever repository owns the model descriptions should own the template.

Wording and site

  • Working group name. The group's site has said "Language and Semantics" since late August, while the PDF's author line, the README and the site footer say "Language and Formal Semantics".
  • Math on GitHub. model-description.md uses \pmb, \mathscr and \text{\textbf{Þ}}. GitHub's rendered view is worth checking.
  • Copy. The repository card on the site no longer says "Hosted and published by QuantEcon", and the README's licensing section no longer says the library "does not own anyone's work", although the site still does.
  • HARK slot. In the site's model table, the "HARK example" link is styled like the empty "open" slots, so it doesn't read as filled or clickable.
  • Milestone. After merge, the working group site's "First baseline templates published" milestone can be marked done.

@mmcky

mmcky commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

@akshayshanker can you let me know if this is mergeable?

@mmcky

mmcky commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Not strictly needed for my presentation today -- but would be nice to have within the next week or so.

mmcky added a commit that referenced this pull request Oct 1, 2026
… name (#10)

The library table gains buffer-stock saving as its first row, with HARK's
solution (in review in #5) in its first slot and its description marked as a
draft; the four proposed families are marked "description (planned)".

#5 replaced the template notebook with a shared model description, so
section 04 becomes "Model descriptions" and the remaining mentions of
templates follow. QuantEcon's role now reads "develops shared tooling in
consultation with the projects", linking its infrastructure page, and the
AI advisor moves from Phase 1 to Phase 2 as something to explore.

The footer and README use the group's settled name, Language and Semantics;
the footer links the working group's code of conduct; and the README's
entry for the Project B talk no longer points to its source.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the conflicts with QuantEcon#8-QuantEcon#11. Main's QuantEcon#10 had already reworded the
landing page for this PR, so the PR's rewritten content stands where it
replaced a section outright, and main wins on what it settled since.

The site keeps main's #descriptions anchor and "Descriptions" rail entry,
the Presentations section, the AI advisor moved to Phase 2, the code of
conduct link, the model-family form and the "Language and Semantics"
name. Section 04, the Contribute section, the library footnote and the
ask keep this branch's text. The buffer-stock row keeps main's name and
filled-slot style, but its HARK slot now links to the notebook rather
than to this PR, and its description links to the PDF.

The README keeps this branch's structure and drops main's Status
section, which would go stale once this PR merges; it takes the group's
settled name and mentions the Project B talk deck under website
maintenance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mmcky

mmcky commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

@mmcky to do:

  • mark as preliminary
  • introduce a version + quality system to published templates

akshayshanker and others added 3 commits October 20, 2026 11:27
The HARK implementation moves from projects/HARK/BST/ to
projects/HARK/buffer-stock/, so the model has the same directory name
under models/ and projects/. The test module becomes
test_buffer_stock.py.

Two names in the example follow. The CSV row E_psi_1mrho becomes
E_psi_1mgamma, matching the model description's gamma. The metadata
keys template_version and template_source become
model_description_version and model_description, and model: BST
becomes model: buffer-stock. The notebook's stored outputs are
refreshed in a later commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every implementation now reports consumption at the sixteen common
resource values, the target and the MPC at the target with step 0.01,
in a format of its choosing. The CSV layouts, metadata example and
tolerances stay optional. The model description lists the required
results at the end of section 3 and asks each implementation to confirm
that the conditions hold under its own shock approximation; the guide
adds the results as item 2 of what to submit; the README and the site's
cards, steps, panel, note and Contribute section say the same. The PDF
is rebuilt in a later commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The HARK example's README now states that its code, including the
notebook and checks/, is released under the Apache License 2.0, as HARK
is, and that the model description is CC-BY-4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
akshayshanker and others added 9 commits October 20, 2026 11:28
requirements.txt drops nbclient, which nothing uses, and adds sympy:
HARK 0.17.1 imports it without declaring it, so a fresh install of the
file could not import HARK. The README warns that running the notebook
rewrites metadata.yml and results/ with the run date and local versions,
and explains that checks/expected.json keeps the software record of the
calculation it preserves. Docstrings in checks/ say "model description"
instead of "template".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README's licensing section again says the library "does not own
anyone's work", as the site does, and the site's repository card again
says "Hosted and published by QuantEcon", now followed by the models/
and projects/ layout instead of the old one-directory-per-model layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The PDF template's author line now reads "Language and Semantics", the
name decided in QuantEcon#7 and used in econ-ark/sce-wg-1#5. The model description
writes the absolute patience factor as \textbf{Þ} instead of
\text{\textbf{Þ}}: MathJax, which renders math on GitHub, does not read
commands inside \text without its text-macros extension, and LaTeX gives
the same output either way. The PDF is rebuilt with the revised section
3 and dated 20 October 2026; it remains four pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Executed from a fresh kernel with HARK 0.17.1, Python 3.12.7, NumPy
2.5.4, SciPy 1.18.1, pandas 3.0.6 and matplotlib 3.11.2, installed from
requirements.txt. The notebook's outputs now show the E_psi_1mgamma row,
and metadata.yml records this run under the renamed keys. The result
tables differ from the previous ones by at most 1.1e-14, and
python -m pytest -q checks passes (14 tests) in the same environment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The notebook's final cell wrote the method, discretisation and grid into
metadata.yml as fixed strings, so changing aXtraCount or PermShkCount and
rerunning would record settings the calculation no longer used. They are
now read from the agent, and the MPC step is named once in the reporting
cell and recorded from there.

The cell also copied `authors` from an existing metadata.yml in the
working directory, so a run from any other directory wrote `authors: []`.
The authors are now set in the notebook.

Re-executed from a fresh kernel with Python 3.12.7 and the pinned
requirements; the stored outputs are unchanged, and metadata.yml changes
only in the generated discretisation wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Section 04 linked the text to the models/buffer-stock folder, which
GitHub opens on the submission guide, while the same text in Contribute
opens model-description.md. Both now open the description.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The example showed `software` as one string, while the HARK
metadata.yml beside it maps each package to its version and also
records `target_mpc`. The example now has the same shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The conditions table gives 0.068 for the weak return impatience factor,
while the paper's calibration table prints 0.071, which is the same
factor before the division by R. A sentence after the table says so, so
a reader checking the two does not take either for an error. The PDF is
rebuilt and remains four pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tests solved the model through checks/hark_checks.py but never read
the result files the notebook commits, which hold the numbers every
implementation now reports. The CSV checks from the module test move
into a helper that also runs on the committed results/, and a new test
checks that the committed metadata.yml credits its authors.

The conditions test now compares FVAC with HARK's own result, and the
MPC test checks that the reported step-0.01 MPC also lies between the
limiting MPCs. 16 tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mmcky

mmcky commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Will follow up on final actions.

Thanks @akshayshanker

@mmcky
mmcky merged commit f1516d5 into QuantEcon:main Oct 20, 2026
2 checks passed
llorracc added a commit to llorracc/sce-wg-1-dev that referenced this pull request Oct 21, 2026
The community library's HARK implementation of the buffer-stock model, added by
QuantEcon/community-library#5 as projects/HARK/buffer-stock/, now lives at
solutions/buffer-stock/001-hark-egm/, moved there by #15. It uses HARK alone, at econ-ark 0.17.1;
its independent check is an endogenous-grid solver in NumPy and SciPy.

Claude-Session: https://claude.ai/code/session_01AVHe7BA5PMhQ9H4LHp7ewM
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.

3 participants