AngularSpectrumPropagation#
- class deepinv.physics.AngularSpectrumPropagation(img_size, H, pixel_size=1.0, dtype=torch.cfloat, device='cpu', **kwargs)[source]#
Bases:
LinearPhysicsLinear angular-spectrum propagation with a user-defined transfer function.
This operator propagates a complex wave field \(u\) according to
\[P_H(u) = \mathcal{F}^{-1}\{H(f_x, f_y)\mathcal{F}\{u\}\}.\]The transfer function
Hcan be supplied either as a tensor in the unshifted ordering used bytorch.fft.fft2(), or as a callable with signatureH(fx, fy). In the latter case, the callable is evaluated once at construction on frequency grids expressed in cycles per unit ofpixel_size.This class models propagation of an already formed complex field. Object transmission functions such as \(T(\delta, \beta)=\exp(g(\delta, \beta))\) should be represented by a separate nonlinear
deepinv.physics.Physicsoperator and composed with this one.Note
The FFT implementation imposes periodic boundary conditions. Pad the field and define
Hon the padded grid when circular wrap-around is not appropriate for the experiment.- Parameters:
img_size (tuple[int, ...]) – Shape of an unbatched input. The final two entries are interpreted as
(height, width).H (torch.Tensor, Callable) – Transfer-function tensor or callable
H(fx, fy). It must act pointwise without adding an output dimension. It may be (or return) a scalar, have shape(height, width), or contain leading dimensions that broadcast toimg_size(for example,(channels, height, width)).pixel_size (float, tuple[float, float]) – Sampling pitch
dy, dx. Iffloat, thendy, dy, default 1.dtype (torch.dtype) – Complex dtype used to evaluate and store
H. Default:torch.cfloat.device (torch.device, str) – Device on which the frequency grid and transfer function are created. Default:
"cpu".
- Examples:
Define a quadratic phase transfer function directly:
>>> import torch >>> from deepinv.physics import AngularSpectrumPropagation >>> propagation = AngularSpectrumPropagation( ... img_size=(1, 32, 48), ... pixel_size=(2e-6, 3e-6), ... H=lambda fx, fy: torch.exp( ... -1j * 1e-10 * (fx.square() + fy.square()) ... ), ... ) >>> x = torch.randn(2, 1, 32, 48, dtype=torch.cfloat) >>> propagation(x).shape torch.Size([2, 1, 32, 48])
- A(x, **kwargs)[source]#
Propagate a complex field without noise or sensor nonlinearities.
- Parameters:
x (torch.Tensor) – complex input image, where the last two dimensions are
(height, width).- Returns:
torch.Tensory, the measurements, of the same shape asx.- Return type:
- A_adjoint(y, **kwargs)[source]#
Apply the Hermitian adjoint of the propagation operator.
- Parameters:
y (torch.Tensor) – complex input image, where the last two dimensions are
(height, width).- Returns:
torch.Tensorx, of the same shape asy.- Return type:
- A_dagger(y, rcond=None, **kwargs)[source]#
Apply the Moore-Penrose pseudo-inverse.
The operator is diagonal in the Fourier domain, so the pseudo-inverse is closed-form, analogous to
deepinv.physics.DecomposablePhysics.- Parameters:
y (torch.Tensor) – complex input image, where the last two dimensions are
(height, width).rcond (float) – frequencies whose magnitude
< rcond * max(abs(H))are mapped to zero. IfNone, uses real component dtype machine precision.
- Returns:
torch.Tensorx, of the same shape asy.- Return type:
- static frequency_grid(img_size, pixel_size=1.0, dtype=torch.float32, device='cpu')[source]#
Return unshifted spatial-frequency grids
(fx, fy).Frequencies are in cycles per unit of
pixel_sizeand follow the ordering expected bytorch.fft.fft2().- Parameters:
img_size (tuple[int, ...]) – Shape whose final entries are
(height, width).pixel_size (float, tuple[float, float]) – Scalar pitch or
(dy, dx).dtype (torch.dtype) – Real floating-point dtype for the grids.
device (torch.device, str) – Grid device.
- Returns:
The two grids
(fx, fy), each of shape(height, width).- Return type: