# Util functions

## Convolution Functions

`DeconvOptim.conv`

— Function`conv(u, v[, dims])`

Convolve `u`

with `v`

over `dims`

dimensions with an FFT based method. Note, that this method introduces wrap-around artifacts without proper padding/windowing.

**Arguments**

`u`

is an array in real space.`v`

is the array to be convolved in real space as well.- Per default
`ntuple(+, min(N, M)))`

means that we perform the convolution over all dimensions of that array which has less dimensions. If`dims`

is an array with integers, we perform convolution only over these dimensions. Eg.`dims=[1,3]`

would perform the convolution over the first and third dimension. Second dimension is not convolved.

If `u`

and `v`

are both a real valued array we use `rfft`

and hence the output is real as well. If either `u`

or `v`

is complex we use `fft`

and output is hence complex.

**Examples**

1D with FFT over all dimensions. We choose `v`

to be a delta peak. Therefore convolution should act as identity.

```
julia> u = [1 2 3 4 5]
1×5 Array{Int64,2}:
1 2 3 4 5
julia> v = [0 0 1 0 0]
1×5 Array{Int64,2}:
0 0 1 0 0
julia> conv(u, v)
1×5 Matrix{Float64}:
4.0 5.0 1.0 2.0 3.0
```

2D with FFT with different `dims`

arguments.

```
julia> u = 1im .* [1 2 3; 4 5 6]
2×3 Matrix{Complex{Int64}}:
0+1im 0+2im 0+3im
0+4im 0+5im 0+6im
julia> v = [1im 0 0; 1im 0 0]
2×3 Matrix{Complex{Int64}}:
0+1im 0+0im 0+0im
0+1im 0+0im 0+0im
julia> conv(u, v)
2×3 Matrix{ComplexF64}:
-5.0+0.0im -7.0+0.0im -9.0+0.0im
-5.0+0.0im -7.0+0.0im -9.0+0.0im
```

`DeconvOptim.conv_psf`

— Function`conv_psf(u, psf[, dims])`

`conv_psf`

is a shorthand for `conv(u,ifftshift(psf))`

. For examples see `conv`

.

`DeconvOptim.plan_conv`

— Function`plan_conv(u, v [, dims])`

Pre-plan an optimized convolution for arrays shaped like `u`

and `v`

(based on pre-plan FFT) along the given dimensions `dims`

. `dims = 1:ndims(u)`

per default. The 0 frequency of `u`

must be located at the first entry. We return two arguments: The first one is `v_ft`

(obtained by `fft(v)`

or `rfft(v)`

). The second return is the convolution function `pconv`

. `pconv`

itself has two arguments. `pconv(u, v_ft=v_ft)`

where `u`

is the object and `v_ft`

the v_ft. This function achieves faster convolution than `conv(u, u)`

. Depending whether `u`

is real or complex we do `fft`

s or `rfft`

s

**Warning**

The resulting output of the `pconv`

function is a reference to an internal, allocated array. If you use the `pconv`

function for different tasks, a new call to `pconv`

will change the previous result (since the previous result was only a reference, not a new array).

**Examples**

```
julia> u = [1 2 3 4 5]
1×5 Matrix{Int64}:
1 2 3 4 5
julia> v = [1 0 0 0 0]
1×5 Matrix{Int64}:
1 0 0 0 0
julia> v_ft, pconv = plan_conv(u, v);
julia> pconv(u, v_ft)
1×5 Matrix{Float64}:
1.0 2.0 3.0 4.0 5.0
julia> pconv(u)
1×5 Matrix{Float64}:
1.0 2.0 3.0 4.0 5.0
```

`DeconvOptim.plan_conv_psf`

— Function`plan_conv_psf(u, psf [, dims]) where {T, N}`

`plan_conv_psf`

is a shorthand for `plan_conv(u, ifftshift(psf))`

. For examples see `plan_conv`

.

`DeconvOptim.next_fast_fft_size`

— Function`next_fast_fft_size(x)`

`x`

is a tuple of sizes. It rounds to the next fast FFT size. FFT is especially fast on small prime factors.

## Point Spread Function

`DeconvOptim.generate_psf`

— Function`generate_psf(psf_size, radius)`

Generation of an approximate 2D PSF. `psf_size`

is the output size of the PSF. The PSF will be centered around the point [1, 1], `radius`

indicates the pupil diameter in pixel from which the PSF is generated.

Returned 2D PSF is `fftshift`

ed in contrast to models, you can find in literature.

**Examples**

```
julia> generate_psf([5, 5], 2)
5×5 Array{Float64,2}:
0.36 0.104721 0.0152786 0.0152786 0.104721
0.104721 0.0304627 0.00444444 0.00444444 0.0304627
0.0152786 0.00444444 0.000648436 0.000648436 0.00444444
0.0152786 0.00444444 0.000648436 0.000648436 0.00444444
0.104721 0.0304627 0.00444444 0.00444444 0.0304627
```

## Interpolation and downsampling

`DeconvOptim.generate_downsample`

— Function`generate_downsample(num_dim, downsample_dims, factor)`

Generate a function (based on Tullio.jl) which can be used to downsample arrays. `num_dim`

(Integer) are the dimensions of the array. `downsample_dims`

is a list of which dimensions should be downsampled. `factor`

is a downsampling factor. It needs to be an integer number.

**Examples**

```
julia> ds = generate_downsample(2, [1, 2], 2)
[...]
julia> ds([1 2; 3 4; 5 6; 7 8])
2×1 Array{Float64,2}:
2.5
6.5
julia> ds = generate_downsample(2, [1], 2)
[...]
julia> ds([1 2; 3 5; 5 6; 7 8])
2×2 Array{Float64,2}:
2.0 3.5
6.0 7.0
```

`DeconvOptim.my_interpolate`

— Function`my_interpolate(arr, size_n, [interp_type])`

Interpolates `arr`

to the sizes provided in `size_n`

. Therefore it holds `ndims(arr) == length(size_n)`

. `interp_type`

specifies the interpolation type. See Interpolations.jl for all options

## Center Methods

`DeconvOptim.center_extract`

— Function`center_extract(arr, new_size_array)`

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.

**Examples**

```
julia> DeconvOptim.center_extract([1 2; 3 4], [1])
1×2 Array{Int64,2}:
3 4
julia> DeconvOptim.center_extract([1 2; 3 4], [1, 1])
1×1 Array{Int64,2}:
4
julia> DeconvOptim.center_extract([1 2 3; 3 4 5; 6 7 8], [2 2])
2×2 Array{Int64,2}:
1 2
3 4
```

`DeconvOptim.center_set!`

— Function`center_set!(arr_large, arr_small)`

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.

**Examples**

```
julia> DeconvOptim.center_set!([1, 1, 1, 1, 1, 1], [5, 5, 5])
6-element Array{Int64,1}:
1
1
5
5
5
1
```

`DeconvOptim.center_pos`

— Function`center_pos(x)`

Calculate the position of the center frequency. Size of the array is `x`

**Examples**

```
julia> DeconvOptim.center_pos(3)
2
julia> DeconvOptim.center_pos(4)
3
```