QuantEcon / QuantEcon/QuantEcon.py

Refactor DLE (_dle.py) to use native scalars and 1-D arrays instead of (1, 1)/2-D matrix conventions

Open
#844 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

breaking discuss refactor
Dominant language
Python
Stars
2.4k
Forks
2.3k
Avg merge
3d 3h
Merged PRs (30d)
3

Description

Background

This came out of the review of #842 (which fixed #839). @oyamad noted that quantecon/_dle.py is written in a very "matrix-oriented" style that differs from the rest of the library and is the root cause of the NumPy 2.4 breakage that #842 patched.

In _dle.py, conceptually scalar quantities are stored as (1, 1) arrays and conceptually 1-D vectors are stored as 2-D row arrays. Concretely: self.beta is a (1, 1) array (a scalar discount factor), e1 is built as a (1, nc) 2-D row selector, and the bond-price expressions therefore reduce to size-1 (ndim > 0) arrays rather than plain scalars.

Why it matters

Concern Detail
Fragility Because the price terms are size-1 arrays, assigning them into scalar slots (self.R1_Price[i, 0] = ...) relied on NumPy implicitly converting an ndim > 0 array to a scalar. That conversion was deprecated in NumPy 1.25 and became a hard error in NumPy 2.4 — exactly the #839 regression. #842 worked around it with .item(), but the same fragility lurks anywhere this matrix convention yields a size-1 result.
Readability Readers must constantly track whether a quantity is a scalar, a (1,) vector, or a (1, 1) matrix. The precedence between * and @ (same precedence, left-associative) becomes load-bearing and easy to get subtly wrong.
Inconsistency The rest of QuantEcon.py uses native scalars and 1-D arrays. _dle.py is an outlier, which raises the barrier to contribution and maintenance.

Proposed change

The idea is to make the representation match the mathematics:

  • Store scalar parameters (e.g. beta) as native Python/NumPy scalars rather than (1, 1) arrays.
  • Store conceptual vectors as 1-D arrays, and build selectors such as e1 as 1-D.
  • Assemble the price/return series from genuine scalars, which removes the need for the .item() coercions added in #842 and makes the price loop read directly as its closed form.

Scope and risks

This is a global rewrite of _dle.py, not a local edit — which is why it was deliberately kept out of #842.

It is potentially breaking: public attributes such as DLE.beta (and possibly others) would change shape from (1, 1) to scalar, which could affect downstream code and the DLE lectures in lecture-python-advanced.myst (cattle_cycles, growth_in_dles, irfs_in_hall_model, lucas_asset_pricing_dles, permanent_income_dles). This warrants an audit of which attributes are part of the public API and whether a deprecation path is needed.

#842 added the first regression tests for compute_sequence (test_compute_sequence, test_compute_sequence_with_pay). Before attempting the refactor, test coverage should be expanded further (e.g. irf and the other public attributes) so the current numerical behaviour can be pinned and compared before/after.

References

  • Regression that triggered this: #839
  • Workaround / minimal fix: #842
  • Style point raised by @oyamad in the #842 review

🤖 Generated with Claude Code

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with quantecon/_dle.py and the existing test_compute_sequence and test_compute_sequence_with_pay regression tests added for #842. Audit the public attributes and the DLE lecture references named in the issue before changing representations. Done means scalar and 1-D conventions are consistent, numerical behavior is pinned by expanded tests including irf, and API compatibility or deprecation needs are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
backend
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.