spyrit.core.inverse.Tikhonov.forward

Tikhonov.forward(y: tensor, gamma: tensor) tensor[source]

Reconstructs the signal from measurements and noise covariance.

The Tikhonov solution is computed as

\[\hat{x} = B^\top (C + \Gamma)^{-1} y\]

with \(B = \Sigma A^\top\) and \(C = A \Sigma A^\top\). When self.approx is True, it is approximated as

\[\hat{x} = B^\top \frac{y}{\text{diag}(C + \Gamma)}\]
Args:

y (torch.tensor): A batch of measurement vectors \(y\) of shape \((*, M)\).

gamma (torch.tensor): A batch of noise covariance \(\Gamma\) of shape \((*, M, M)\).

Returns:

(torch.tensor): A batch of reconstructed images of shape \((*, N)\) or the \(meas\_op.unvectorize\) version of the image shape.

Example 1: With reshape_output = True
>>> from spyrit.core.meas import Linear
>>> M, N = 32, 64
>>> b, c, h, w = 85, 3, 8, 8
>>> meas_op = Linear(torch.rand([M,N]), meas_shape=(1,N))
>>> x = torch.randn(b,c,h,w)
>>> y = meas_op(x)
>>> sigma = torch.rand(N,N)
>>> tikho = Tikhonov(meas_op, sigma, approx=False, reshape_output=True)
>>> gamma = torch.eye(M).expand(b, c, M, M)
>>> print(tikho(y, gamma).shape)
torch.Size([85, 3, 1, 64])
Example 2: With reshape_output = False
>>> from spyrit.core.meas import Linear
>>> M, N = 32, 64
>>> b, c, h, w = 85, 3, 8, 8
>>> meas_op = Linear(torch.rand([M,N]), meas_shape=(1,N))
>>> x = torch.randn(b,c,h,w)
>>> y = meas_op(x)
>>> sigma = torch.rand(N,N)
>>> tikho = Tikhonov(meas_op, sigma, approx=False, reshape_output=False)
>>> gamma = torch.eye(M).expand(b, c, M, M)
>>> print(tikho(y, gamma).shape)
torch.Size([85, 3, 64])