Skip to content

feat: masked-grid derivative operators + mask regularizations (potential correction phase 1)#390

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/potential-correction-port
Jul 17, 2026
Merged

feat: masked-grid derivative operators + mask regularizations (potential correction phase 1)#390
Jammy2211 merged 1 commit into
mainfrom
feature/potential-correction-port

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Phase 1 of porting the gravitational-imaging (potential correction) technique into the PyAuto stack (PyAutoLabs/PyAutoLens#618): the generic linear-algebra layer. Adds sparse finite-difference derivative operators on masked 2D grids, coarse-mesh→fine-grid bilinear interpolation, and two mask-based regularization schemes (CurvatureMask, FourthOrderMask) used to regularize pixelized corrections of the lensing potential.

Ported from the potential_correction package of Cao et al. 2025 (https://github.com/caoxiaoyue/lensing_potential_correction); all new modules cite it and https://github.com/caoxiaoyue/potential_correction_paper. The port is parity-certified bit-identical against the original on randomized masks; Cao's ~400-line unrolled fourth-order stencil cascade is collapsed into one general forward-difference builder (coefficients (-1)^(L-k) C(L,k) / h^L, order degrading with the unmasked run length). One genuine bug in the original is fixed rather than ported: its nearest-interpolation-box search indexes with negative wrap-around and crashes (KeyError) when the search runs off the coarse-mesh edge — the port clamps the search bounds and raises a loud MeshException when the mesh has no usable interpolation box.

The existing GaussianKernel / ExponentialKernel / MaternKernel regularizations already cover the original's covariance_reg.py, so that module is deliberately not ported. No new dependencies (the original's GPy / multiprocess / powerbox / numba-scipy are not adopted). NumPy/numba only — the JAX port is a known follow-up.

Phases 2 (PyAutoGalaxy input pixelized mass profiles) and 3 (the autolens/potential_correction subpackage) follow in separate PRs — see the issue plan.

API Changes

Added only — nothing removed or changed. Two new regularization classes, aa.reg.CurvatureMask and aa.reg.FourthOrderMask, regularize linear objects defined on rectangular masked grids (the linear object must expose its mask). Two new util modules, aa.util.derivative (masked-grid sparse derivative operators + mask cleaning) and aa.util.coarse_interp (coarse-mesh binning + bilinear interpolation matrices), carry the underlying builders.
See full details below.

Test Plan

  • 28 new tests: analytic exactness (1st derivatives on linear functions, 2nd on quadratics, 4th-order stencils annihilate cubics), hand-computed stencil matrices, symmetry/PSD of regularization matrices, bilinear partition-of-unity + exactness, edge-search and no-box error paths.
  • Full test_autoarray/inversion + test_autoarray/operators suites: 309 passed.
  • Parity harness vs the original implementation on randomized masks/pixel scales: bit-identical operators, regularization matrices and interpolation matrices on every non-crashing trial; valid output where the original crashes.
Full API Changes (for automation & release notes)

Added

  • aa.reg.CurvatureMask(coefficient=1.0) — curvature regularization on the unmasked pixels of a rectangular masked 2D grid (forward second-difference stencils, degrading to first/zeroth order at the mask edge); regularization_matrix_from(linear_obj) reads linear_obj.mask.
  • aa.reg.FourthOrderMask(coefficient=1.0) — fourth-order variant (stencils degrade 4th→3rd→2nd→1st→0th); weaker prior permitting localised curvature.
  • autoarray/inversion/regularization/curvature_mask.py::curvature_reg_matrix_via_mask_from(mask, pixel_scale=1.0).
  • autoarray/inversion/regularization/fourth_order_mask.py::fourth_order_reg_matrix_via_mask_from(mask, pixel_scale=1.0).
  • aa.util.derivative (new module autoarray/operators/derivative_util.py):
    • cleaned_mask_from(mask, max_iter=50) / clean_mask_iteration_from(mask) — iteratively mask pixels that cannot support a finite-difference scheme; returns the cleaned mask + per-pixel scheme types.
    • derivative_1st_operators_from(mask, pixel_scale=1.0) → sparse (Hy, Hx); derivative_2nd_operators_from(mask, pixel_scale=1.0) → sparse (Hyy, Hxx) (central/one-sided schemes per pixel; raises MaskException on uncleaned masks).
    • forward_difference_operators_from(mask, pixel_scale=1.0, max_order=2) → order-capped forward-difference operators (every unmasked pixel gets a row; order degrades at mask edges).
    • forward_difference_reg_matrix_from(mask, pixel_scale=1.0, max_order=2) → sparse Hx^T Hx + Hy^T Hy.
    • triplet-level builders derivative_1st_triplets_from / derivative_2nd_triplets_from / forward_difference_triplets_from.
  • aa.util.coarse_interp (new module autoarray/operators/coarse_interp_util.py):
    • binned_image_from(arr, bin_factor) / binned_mask_from(mask, bin_factor) — coarse pixel unmasked only if every fine pixel inside it is unmasked.
    • interp_box_mask_from(mask) — mask of 2x2 coarse-corner interpolation boxes.
    • bilinear_weights_from_box(box_x, box_y, position) — bilinear weights of a (y, x) position in a box.
    • coarse_interp_matrix_from(...) → sparse [n_fine, n_coarse] bilinear interpolation matrix (nearest-unmasked-box search, bounds-clamped; raises MeshException if the mesh has no unmasked box); triplet-level coarse_interp_triplets_from.

Migration

  • None — additive only.

Generated by the PyAutoLabs agent workflow.

…ask regularizations (potential correction phase 1)

Ports the generic linear-algebra layer of the gravitational-imaging
(potential correction) technique of Cao et al. 2025
(https://github.com/caoxiaoyue/lensing_potential_correction) into
autoarray: sparse finite-difference derivative operators on masked 2D
grids, coarse-mesh bilinear interpolation matrices, and the
CurvatureMask / FourthOrderMask regularizations. Parity-certified
against the original; cite via
https://github.com/caoxiaoyue/potential_correction_paper.

Phase 1 of PyAutoLabs/PyAutoLens#618.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 17, 2026
@Jammy2211
Jammy2211 merged commit d6cb7eb into main Jul 17, 2026
4 checks passed
@Jammy2211
Jammy2211 deleted the feature/potential-correction-port branch July 17, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant