Efficient Propagations

They create efficient functions which avoid recalculating some parts.

WaveOpticsPropagation.AngularSpectrumFunction
AngularSpectrum(field, z, λ, L; kwargs...)

Returns a function for efficient reuse of pre-calculated kernels. This function returns the electrical field with physical length L and wavelength λ propagated with the angular spectrum method of plane waves (AS) by the propagation distance z.

This method is efficient but to avoid recalculating some arrays (such as the phase kernel), see AngularSpectrum.

Arguments

  • field: Input field
  • z: propagation distance. Can be a single number or a vector of zs (Or CuVector). In this case the returning array has one dimension more.
  • λ: wavelength of field
  • L: field size (can be a scalar or a tuple) indicating field size

Keyword Arguments

  • padding=true: applies padding to avoid convolution wraparound
  • bandlimit=true: applies the bandlimit to avoid circular wraparound due to undersampling of the complex propagation kernel [1]
  • bandlimit_border=(0.8, 1): applies a smooth bandlimit cut-off instead of hard-edge.

See angular_spectrum for the full documentation.

Example

julia> field = zeros(ComplexF32, (4,4)); field[3,3] = 1
1

julia> as = AngularSpectrum(field, 100e-9, 632e-9, 10e-6);

julia> as(field);
source
WaveOpticsPropagation.FraunhoferFunction
Fraunhofer(U, z, λ, L; skip_final_phase=true)

This returns a function for efficient reuse of pre-calculated kernels. This function then returns the electrical field with physical length L and wavelength λ propagated with the Fraunhofer propagation (a single FFT) by the propagation distance z. This is based on a far field approximation.

Arguments

  • U: Input field
  • z: propagation distance
  • λ: wavelength of field
  • L: field size indicating field size

Keyword Arguments

  • skip_final_phase=true skip the final phase which is multiplied to the propagated field at the end

See fraunhofer for the full documentation.

Example

julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;

julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;

julia> f = Fraunhofer(field, 4f-3, 632f-9, 100f-6);

julia> res = f(field);

julia> f.params.Lp[1] / 100f-6
64.71681f0

julia> 4f-3 * 632f-9 * 256 / (100f-6)^2
64.71681f0
source
WaveOpticsPropagation.ScalableAngularSpectrumFunction
ScalableAngularSpectrum(field, z, λ, L; kwargs...)

Returns the electrical field with physical length L and wavelength λ propagated with the scalable angular spectrum method of plane waves (SAS) by the propagation distance z.

Arguments

  • field: Input field
  • z: propagation distance
  • λ: wavelength of field
  • L: field size (can be a scalar or a tuple) indicating field size

Keyword Arguments

  • skip_final_phase=true: avoid multiplying with final phase. This phase is also undersampled.

Example

julia> field = zeros(ComplexF32, (256,256)); field[130,130] = 1;

julia> f = ScalableAngularSpectrum(field, 10f-3, 633f-9, 500f-6);

julia> f.params.Lp
0.00162048f0

julia> f.params.Lp / 500f-6 # calculate magnification
3.24096f0

julia> 10f-3 * 633f-9 * 256 / 500f-6^2 / 2 # equation from paper
3.2409596f0

References

source
WaveOpticsPropagation.ShiftedAngularSpectrumType
ShiftedAngularSpectrum(field, z, λ, L, α; kwargs...)

Returns a method to propagate the electrical field with physical length L and wavelength λ with the shifted angular spectrum method of plane waves (AS) by the propagation distance z. α should be a tuple containing the offset angles with respect to the optical axis.

Arguments

  • field: Input field
  • z: propagation distance. Can be a single number or a vector of zs (Or CuVector). In this case the returning array has one dimension more.
  • λ: wavelength of field
  • L: field size (can be a scalar or a tuple) indicating field size
  • α is the tuple of shift angles with respect to the optical axis.

Keyword Arguments

  • pad_factor=2: padding of 2. Larger numbers are not recommended since they don't provide better results.
  • bandlimit=true: applies the bandlimit to avoid circular wraparound due to undersampling of the complex propagation kernel [1]
  • extract_ramp=true: divides the field by phase ramp exp.(1im * 2π / λ * (sin(α[2]) .* x .+ sin(α[1]) .* y)) and multiplies after propagation the ramp (with new real space coordinates) back to the field

