Skip to content

Commit b495620

Browse files
Jammy2211Jammy2211
authored andcommitted
do same in numba sparse
1 parent 10f0a47 commit b495620

File tree

1 file changed

+85
-41
lines changed
  • autoarray/inversion/inversion/imaging_numba

1 file changed

+85
-41
lines changed

autoarray/inversion/inversion/imaging_numba/sparse.py

Lines changed: 85 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,61 @@ def _curvature_matrix_func_list_and_mapper(self) -> np.ndarray:
467467

468468
return curvature_matrix
469469

470+
def _mapped_reconstructed_data_dict_from(
471+
self,
472+
*,
473+
use_operated_for_linear_func: bool,
474+
) -> Dict["LinearObj", "Array2D"]:
475+
"""
476+
Shared implementation for mapping a reconstruction to image-plane arrays for each linear object.
477+
478+
- AbstractMapper: uses unique mappings (w-tilde compatible) + PSF convolution.
479+
- Linear-func: uses either operated or unoperated mapping matrix dict.
480+
"""
481+
mapped_dict: Dict["LinearObj", "Array2D"] = {}
482+
483+
reconstruction_dict = self.source_quantity_dict_from(
484+
source_quantity=self.reconstruction
485+
)
486+
487+
for linear_obj in self.linear_obj_list:
488+
reconstruction = reconstruction_dict[linear_obj]
489+
490+
if isinstance(linear_obj, AbstractMapper):
491+
492+
mapped = inversion_imaging_numba_util.mapped_reconstructed_data_via_image_to_pix_unique_from(
493+
data_to_pix_unique=linear_obj.unique_mappings.data_to_pix_unique,
494+
data_weights=linear_obj.unique_mappings.data_weights,
495+
pix_lengths=linear_obj.unique_mappings.pix_lengths,
496+
reconstruction=np.array(reconstruction),
497+
)
498+
499+
mapped = Array2D(values=mapped, mask=self.mask)
500+
501+
if use_operated_for_linear_func:
502+
mapped = self.psf.convolved_image_from(
503+
image=mapped,
504+
blurring_image=None,
505+
).array
506+
507+
mapped = Array2D(values=mapped, mask=self.mask)
508+
509+
else:
510+
511+
if use_operated_for_linear_func:
512+
mapping_matrix = self.linear_func_operated_mapping_matrix_dict[linear_obj]
513+
else:
514+
mapping_matrix = self.linear_func_mapping_matrix_dict[linear_obj]
515+
516+
mapped = np.sum(reconstruction * mapping_matrix, axis=1)
517+
mapped = Array2D(values=mapped, mask=self.mask)
518+
519+
mapped_dict[linear_obj] = mapped
520+
521+
return mapped_dict
522+
470523
@property
471-
def mapped_reconstructed_operated_data_dict(self) -> Dict[LinearObj, Array2D]:
524+
def mapped_reconstructed_data_dict(self) -> Dict[LinearObj, Array2D]:
472525
"""
473526
When constructing the simultaneous linear equations (via vectors and matrices) the quantities of each individual
474527
linear object (e.g. their `mapping_matrix`) are combined into single ndarrays via stacking. This does not track
@@ -482,6 +535,9 @@ def mapped_reconstructed_operated_data_dict(self) -> Dict[LinearObj, Array2D]:
482535
This function converts an ndarray of a `reconstruction` to a dictionary of ndarrays containing each linear
483536
object's reconstructed data values, where the keys are the instances of each mapper in the inversion.
484537
538+
The images are the unconvolved reconstructed data values, meaning they are the solved for reconstruction
539+
with PSF operations removed.
540+
485541
The w-tilde formalism bypasses the calculation of the `mapping_matrix` and it therefore cannot be used to map
486542
the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used,
487543
including the 2D convolution operation after mapping is complete.
@@ -492,52 +548,40 @@ def mapped_reconstructed_operated_data_dict(self) -> Dict[LinearObj, Array2D]:
492548
The reconstruction (in the source frame) whose values are mapped to a dictionary of values for each
493549
individual mapper (in the image-plane).
494550
"""
495-
496-
mapped_reconstructed_operated_data_dict = {}
497-
498-
reconstruction_dict = self.source_quantity_dict_from(
499-
source_quantity=self.reconstruction
551+
return self._mapped_reconstructed_data_dict_from(
552+
use_operated_for_linear_func=False
500553
)
501554

502-
for linear_obj in self.linear_obj_list:
503-
reconstruction = reconstruction_dict[linear_obj]
504-
505-
if isinstance(linear_obj, AbstractMapper):
506-
507-
mapped_reconstructed_image = inversion_imaging_numba_util.mapped_reconstructed_data_via_image_to_pix_unique_from(
508-
data_to_pix_unique=linear_obj.unique_mappings.data_to_pix_unique,
509-
data_weights=linear_obj.unique_mappings.data_weights,
510-
pix_lengths=linear_obj.unique_mappings.pix_lengths,
511-
reconstruction=np.array(reconstruction),
512-
)
513-
514-
mapped_reconstructed_image = Array2D(
515-
values=mapped_reconstructed_image, mask=self.mask
516-
)
517-
518-
mapped_reconstructed_image = self.psf.convolved_image_from(
519-
image=mapped_reconstructed_image,
520-
blurring_image=None,
521-
).array
555+
@property
556+
def mapped_reconstructed_operated_data_dict(self) -> Dict[LinearObj, Array2D]:
557+
"""
558+
When constructing the simultaneous linear equations (via vectors and matrices) the quantities of each individual
559+
linear object (e.g. their `mapping_matrix`) are combined into single ndarrays via stacking. This does not track
560+
which quantities belong to which linear objects, therefore the linear equation's solutions (which are returned
561+
as ndarrays) do not contain information on which linear object(s) they correspond to.
522562
523-
mapped_reconstructed_image = Array2D(
524-
values=mapped_reconstructed_image, mask=self.mask
525-
)
563+
For example, consider if two `Mapper` objects with 50 and 100 source pixels are used in an `Inversion`.
564+
The `reconstruction` (which contains the solved for source pixels values) is an ndarray of shape [150], but
565+
the ndarray itself does not track which values belong to which `Mapper`.
526566
527-
else:
567+
This function converts an ndarray of a `reconstruction` to a dictionary of ndarrays containing each linear
568+
object's reconstructed data values, where the keys are the instances of each mapper in the inversion.
528569
529-
operated_mapping_matrix = self.linear_func_operated_mapping_matrix_dict[
530-
linear_obj
531-
]
570+
The images are the convolved reconstructed data values, meaning they are the solved for reconstruction with PSF
571+
operations included.
532572
533-
mapped_reconstructed_image = np.sum(
534-
reconstruction * operated_mapping_matrix, axis=1
535-
)
573+
The w-tilde formalism bypasses the calculation of the `mapping_matrix` and it therefore cannot be used to map
574+
the reconstruction's values to the image-plane. Instead, the unique data-to-pixelization mappings are used,
575+
including the 2D convolution operation after mapping is complete.
536576
537-
mapped_reconstructed_image = Array2D(
538-
values=mapped_reconstructed_image, mask=self.mask
539-
)
577+
Parameters
578+
----------
579+
reconstruction
580+
The reconstruction (in the source frame) whose values are mapped to a dictionary of values for each
581+
individual mapper (in the image-plane).
582+
"""
583+
return self._mapped_reconstructed_data_dict_from(
584+
use_operated_for_linear_func=True
585+
)
540586

541-
mapped_reconstructed_operated_data_dict[linear_obj] = mapped_reconstructed_image
542587

543-
return mapped_reconstructed_operated_data_dict

0 commit comments

Comments
 (0)