@@ -442,6 +442,102 @@ def adaptive_pixel_signals_from(
442442 return pixel_signals ** signal_scale
443443
444444
445+ import numpy as np
446+
447+ def pixel_triplets_from_subpixel_arrays_from (
448+ pix_indexes_for_sub , # (M_sub, P)
449+ pix_weights_for_sub , # (M_sub, P)
450+ slim_index_for_sub , # (M_sub,)
451+ fft_index_for_masked_pixel , # (N_unmasked,)
452+ sub_fraction_slim , # (N_unmasked,)
453+ * ,
454+ xp = np ,
455+ ):
456+ """
457+ Build sparse source→image mapping triplets (rows, cols, vals)
458+ for a fixed-size interpolation stencil.
459+
460+ This supports both:
461+ - NumPy (xp=np)
462+ - JAX (xp=jax.numpy)
463+
464+ Parameters
465+ ----------
466+ pix_indexes_for_sub
467+ Source pixel indices for each subpixel (M_sub, P)
468+ pix_weights_for_sub
469+ Interpolation weights for each subpixel (M_sub, P)
470+ slim_index_for_sub
471+ Mapping subpixel -> slim image pixel index (M_sub,)
472+ fft_index_for_masked_pixel
473+ Mapping slim pixel -> rectangular FFT-grid pixel index (N_unmasked,)
474+ sub_fraction_slim
475+ Oversampling normalization per slim pixel (N_unmasked,)
476+ xp
477+ Backend module (np or jnp)
478+
479+ Returns
480+ -------
481+ rows : (nnz,) int32
482+ Rectangular FFT grid row index per mapping entry
483+ cols : (nnz,) int32
484+ Source pixel index per mapping entry
485+ vals : (nnz,) float64
486+ Mapping weight per entry including sub_fraction normalization
487+ """
488+
489+ # ------------------------------------------------------------
490+ # Put everything on the right backend
491+ # ------------------------------------------------------------
492+ pix_indexes_for_sub = xp .asarray (pix_indexes_for_sub )
493+ pix_weights_for_sub = xp .asarray (pix_weights_for_sub )
494+ slim_index_for_sub = xp .asarray (slim_index_for_sub )
495+ fft_index_for_masked_pixel = xp .asarray (fft_index_for_masked_pixel )
496+ sub_fraction_slim = xp .asarray (sub_fraction_slim )
497+
498+ # dtypes (important for JAX scatter / indexing performance)
499+ pix_indexes_for_sub = pix_indexes_for_sub .astype (xp .int32 )
500+ pix_weights_for_sub = pix_weights_for_sub .astype (xp .float64 )
501+ slim_index_for_sub = slim_index_for_sub .astype (xp .int32 )
502+ fft_index_for_masked_pixel = fft_index_for_masked_pixel .astype (xp .int32 )
503+ sub_fraction_slim = sub_fraction_slim .astype (xp .float64 )
504+
505+ # ------------------------------------------------------------
506+ # Dimensions
507+ # ------------------------------------------------------------
508+ M_sub , P = pix_indexes_for_sub .shape
509+
510+ # ------------------------------------------------------------
511+ # Subpixel IDs repeated P times (fixed stencil)
512+ # ------------------------------------------------------------
513+ sub_ids = xp .repeat (xp .arange (M_sub , dtype = xp .int32 ), P ) # (M_sub*P,)
514+
515+ # ------------------------------------------------------------
516+ # Flatten interpolation stencil
517+ # ------------------------------------------------------------
518+ cols = pix_indexes_for_sub .reshape (- 1 ).astype (xp .int32 ) # (nnz,)
519+ vals = pix_weights_for_sub .reshape (- 1 ).astype (xp .float64 ) # (nnz,)
520+
521+ # ------------------------------------------------------------
522+ # subpixel -> slim image pixel
523+ # ------------------------------------------------------------
524+ slim_rows = slim_index_for_sub [sub_ids ].astype (xp .int32 ) # (nnz,)
525+
526+ # ------------------------------------------------------------
527+ # slim pixel -> FFT rectangular pixel
528+ # ------------------------------------------------------------
529+ rows = fft_index_for_masked_pixel [slim_rows ].astype (xp .int32 )
530+
531+ # ------------------------------------------------------------
532+ # Oversampling normalization
533+ # ------------------------------------------------------------
534+ vals = vals * sub_fraction_slim [slim_rows ].astype (xp .float64 )
535+
536+ return rows , cols , vals
537+
538+
539+
540+
445541def mapping_matrix_from (
446542 pix_indexes_for_sub_slim_index : np .ndarray ,
447543 pix_size_for_sub_slim_index : np .ndarray ,
0 commit comments