Source code for pyfli.sp_analysis.basis
"""
Implement Hadamard and DCT sensing bases for single-pixel reconstruction.
This module belongs to :mod:`pyfli.sp_analysis` and is part of PyFLI single-pixel camera
basis generation, acquisition simulation, and reconstruction solvers. Public API
includes classes :class:`OrthogonalBasis`, :class:`HadamardBasis`, and
:class:`DCTBasis`.
"""
from typing import Any
import numpy as np
from scipy.fftpack import dct, idct
from scipy.linalg import hadamard as _hadamard
[docs]
class OrthogonalBasis:
"""
Define the interface for orthogonal sensing bases. Subclasses implement forward and
inverse transforms for flattened spatial signals or spatial-temporal stacks.
"""
[docs]
def forward(self, x: np.ndarray) -> None:
"""
Apply the forward basis transform.
Parameters
----------
x : np.ndarray
Input array, coordinate, or signal being transformed.
Returns
-------
None
No object is returned; the function perform forward.
"""
raise NotImplementedError
[docs]
def inverse(self, y: np.ndarray) -> None:
"""
Apply the inverse basis transform.
Parameters
----------
y : np.ndarray
Observed signal, target data, or coordinate array.
Returns
-------
None
No object is returned; the function perform inverse.
"""
raise NotImplementedError
[docs]
class HadamardBasis(OrthogonalBasis):
"""
Apply a Walsh-Hadamard sensing basis by matrix multiplication. The basis requires a
power-of-two pixel count and transforms along the spatial axis.
Parameters
----------
n_pixels : int
Number of spatial pixels represented by the basis.
"""
def __init__(self, n_pixels: int) -> None:
self.n = n_pixels
self._H = _hadamard(n_pixels).astype(np.float64)
[docs]
def forward(self, x: np.ndarray) -> Any:
"""
Apply the forward basis transform.
Parameters
----------
x : np.ndarray
Input array, coordinate, or signal being transformed.
Returns
-------
Any
Object produced by forward.
"""
shape = x.shape
return (self._H @ x.reshape(self.n, -1)).reshape(shape)
[docs]
def inverse(self, y: np.ndarray) -> Any:
# H @ H = N * I, so H^{-1} = H / N
"""
Apply the inverse basis transform.
Parameters
----------
y : np.ndarray
Observed signal, target data, or coordinate array.
Returns
-------
Any
Object produced by inverse.
"""
shape = y.shape
return (self._H @ y.reshape(self.n, -1) / self.n).reshape(shape)
[docs]
class DCTBasis(OrthogonalBasis):
"""
Apply DCT-II and inverse DCT transforms as a compact orthogonal sensing basis. It is
useful for Fourier-like single-pixel simulation and reconstruction.
"""
[docs]
def forward(self, x: np.ndarray) -> Any:
"""
Apply the forward basis transform.
Parameters
----------
x : np.ndarray
Input array, coordinate, or signal being transformed.
Returns
-------
Any
Object produced by forward.
"""
return dct(x, axis=0, norm="ortho")
[docs]
def inverse(self, y: np.ndarray) -> Any:
"""
Apply the inverse basis transform.
Parameters
----------
y : np.ndarray
Observed signal, target data, or coordinate array.
Returns
-------
Any
Object produced by inverse.
"""
return idct(y, axis=0, norm="ortho")