-
Notifications
You must be signed in to change notification settings - Fork 8
Feature/matern adaptive #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
09be29c
ac9805b
e366b49
f724404
9184f28
a14f39a
244caf0
12de13b
29a2d89
e102dc7
917b78c
95cf5b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,153 @@ | ||||||
| from __future__ import annotations | ||||||
| import numpy as np | ||||||
| from typing import TYPE_CHECKING | ||||||
|
|
||||||
| from autoarray.inversion.regularization.matern_kernel import MaternKernel | ||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from autoarray.inversion.linear_obj.linear_obj import LinearObj | ||||||
|
|
||||||
| from autoarray.inversion.regularization.matern_kernel import matern_kernel | ||||||
|
|
||||||
|
|
||||||
| def matern_cov_matrix_from( | ||||||
| scale: float, | ||||||
| nu: float, | ||||||
| pixel_points, | ||||||
| weights=None, | ||||||
| xp=np, | ||||||
| ): | ||||||
| """ | ||||||
| Construct the regularization covariance matrix (N x N) using a Matérn kernel, | ||||||
| optionally modulated by per-pixel weights. | ||||||
|
|
||||||
| If `weights` is provided (shape [N]), the covariance is: | ||||||
| C_ij = K(d_ij; scale, nu) * w_i * w_j | ||||||
| with a small diagonal jitter added for numerical stability. | ||||||
|
|
||||||
| Parameters | ||||||
| ---------- | ||||||
| scale | ||||||
| Typical correlation length of the Matérn kernel. | ||||||
| nu | ||||||
| Smoothness parameter of the Matérn kernel. | ||||||
| pixel_points | ||||||
| Array-like of shape [N, 2] with (y, x) coordinates (or any 2D coords; only distances matter). | ||||||
| weights | ||||||
| Optional array-like of shape [N]. If None, treated as all ones. | ||||||
| xp | ||||||
| Backend (numpy or jax.numpy). | ||||||
|
|
||||||
| Returns | ||||||
| ------- | ||||||
| covariance_matrix | ||||||
| Array of shape [N, N]. | ||||||
| """ | ||||||
|
|
||||||
| # -------------------------------- | ||||||
| # Pairwise distances (broadcasted) | ||||||
| # -------------------------------- | ||||||
| diff = pixel_points[:, None, :] - pixel_points[None, :, :] # (N, N, 2) | ||||||
| d_ij = xp.sqrt(diff[..., 0] ** 2 + diff[..., 1] ** 2) # (N, N) | ||||||
|
|
||||||
| # -------------------------------- | ||||||
| # Base Matérn covariance | ||||||
| # -------------------------------- | ||||||
| covariance_matrix = matern_kernel(d_ij, l=scale, v=nu, xp=xp) # (N, N) | ||||||
|
|
||||||
| # -------------------------------- | ||||||
| # Apply weights: C_ij *= w_i * w_j | ||||||
| # (broadcasted outer product, JAX-safe) | ||||||
| # -------------------------------- | ||||||
| if weights is not None: | ||||||
| w = xp.asarray(weights) | ||||||
| # Ensure shape (N,) -> outer product (N,1)*(1,N) -> (N,N) | ||||||
| covariance_matrix = covariance_matrix * (w[:, None] * w[None, :]) | ||||||
|
|
||||||
| # -------------------------------- | ||||||
| # Add diagonal jitter (JAX-safe) | ||||||
| # -------------------------------- | ||||||
| pixels = pixel_points.shape[0] | ||||||
| covariance_matrix = covariance_matrix + 1e-8 * xp.eye(pixels) | ||||||
|
|
||||||
| return covariance_matrix | ||||||
|
|
||||||
|
|
||||||
| class MaternAdaptiveBrightnessKernel(MaternKernel): | ||||||
| def __init__( | ||||||
| self, | ||||||
| coefficient: float = 1.0, | ||||||
| scale: float = 1.0, | ||||||
| nu: float = 0.5, | ||||||
| rho: float = 1.0, | ||||||
| ): | ||||||
| """ | ||||||
| Regularization which uses a Matern smoothing kernel to regularize the solution with regularization weights | ||||||
| that adapt to the brightness of the source being reconstructed. | ||||||
|
|
||||||
| For this regularization scheme, every pixel is regularized with every other pixel. This contrasts many other | ||||||
| schemes, where regularization is based on neighboring (e.g. do the pixels share a Delaunay edge?) or computing | ||||||
| derivates around the center of the pixel (where nearby pixels are regularization locally in similar ways). | ||||||
|
|
||||||
| This makes the regularization matrix fully dense and therefore maybe change the run times of the solution. | ||||||
|
Jammy2211 marked this conversation as resolved.
Outdated
|
||||||
| It also leads to more overall smoothing which can lead to more stable linear inversions. | ||||||
|
|
||||||
| For the weighted regularization scheme, each pixel is given an 'effective regularization weight', which is | ||||||
| applied when each set of pixel neighbors are regularized with one another. The motivation of this is that | ||||||
| different regions of a pixelization's mesh require different levels of regularization (e.g., high smoothing where the | ||||||
| no signal is present and less smoothing where it is, see (Nightingale, Dye and Massey 2018)). | ||||||
|
|
||||||
| This scheme is not used by Vernardos et al. (2022): https://arxiv.org/abs/2202.09378, but it follows | ||||||
| a similar approach. | ||||||
|
|
||||||
| A full description of regularization and this matrix can be found in the parent `AbstractRegularization` class. | ||||||
|
|
||||||
| Parameters | ||||||
| ---------- | ||||||
| coefficient | ||||||
| The regularization coefficient which controls the degree of smooth of the inversion reconstruction. | ||||||
| scale | ||||||
| The typical scale of the exponential regularization pattern. | ||||||
|
||||||
| The typical scale of the exponential regularization pattern. | |
| The typical scale of the Matérn regularization pattern. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ def __init__( | |
| linear_light_profile_blurred_mapping_matrix=None, | ||
| use_voronoi_areas: bool = True, | ||
| areas_factor: float = 0.5, | ||
| skip_areas: bool = False, | ||
|
||
| ): | ||
| """ | ||
| Stores preloaded arrays and matrices used during pixelized linear inversions, improving both performance | ||
|
|
@@ -123,3 +124,4 @@ def __init__( | |
|
|
||
| self.use_voronoi_areas = use_voronoi_areas | ||
| self.areas_factor = areas_factor | ||
| self.skip_areas = skip_areas | ||
Uh oh!
There was an error while loading. Please reload this page.