spyrit.core.meas.FreeformLinear

class spyrit.core.meas.FreeformLinear(H: tensor, meas_shape: int | Size | Iterable[int] = None, meas_dims: int | Size | Iterable[int] = None, index_mask: tensor = None, bool_mask: tensor = None, *, noise_model: Module = Identity(), dtype: dtype = torch.float32, device: device = device(type='cpu'))[source]

Bases: Linear

Simulate linear measurements in a region of interest

\[m =\mathcal{N}\left(Hx\right), \quad \text{where }x = \text{mask}(\tilde{x})\]

where \(\mathcal{N} \colon\, \mathbb{R}^M \to \mathbb{R}^M\) represents a noise operator (e.g., Gaussian), \(H\in\mathbb{R}^{M\times N}\) is the acquisition matrix, \(x \in \mathbb{R}^N\) is the signal in the region of interest, \(M\) is the number of measurements, \(N\) is the number of pixels in the region of interest, \(\text{mask} \colon\, \mathbb{R}^\tilde{N} \to \mathbb{R}^N\) represents the masking operation, \(\tilde{x} \in \mathbb{R}^\tilde{N}\) is the full signal, and \(\tilde{N}\ge N\) is the dimension of the full signal \(\tilde{x}\).

Args:

H (torch.tensor): measurement matrix (linear operator) with shape \((M, N)\). Only real values are supported.

meas_shape (tuple): Shape of the underliying multi-dimensional array \(X\). Must be a tuple of integers \((N_1, N_2)\) such that \(N_1 \times N_2 \ge N\). If not, an error is raised.

meas_dims (tuple, optional): Dimensions of \(X\) the acquisition matrix applies to. Must be a tuple with the same length as meas_shape. If not, an error is raised. Defaults to the last dimensions of the multi-dimensional array \(X\) (e.g., (-2,-1) when len(meas_shape)).

index_masked (torch.tensor): Indices of \(X\) where measurement applies. This is a tensor with shape shape \((2, N)\).

noise_model (see spyrit.core.noise): Noise model \(\mathcal{N}\). Defaults to = torch.nn.Identity.

Note

Only tested for measurements in 2D using mask indices.

Example: Select one every second point on the diagonal of a batch of images
>>> images = torch.rand(17, 3, 40, 40)
>>> mask = torch.tensor([[i, i] for i in range(0,40,2)]).T
>>> H = torch.randn(13, 20)
>>> meas_op = FreeformLinear(H, meas_shape=(40,40), index_mask=mask)
>>> x_masked = meas_op(images)
>>> print(x_masked.shape)
torch.Size([17, 3, 13])

Methods

adjoint(m[, unvectorize])

Apply adjoint of matrix H.

forward(x)

Simulate measurements.

measure(x)

Simulate noiseless measurements.

set_matrix_to_inverse(matrix_name)

unvectorize(x[, fill_value])

Unflatten the last dimension of a tensor to the measurement shape at the measured dimensions based on the mask.

vectorize(x)

Appplies the saved mask to the input tensor, where the masked dimensions are collapsed into one.