spyrit.core.meas.DynamicLinearSplit.forward_H

DynamicLinearSplit.forward_H(x: tensor) tensor[source]

Simulates noisy dynamic measurements from matrix H.

It acquires

\[m = \mathcal{N}\left(\text{diag}(H x_{t=1, ..., M})\right),\]

where \(H \in \mathbb{R}^{M\times N}\) is the measurement matrix (that may contain negative values), \(x_{t=1, ..., M} \in \mathbb{R}^{N \times M}\) is the temporal signal obtained from averaging the positive and negative frames of \(x_{t=1, ..., 2M}\), \(M\) is the number of DMD patterns, \(N\) is the dimension of the signal, \(\text{diag}\colon\, \mathbb{R}^{M \times M} \to \mathbb{R}^{M}\) extracts the diagonal of its input, and \(\mathcal{N} \colon\, \mathbb{R}^{M} \to \mathbb{R}^{M}\) represents a noise operator (e.g., Gaussian).

Note

The acquisition matrix \(H\) is given by self.H.

Note

Here the number of frames is 2M and the number of measurements is M.

Args:

x (torch.tensor): Video signal \(x\) whose dimensions self.meas_dims must be of shape self.meas_shape and dimension self.time_dim must be of size 2 * self.M.

Returns:

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

Example:
>>> import torch
>>> from spyrit.core.meas import DynamicLinearSplit
>>> from spyrit.core.noise import Poisson
>>>
>>> x = torch.rand([1, 800, 3, 50, 50])  # dummy RGB video with 400 frames of size 50x50
>>> H = torch.rand([400, 40*40])  # dummy static measurement matrix
>>> alpha = 5  # noise level
>>> noise_op = Poisson(alpha=alpha, g=1/alpha)
>>> meas_op = DynamicLinearSplit(H, time_dim=1, meas_shape=(40, 40), img_shape=(50, 50), noise_model=noise_op)
>>> print(meas_op)
DynamicLinearSplit(
  (noise_model): Poisson()
)
>>>
>>> m = meas_op.forward_H(x)  # simulate noisy dynamic measurements
>>> print(m.shape)
torch.Size([1, 3, 400])