feat: MGE/CSE fallback for zero-returning mass profile potentials#449
Merged
Conversation
Replace zero-returning potential_2d_from and convergence_2d_from methods across 10 mass profiles with proper implementations: - PointMass: analytic potential psi = R_E^2 * ln(r) - MassSheet: analytic potential psi = 0.5 * kappa * r^2 - cNFW/cNFWSph: convergence + potential via MGE decomposition - NFWTruncatedSph: potential via MGE decomposition - Sersic/SersicSph: potential via MGE decomposition - Gaussian: potential via MGE decomposition - Chameleon/ChameleonSph: potential via MGE decomposition - PowerLawBroken/Sph: potential via MGE decomposition - dPIEMass/Sph: potential via MGE decomposition - dPIEPotential/Sph: potential via MGE decomposition New potential_2d_via_mge_from method on MGEDecomposer using the E1 (exponential integral) formula from Shajib (2019), cross-validated against Jax-Lensing-Profiles (Herculens). Self-consistency verified to 0.3% (laplacian of MGE potential = 2 * MGE convergence). Phase 3 of mass profiles refactoring epic (#445). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced May 26, 2026
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
Replace zero-returning
potential_2d_fromandconvergence_2d_frommethods across 10 mass profiles with proper implementations. Adds a newpotential_2d_via_mge_frommethod toMGEDecomposerusing the E1 (exponential integral) formula from Shajib (2019), cross-validated against Jax-Lensing-Profiles (Herculens). Phase 3 of the mass profiles refactoring epic (#445).Three tiers of implementation:
potential_2d_via_mge_fromSelf-consistency validated: laplacian(ψ_MGE) = 2κ_MGE to 0.3% median error. The ~5-9% error vs profiles with known analytic potentials is inherent to the MGE decomposition (convergence itself has similar error), not the potential formula.
API Changes
Added
MGEDecomposer.potential_2d_via_mge_from()— new public method computing lensing potential from MGE-decomposed convergence using the E1 exponential integral. Added helper methodsE1()(Abramowitz & Stegun approximation, JAX-compatible) andpotential_func_gaussian(). All existing zero-returning methods now return physically meaningful values instead of zeros. See full details below.Test Plan
pytest test_autogalaxy/profiles/mass/— 406 passed, 0 failedtest_mass_sheet.pyto match new correct potential valuesFull API Changes (for automation & release notes)
Added
MGEDecomposer.E1(x, xp)— static method, exponential integral of first order (Abramowitz & Stegun 1970)MGEDecomposer.potential_func_gaussian(grid_radii, sigma, intensity, xp)— potential of a single Gaussian convergence componentMGEDecomposer.potential_2d_via_mge_from(grid, *, sigma_log_list, three_D, ellipticity_convention, ...)— lensing potential via MGE decompositionMGEDecomposer._potential_2d_via_mge_from(grid_radii, *, sigma_log_list, ...)— internal implementationChanged Behaviour
PointMass.potential_2d_from— was zeros, now returns ψ = R_E² ln(r)MassSheet.potential_2d_from— was zeros, now returns ψ = ½κr²cNFW.convergence_2d_from/cNFWSph.convergence_2d_from— was zeros, now MGE-computedcNFW.potential_2d_from/cNFWSph.potential_2d_from— was zeros, now MGE-computedNFWTruncatedSph.potential_2d_from— was zeros, now MGE-computedAbstractSersic.potential_2d_from(Sersic, SersicSph) — was zeros, now MGE-computedGaussian.potential_2d_from— was zeros, now MGE-computedChameleon.potential_2d_from— was zeros, now MGE-computedPowerLawBroken.potential_2d_from— was zeros, now MGE-computeddPIEMass.potential_2d_from— was zeros, now MGE-computeddPIEPotential.potential_2d_from/dPIEPotentialSph.potential_2d_from— was zeros, now MGE-computedMigration
No migration needed — methods that returned zeros now return physically correct values. Any code that relied on these methods returning zeros was already broken (using a placeholder).
🤖 Generated with Claude Code