QuantEcon / QuantEcon/QuantEcon.py
Refactor DLE (_dle.py) to use native scalars and 1-D arrays instead of (1, 1)/2-D matrix conventions
Nobody has claimed this yet.
- 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
e1as 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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