spyrit.core.meas.DynamicHadamSplit2d.adjoint_H_dyn

DynamicHadamSplit2d.adjoint_H_dyn(m: tensor, unvectorize=False)

Apply adjoint of matrix \(H_{\rm{dyn}}\).

It computes

\[x = H_{\rm{dyn}}^\top m,\]

where \(H_{\rm{dyn}} \in \mathbb{R}^{M \times L}\) is the dynamic acquisition matrix (that may contain negative values), \(m \in \mathbb{R}^M\) is a measurement vector.

Warning

This supposes the dynamic measurement matrix \(H_{\rm{dyn}}\) has been set using the build_dynamic_forward() method. An error will be raised otherwise.

Note

The acquisition matrix \(H_{\rm{dyn}}\) is given by self.H_dyn.

Args:

m (torch.tensor): Measurements \(m\) whose dimensions self.meas_dims must have shape self.meas_shape.

Returns:

A batch of signals \(x\). If unvectorize is False, \(x\) has shape \((*, L)\) where \(*\) is the same as for m. If unvectorize is True, \(x\) is reshaped such that the dimensions self.meas_dims have shape self.img_shape.

Example:
>>> import torch
>>> from spyrit.core.noise import Poisson
>>> from spyrit.core.warp import DeformationField
>>> from spyrit.core.meas import DynamicLinearSplit
>>>
>>> def_field = DeformationField(torch.rand([800, 50, 50, 2]) * 2 - 1)  # dummy deformation field with 400 frames
>>> x = torch.rand([1, 3, 50, 50])  # dummy RGB reference image of size 50x50
>>> x_motion = def_field(x)  # dummy video obtained by warping x with def_field
>>> 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()
)
>>>
>>> meas_op.build_dynamic_forward(def_field)
>>> m = meas_op.measure_H(x_motion)  # simulate noiseless dynamic measurements from matrix H
>>> H_dyn_adj_x = meas_op.adjoint_H_dyn(m)  # apply adjoint of dynamic measurement matrix (with differential strategy)
>>> print(H_dyn_adj_x.shape)
torch.Size([1, 3, 2500])