Commit 97a5b558 by Leon Merten Lohse

### add discrete hankel transform and vacuum propagation

parent bc06658c
fresnel/hankel.py 0 → 100644
 import numpy as np import scipy.special def hankelMatrix(N, n=0): ''' returns a N x N matrix for discrete Hankel transfrom of n-th order. N: number of pixels n: order of Hankel transform The Hankel matrix is self-inverse! I.e. HH = Id For forward and backward Hankel transfrom different prefactors have to be considered! As in: Theory and operational rules for the discreteHankel transform by Natalie Baddour* and Ugo Chouinard https://doi.org/10.1364/JOSAA.32.000611 ''' jn = np.array(scipy.special.jn_zeros(n, N + 1)) k = np.expand_dims(np.arange(N), axis=0) m = np.expand_dims(np.arange(N), axis=1) jN = jn[-1] Y = scipy.special.jn(n, jn[m] * jn[k] / jN) # matrix Y *= 2 / (jN * scipy.special.jn(n + 1, jn[k]) ** 2) # prefactor return Y def hankelFreq(N, n=0, kmax=0.5): ''' Returns the Hankel space (frequency) sampling grid for the inverse discrete Hankel transfrom (of order n) of a signal with N pixels. kmax is the maximum sampling frequency in dimensionless units, i.e. minimal sampled realspace oscillation 2px -> max. sampled frequency 1/(2px) -> 0.5 dimensionless ''' jn = np.array(scipy.special.jn_zeros(n, N + 1)) return jn[:-1] * kmax / jn[N] def hankelSamples(N, n=0, kmax=0.5): ''' Returns the real space sampling grid for the forward discrete Hankel transfrom (of order n) of a signal with N pixels. kmax is the maximum sampling frequency in dimensionless units, i.e. minimal sampled realspace oscillation 2px -> max. sampled frequency 1/(2px) -> 0.5 dimensionless ''' jn = np.array(scipy.special.jn_zeros(n, N)) return jn / (kmax*2*np.pi) class DiscreteHankelTransform: def __init__(self, N, n=0, kmax=0.5): self._matrix = hankelMatrix(N, n) def __call__(self, x): return self._matrix @ x