# odak.learn.wave.band_limited_angular_spectrum¶

A definition to calculate bandlimited angular spectrum based beam propagation. For more

Matsushima, Kyoji, and Tomoyoshi Shimobaba. "Band-limited angular spectrum method for numerical simulation of free-space propagation in far and near fields." Optics express 17.22 (2009): 19662-19673.

Parameters:

Name Type Description Default
field torch.complex

Complex field (MxN).

required
k odak.wave.wavenumber

Wave number of a wave, see odak.wave.wavenumber for more.

required
distance float

Propagation distance.

required
dx float

Size of one single pixel in the field grid (in meters).

required
wavelength float

Wavelength of the electric field.

required

Returns:

Type Description
torch.complex

Final complex field (MxN).

Source code in odak/learn/wave/classical.py
def band_limited_angular_spectrum(field, k, distance, dx, wavelength):
"""
A definition to calculate bandlimited angular spectrum based beam propagation. For more
Matsushima, Kyoji, and Tomoyoshi Shimobaba. "Band-limited angular spectrum method for numerical simulation of free-space propagation in far and near fields." Optics express 17.22 (2009): 19662-19673.

Parameters
----------
field            : torch.complex
Complex field (MxN).
k                : odak.wave.wavenumber
Wave number of a wave, see odak.wave.wavenumber for more.
distance         : float
Propagation distance.
dx               : float
Size of one single pixel in the field grid (in meters).
wavelength       : float
Wavelength of the electric field.

Returns
-------
result           : torch.complex
Final complex field (MxN).
"""
distance = torch.tensor([distance]).to(field.device)
nv, nu = field.shape[-1], field.shape[-2]
y, x = (dx * float(nv), dx * float(nu))
fy = torch.linspace(-1 / (2 * dx) + 0.5 / (2 * x), 1 / (2 * dx) - 0.5 / (2 * x), nv, dtype=torch.float32).to(field.device)
fx = torch.linspace(-1 / (2 * dx) + 0.5 / (2 * x), 1 / (2 * dx) - 0.5 / (2 * x), nu, dtype=torch.float32).to(field.device)
FY, FX = torch.meshgrid(fx, fy, indexing='ij')
HH = 2 * np.pi * torch.sqrt(1 / wavelength**2 - (FX**2 + FY**2))
H_exp = HH.to(field.device)
H_exp = torch.mul(H_exp, distance)
fy_max = 1 / torch.sqrt((2 * distance * (1 / y))**2 + 1) / wavelength
fx_max = 1 / torch.sqrt((2 * distance * (1 / x))**2 + 1) / wavelength
H_filter = ((torch.abs(FX) < fx_max) & (torch.abs(FY) < fy_max)).clone().detach()
H = generate_complex_field(H_filter,H_exp)
U1 = torch.fft.fftshift(torch.fft.fft2(torch.fft.fftshift(field)))
U2 = H*U1
result = torch.fft.ifftshift(torch.fft.ifft2(torch.fft.ifftshift(U2)))
return result


## Notes¶

Unless you know what you are doing, we do not suggest you to use this function directly. Rather stick to odak.learn.wave.propagate_beam for your beam propagation code.