Module regpy.operators.convolution
Classes
class PaddingOperator (grid, pad_amount=None)
-
Operator that implements zero-padding for numpy arrays.
Parameters
grid
:UniformGridFcts
- The domain on which the operator is defined.
pad_amount
:n-tuple
ofpairs
ofnon-negative integer determining the amount
ofpadding
- where n is the dimension of grid. E.g., for n=2,
pad_amont = ((pad_top,pad_bottom),(pad_left,pad_right))
Notes
A wrapper of the np.pad function
Expand source code
class PaddingOperator(Operator): r"""Operator that implements zero-padding for numpy arrays. Parameters ---------- grid : regpy.vecsps.UniformGridFcts The domain on which the operator is defined. pad_amount: n-tuple of pairs of non-negative integer determining the amount of padding where n is the dimension of grid. E.g., for n=2, pad_amont = ((pad_top,pad_bottom),(pad_left,pad_right)) Notes ------- A wrapper of the np.pad function """ def __init__(self,grid, pad_amount = None): assert isinstance(grid, UniformGridFcts) s = grid.shape self.ndim = grid.ndim if pad_amount is None: pad_amount = ((0,0),)*self.ndim self.pad_amount = pad_amount padded_grid = UniformGridFcts( *[np.arange(N+pad[0]+pad[1])*spc + ax[0] - pad[0]*spc for (N,pad,spc,ax) in zip(grid.shape,pad_amount,grid.spacing,grid.axes)], dtype = grid. dtype ) super().__init__(domain=grid,codomain=padded_grid,linear =True) def _eval(self,x): return np.pad(x,self.pad_amount,'constant') def _adjoint(self,y): ind = tuple(slice(pad[0],None if pad[1]==0 else -pad[1]) for pad in self.pad_amount) return y[ind]
Ancestors
Inherited members
class ConvolutionOperator (grid, fourier_multiplier, pad_amount=None, first_conv_axis=0)
-
Periodic convolution operator on UniformGridFcts
If the UniformGridFcts is a real vector space, the convolution kernel must be real-valued or equivalently its Fourier transform, the Fourier multiplier must be symmetric w.r.t. the origin.
Parameters
grid
:UniformGridFcts
ofarbitrary dimension d
- The space on which the operator is defined. If it real, real-valued fft will be used, otherwise complex fft
fourier_multiplier
-
- Either a d-dimensional numpy array, the Fourier transform of the convolution kernel (If grid is real, the size of the last dimension is about half of that of grid)
- of a function taking d real values and returning a real or complex number In this case, the function is evaluated on a grid that is reciprocal to the input grid
pad_amount
:d-tuple
ofpairs
ofintegers
- To model non-periodic convolutions, zero padding is often needed to avoid aliasing artifacts by periodization. Each pair of integers specifies the number of pixels to be added in each dimension.
first_conv_axis
:integer
, default:0
- If first_conv_axis>0, then convolution is only performed along the last (grid.ndim-first_conv_axis) axes.
Expand source code
class ConvolutionOperator(Composition): r"""Periodic convolution operator on UniformGridFcts If the UniformGridFcts is a real vector space, the convolution kernel must be real-valued or equivalently its Fourier transform, the Fourier multiplier must be symmetric w.r.t. the origin. Parameters ---------- grid : regpy.vecsps.UniformGridFcts of arbitrary dimension d The space on which the operator is defined. If it real, real-valued fft will be used, otherwise complex fft fourier_multiplier: - Either a d-dimensional numpy array, the Fourier transform of the convolution kernel (If grid is real, the size of the last dimension is about half of that of grid) - of a function taking d real values and returning a real or complex number In this case, the function is evaluated on a grid that is reciprocal to the input grid pad_amount: d-tuple of pairs of integers To model non-periodic convolutions, zero padding is often needed to avoid aliasing artifacts by periodization. Each pair of integers specifies the number of pixels to be added in each dimension. first_conv_axis: integer, default:0 If first_conv_axis>0, then convolution is only performed along the last (grid.ndim-first_conv_axis) axes. """ def __init__(self, grid, fourier_multiplier, pad_amount=None,first_conv_axis=0): ndim = grid.ndim if pad_amount is None or pad_amount == ((0,0),)*ndim: ft = FourierTransform(grid,axes=tuple(range(first_conv_axis,ndim))) self._frqs = ft.codomain.coords if callable(fourier_multiplier): self._otf = fourier_multiplier(*self._frqs) else: self._otf = fourier_multiplier multiplier = PtwMultiplication(ft.codomain, np.broadcast_to(self._otf,ft.codomain.shape)) super().__init__(ft.adjoint, multiplier, ft) else: pad_op = PaddingOperator(grid,pad_amount) ft = FourierTransform(pad_op.codomain,axes=tuple(range(first_conv_axis,ndim))) self._frqs = ft.codomain.coords if callable(fourier_multiplier): self._otf = fourier_multiplier(*self._frqs) else: self._otf = fourier_multiplier multiplier = PtwMultiplication(ft.codomain, np.broadcast_to(self._otf,ft.codomain.shape)) super().__init__(pad_op.adjoint, ft.adjoint, multiplier, ft, pad_op) @property def freqs(self): """coordinates in Fourier space""" return self._freqs @property def fourier_multiplier(self): """Fourier transform of the convolution kernel""" return self._otf
Ancestors
Subclasses
Instance variables
prop freqs
-
coordinates in Fourier space
Expand source code
@property def freqs(self): """coordinates in Fourier space""" return self._freqs
prop fourier_multiplier
-
Fourier transform of the convolution kernel
Expand source code
@property def fourier_multiplier(self): """Fourier transform of the convolution kernel""" return self._otf
Inherited members
class GaussianBlur (grid, kernel_width, shift=None, pad_amount=None, first_conv_axis=0)
-
Convolution with the shifted Gaussian kernel exp(-((x-shift)/kernel_width)^2). For shift=0 it also represents the forward operator for the backward heat equation if kernel_width= 2\sqrt{t}.
Expand source code
class GaussianBlur(ConvolutionOperator): r"""Convolution with the shifted Gaussian kernel exp(-((x-shift)/kernel_width)^2). For shift=0 it also represents the forward operator for the backward heat equation if kernel_width= 2\sqrt{t}. """ def __init__(self,grid,kernel_width,shift=None,pad_amount= None,first_conv_axis=0): if shift==None: super().__init__(grid, lambda *x : np.exp(-(np.pi*kernel_width)**2 * sum(y**2 for y in x)), pad_amount=pad_amount, first_conv_axis=first_conv_axis ) else: super().__init__(grid, lambda *x : np.exp(sum(-(np.pi*kernel_width)**2*y**2 + 2*np.pi*1j*sh*y for y,sh in zip(x,shift))), pad_amount=pad_amount, first_conv_axis=first_conv_axis )
Ancestors
Inherited members
class ExponentialConvolution (grid, a, pad_amount=None, first_conv_axis=0)
-
Convolution with an exponential function exp(-|x|_1/a).
Expand source code
class ExponentialConvolution(ConvolutionOperator): r"""Convolution with an exponential function exp(-|x|_1/a). """ def __init__(self,grid,a,pad_amount= None,first_conv_axis=0): super().__init__(grid, lambda *x : np.prod([1/(1 + (2*np.pi*a*y)**2) for y in x],axis=0), pad_amount=pad_amount, first_conv_axis=first_conv_axis )
Ancestors
Inherited members
class FresnelPropagator (grid, fresnel_number, pad_amount=None, first_conv_axis=0)
-
Operator that implements Fresnel-propagation of arrays of arbitrary dimension. In 2D this models near-field diffraction in the regime of the free-space paraxial Helmholtz equation.
Parameters
domain
:VectorSpace
- The domain on which the operator is defined.
fresnel_number
:float
- Fresnel number of the imaging setup, defined with respect to the lengthscale that corresponds to length 1 in domain.coords. Governs the strength of the diffractive effects modeled by the Fresnel-propagator
pad_amount = ((pad_top,pad_bottom),(pad_left,pad_right)): amount of padding to avoid aliasing artifacts
Notes
The Fresnel-propagator D_F is a unitary Fourier-multiplier defined by
D_F(f) = FT^{-1}(m_F \cdot FT(f))
where FT(f)(\nu) = \int_{\mathbb{R}^2} \exp(-i\xi \cdot x) f(x) Dx denotes the Fourier transform and the factor m_F is defined by m_F(\xi) := \exp(-i \pi |\nu|^2 / F) with the Fresnel-number F.
It should be noted that if the grid is not dimensionless, the frequency vector (here defined in units of 1/\text{length} instead of 2\pi/\text{length} is not dimensionless either. In this case, the Fresnel number is F = 1 / (\lambda d)
with wavelength lambda and propagation distance d.Expand source code
class FresnelPropagator(ConvolutionOperator): r"""Operator that implements Fresnel-propagation of arrays of arbitrary dimension. In 2D this models near-field diffraction in the regime of the free-space paraxial Helmholtz equation. Parameters ---------- domain : regpy.vecsps.VectorSpace The domain on which the operator is defined. fresnel_number : float Fresnel number of the imaging setup, defined with respect to the lengthscale that corresponds to length 1 in domain.coords. Governs the strength of the diffractive effects modeled by the Fresnel-propagator pad_amount = ((pad_top,pad_bottom),(pad_left,pad_right)): amount of padding to avoid aliasing artifacts Notes ----- The Fresnel-propagator \(D_F\) is a unitary Fourier-multiplier defined by \[ D_F(f) = FT^{-1}(m_F \cdot FT(f)) \] where \(FT(f)(\nu) = \int_{\mathbb{R}^2} \exp(-i\xi \cdot x) f(x) Dx\) denotes the Fourier transform and the factor \(m_F\) is defined by \(m_F(\xi) := \exp(-i \pi |\nu|^2 / F)\) with the Fresnel-number \(F\). It should be noted that if the grid is not dimensionless, the frequency vector (here defined in units of \(1/\text{length}\) instead of \(2\pi/\text{length}\) is not dimensionless either. In this case, the Fresnel number is \(F = 1 / (\lambda d)\) with wavelength \(lambda\) and propagation distance \(d\). """ def __init__(self,grid, fresnel_number, pad_amount=None,first_conv_axis=0): assert grid.is_complex super().__init__(grid, lambda *x : np.exp((-1j * np.pi / fresnel_number) * sum(y**2 for y in x)), pad_amount=pad_amount, first_conv_axis=first_conv_axis )
Ancestors
Inherited members