spyrit.core.meas.HadamSmatrix2d.fast_pinv

HadamSmatrix2d.fast_pinv(m: tensor, vectorize: bool = False) tensor[source]

Apply the pseudo-inverse of the measurement matrix.

Args:

m (torch.tensor): Measurement \(m\) of length self.M.

vectorize (bool): Whether to apply vectorize() after computation of the pseudo-inverse.

Returns:

torch.tensor: Vectorized (or image-shaped) signal \(x\) of length self.N.

Note

We use the separability of the 2D S-transform: the forward map is \(Y = S_{1d} X S_{1d}^T\), so the exact inverse is \(X = T_{1d} Y T_{1d}^T\), where \(T_{1d} = S_{1d}^{-1}\) (see T1d). Only multiplications with \(T_{1d}\) are required. If the number of measurements is smaller than the number of pixels, the measurement vector is zero-padded before inversion, exactly as done in HadamSplit2d.fast_pinv().

Unlike the Hadamard matrix used by HadamSplit2d, whose rows remain exactly orthogonal after any subsampling (making zero-pad-then-invert an exact pseudo-inverse for any self.M), the S-matrix does not have this property in general. This reconstruction is therefore exact only when self.M equals self.N (no subsampling); with subsampling, it is an approximation, consistent with the convention used throughout HadamSplit2d. This holds whether or not scramble is used.