Examples

julia> field = zeros(ComplexF32, (4,4)); field[3,3] = 1
1

julia> shifted_AS = ShiftedAngularSpectrum(field, 100e-6, 633e-9, 100e-6, (deg2rad(10), 0));

julia> shifted_AS(field);

References

  • Matsushima, Kyoji. "Shifted angular spectrum method for off-axis numerical propagation." Optics Express 18.17 (2010): 18453-18463.
source
(shifted_as::ShiftedAngularSpectrum)(field)

Uses the struct to efficiently store some pre-calculated objects. Propagate the field.

source
Missing docstring.

Missing docstring for Params. Check Documenter's build log for details.

Propagation

Those were merely for testing purposes.

Missing docstring.

Missing docstring for fraunhofer. Check Documenter's build log for details.

Missing docstring.

Missing docstring for angular_spectrum. Check Documenter's build log for details.

Utilities

WaveOpticsPropagation.padFunction
pad(arr::AbstractArray{T, N}, new_size; value=zero(T))

Pads arr with values around such that the resulting array size is new_size.

See also crop_center, set_center!.

julia> pad(ones((2,2)), 2)
4×4 Matrix{Float64}:
 0.0  0.0  0.0  0.0
 0.0  1.0  1.0  0.0
 0.0  1.0  1.0  0.0
 0.0  0.0  0.0  0.0
source
pad(arr::AbstractArray{T, N}, M; value=zero(T))

Pads arr with values around such that the resulting array size is round(Int, M .* size(arr)). If M isa Integer, no rounding is needed.

Automatic Differentation

If M isa AbstractFloat, automatic differentation might fail because of size failures

See also crop_center, set_center!.

julia> pad(ones((2,2)), 2)
4×4 Matrix{Float64}:
 0.0  0.0  0.0  0.0
 0.0  1.0  1.0  0.0
 0.0  1.0  1.0  0.0
 0.0  0.0  0.0  0.0
source
WaveOpticsPropagation.crop_centerFunction
crop_center(arr, new_size)

Extracts a center of an array. new_size_array must be list of sizes indicating the output size of each dimension. Centered means that a center frequency stays at the center position. Works for even and uneven. If length(new_size_array) < length(ndims(arr)) the remaining dimensions are untouched and copied.

See also pad, set_center!.

Examples

julia> crop_center([1 2; 3 4], (1,))
1×2 Matrix{Int64}:
 3  4

julia> crop_center([1 2; 3 4], (1,1))
1×1 Matrix{Int64}:
 4

julia> crop_center([1 2; 3 4], (2,2))
2×2 Matrix{Int64}:
 1  2
 3  4
source
WaveOpticsPropagation.set_center!Function
set_center!(arr_large, arr_small; broadcast=false)

Puts the arr_small central into arr_large.

The convention, where the center is, is the same as the definition as for FFT based centered.

Function works both for even and uneven arrays. See also crop_center, pad, set_center!.

Keyword

  • If broadcast==false then a lower dimensional arr_small will not be broadcasted

along the higher dimensions.

  • If broadcast==true it will be broadcasted along higher dims.

See also crop_center, pad.

Examples

julia> set_center!([1, 1, 1, 1, 1, 1], [5, 5, 5])
6-element Vector{Int64}:
 1
 1
 5
 5
 5
 1

julia> set_center!([1, 1, 1, 1, 1, 1], [5, 5, 5, 5])
6-element Vector{Int64}:
 1
 5
 5
 5
 5
 1

julia> set_center!(ones((3,3)), [5])
3×3 Matrix{Float64}:
 1.0  1.0  1.0
 1.0  5.0  1.0
 1.0  1.0  1.0

julia> set_center!(ones((3,3)), [5], broadcast=true)
3×3 Matrix{Float64}:
 1.0  1.0  1.0
 5.0  5.0  5.0
 1.0  1.0  1.0
source