Add numerical guards for CES with heterogeneous epsilon#1096
Open
vahid-ahmadi wants to merge 1 commit intoPSLmodels:masterfrom
Open
Add numerical guards for CES with heterogeneous epsilon#1096vahid-ahmadi wants to merge 1 commit intoPSLmodels:masterfrom
vahid-ahmadi wants to merge 1 commit intoPSLmodels:masterfrom
Conversation
…epsilon When epsilon differs from 1.0 across sectors, the CES production function raises K, L, and K_g to (epsilon-1)/epsilon, which is negative for epsilon < 1. If any input is zero or near-zero (common during initial solver iterations), this produces inf or NaN, causing the SS and TPI solvers to fail. Changes: - Add _FLOOR (1e-12) constant and apply np.maximum() guards before all CES power operations in get_Y, get_MPx, get_KLratio_KLonly, and solve_L - Fix bug in get_MPx: np.any(x) == 0 should be np.any(x == 0) - Guard denominator in get_KLratio_KLonly CES branch against negative values These guards only affect the general CES code paths (epsilon != 1); the Cobb-Douglas special case (epsilon == 1) is unchanged. Tested with OG-UK 8-sector model using heterogeneous epsilon values (0.40-1.30) — SS solver now converges successfully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
vahid-ahmadi
added a commit
to vahid-ahmadi/OG-UK
that referenced
this pull request
Mar 31, 2026
Two changes:
1. Make single-sector (M=1) the default run mode. The 8-sector industry
calibration is now opt-in via `multi_sector=True` parameter on
solve_steady_state() and run_transition_path(), or via the
`multi-sector` CLI flag:
uv run python examples/run_oguk.py ss pooled # M=1
uv run python examples/run_oguk.py ss pooled multi-sector # M=8
2. Enable calibrated heterogeneous CES elasticities (epsilon) in the
8-sector mode. Previously forced to 1.0 (Cobb-Douglas) for all
sectors due to solver NaN issues — now uses literature values from
Chirinko (2008) and Knoblach et al. (2020):
Energy=0.50, Construction=0.70, Trade & Transport=1.00,
Info & Finance=1.20, Real Estate=0.40, Business Services=1.30,
Public & Other=0.90, Manufacturing=0.80
Supporting changes:
- Recalibrate TFP (Z) using CES Solow residuals instead of
Cobb-Douglas residuals when epsilon != 1
- Use hybr root-finder (Powell hybrid) instead of LM for
multi-sector SS — LM gets stuck at ~1e-5 residuals
- Relax mindist_SS and RC_SS to 1e-4 for multi-sector
Requires OG-Core PR PSLmodels/OG-Core#1096 (numerical guards for
CES production functions).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jdebacker
approved these changes
Apr 2, 2026
Member
|
@vahid-ahmadi Can you merge in upstream changes? And then run I think tests should pass and this will be set to merge then. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_FLOOR = 1e-12guards infirm.pyto prevent0^(negative)→ inf/NaN when CES epsilon ≠ 1get_MPx:np.any(x) == 0should benp.any(x == 0)(the original always evaluates to False)get_Y,get_MPx,get_KLratio_KLonly, andsolve_L— only in the general CES code paths; Cobb-Douglas (ε=1) is unchangedMotivation
When
epsilonvaries across sectors (e.g., Energy=0.50, Real Estate=0.40, Info & Finance=1.20), the CES production function raises K, L, K_g to(epsilon-1)/epsilon. For epsilon < 1, this exponent is negative, so any zero or near-zero input during initial solver iterations produces inf/NaN and crashes the solver.This was blocking OG-UK from using calibrated sector-specific CES elasticities from Chirinko (2008) and Knoblach et al. (2020). With this fix, OG-UK's 8-sector model with heterogeneous epsilon (0.40–1.30) converges successfully in both SS and TPI.
Test plan
🤖 Generated with Claude Code