spyrit.core.meas.DynamicHadamSplit2d.forward_H
- DynamicHadamSplit2d.forward_H(x: tensor) tensor[source]
Simulates noisy measurements leveraging the Kronecker structure of the 2d Hadamard transform H.
Each measurement is acquired as, for \(k \in \{1, ..., M\}\):
\[m_k = \mathcal{N}\left( \sum_{i, j} H_{1d}[r_k, i] x_{t=k}[i, j] H_{1d}[j, c_k] \right),\]where \(H_{1d} \in \mathbb{R}^{h\times h}\) is the 1d Hadamard matrix, \(x_{t=k} \in \mathbb{R}^{h \times h}\) is \(k^{\rm{th}}\) frame of the video, \((r_k, c_k) = (\left \lfloor k / h \right\rfloor, k \bmod h)\) are the row and column indices of the 1d Hadamard matrix used to generate the 2d Hadamard pattern used at time \(t=k\).
- Args:
x(torch.tensor): Video signal \(x\) whose dimensionsself.meas_dimsmust be of shapeself.meas_shapeand dimensionself.time_dimmust be of size2 * self.M.- Returns:
torch.tensor: Measurement vector \(m\) of lengthself.M.- Example:
>>> import torch >>> from spyrit.core.noise import Poisson >>> from spyrit.core.meas import DynamicHadamSplit2d >>> >>> x = torch.rand([1, 2 * 32**2, 3, 40, 40]) # dummy RGB video with 2 * 32**2 frames of size 40x40 >>> noise_op = torch.nn.Identity() # We can't use Poisson here because measurements from H can be negative >>> meas_op = DynamicHadamSplit2d(time_dim=1, h=32, M=32**2, img_shape=(40, 40), noise_model=noise_op) # acquisition with 2*M splitted Hadamard patterns of size hxh. >>> print(meas_op) DynamicHadamSplit2d( (noise_model): Identity() ) >>> >>> m = meas_op.forward_H(x) # simulate noisy dynamic measurements from matrix H >>> print(m.shape) torch.Size([1, 3, 1024])