Skip to content

Commit 6b90b4f

Browse files
moved back to using "similar", bug fixes
1 parent a8e576c commit 6b90b4f

File tree

4 files changed

+43
-30
lines changed

4 files changed

+43
-30
lines changed

src/fourier_filtering.jl

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,11 @@ function fourier_filter_by_1D_FT!(arr::TA, fct=window_gaussian; dims=(1:ndims(ar
120120
# only calculate the necessary windows
121121
for d in dims
122122
# these will possibly be transformed later
123-
wins[d] = TR(ifftshift(fct(real(eltype(arr)), select_sizes(arr, d); kwargs...)))
123+
win = similar(arr, real(eltype(arr)), select_sizes(arr, d))
124+
win .= fct(real(eltype(arr)), select_sizes(arr, d); kwargs...)
125+
wins[d] = ifftshift(win)
124126
end
125-
return fourier_filter_by_1D_FT!(arr::TA, wins; transform_win=transform_win, dims=dims)
127+
return fourier_filter_by_1D_FT!(arr, wins; transform_win=transform_win, dims=dims)
126128
end
127129

128130
function fourier_filter_by_1D_RFT!(arr::TA, wins::AbstractVector; dims=(1:ndims(arr)), transform_win=false, kwargs...) where {T<:Real, N, TA<:AbstractArray{T, N}}
@@ -156,14 +158,22 @@ function fourier_filter_by_1D_RFT!(arr::TA, fct=window_gaussian; dims=(1:ndims(a
156158
if isempty(dims)
157159
return arr
158160
end
159-
TR = real_arr_type(TA)
161+
# TR = real_arr_type(TA)
160162
d = dims[1]
161163
p = plan_rfft(arr, d)
162164
arr_ft = p * arr
163-
win = TR(fct(real(eltype(arr)), select_sizes(arr_ft,d), offset=CtrRFFT, scale=2 ./size(arr,d); kwargs...))
164-
if transform_win
165-
pw = plan_rfft(win, d)
166-
win = pw*win
165+
win = let
166+
if transform_win
167+
win = similar(arr, real(eltype(arr)), select_sizes(arr,d))
168+
win .= fct(real(eltype(arr)), select_sizes(arr,d); kwargs...)
169+
win = ifftshift(win) # for CuArray compatibility this has to be done sequentially. InPlace is not supported.
170+
pw = plan_rfft(win, d)
171+
pw*win
172+
else
173+
win = similar(arr, real(eltype(arr_ft)), select_sizes(arr_ft,d))
174+
# win = TR(fct(real(eltype(arr)), select_sizes(arr_ft,d), offset=CtrRFFT, scale=2 ./size(arr,d); kwargs...))
175+
win .= fct(real(eltype(arr)), select_sizes(arr_ft,d), offset=CtrRFFT, scale=2 ./size(arr,d); kwargs...)
176+
end
167177
end
168178
arr_ft .*= win
169179
fourier_filter_by_1D_FT!(arr_ft, fct; dims=dims[2:end], transform_win=transform_win, kwargs...)
@@ -174,34 +184,36 @@ function fourier_filter_by_1D_RFT!(arr::TA, fct=window_gaussian; dims=(1:ndims(a
174184
end
175185

176186
"""
177-
filter_gaussian(arr, sigma=eltype(arr)(1); border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
187+
filter_gaussian(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
178188
179189
performs Gaussian filtering by multiplying a Gaussian function in Fourier space.
180-
Note that this is not identical to the Fourier-transform of a real-space Gaussian, especially for small kernel sizes and small arrays.
190+
Note that the argument `real_space_kernel` defines whether the Gaussian is computed in real or Fourier-space. Especially for small array sizes and small kernelsizes, the real-space version is preferred.
181191
See also `filter_gaussian!()` and `fourier_filter()`.
182192
183193
#Arguments
184194
+`arr`: the array to filter
185195
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
196+
+ `real_space_kernel`: if `true`, the separable Gaussians are computed in real space and then Fourier-transformed. The overhead is relatively small, but the result does not create fringes.
186197
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`. This can be useful to create Fourier-shifted (Gabor-) filtering.
187198
"""
188-
function filter_gaussian(arr, sigma=eltype(arr)(1); real_space_kernel=false, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
199+
function filter_gaussian(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
189200
filter_gaussian!(copy(arr), sigma; real_space_kernel=real_space_kernel, border_in=border_in, border_out=border_out, kwargs...)
190201
end
191202

192203
"""
193-
filter_gaussian!(arr, sigma=eltype(arr)(1); border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
204+
filter_gaussian!(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
194205
195206
performs in-place Gaussian filtering by multiplying a Gaussian function in Fourier space.
196-
Note that this is not identical to the Fourier-transform of a real-space Gaussian, especially for small kernel sizes and small arrays.
207+
Note that the argument `real_space_kernel` defines whether the Gaussian is computed in real or Fourier-space. Especially for small array sizes and small kernelsizes, the real-space version is preferred.
197208
See also `filter_gaussian()` adn `fourier_filter!()`.
198209
199210
#Arguments
200211
+`arr`: the array to filter
201212
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
213+
+ `real_space_kernel`: if `true`, the separable Gaussians are computed in real space and then Fourier-transformed. The overhead is relatively small, but the result does not create fringes.
202214
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`. This can be useful to create Fourier-shifted (Gabor-) filtering.
203215
"""
204-
function filter_gaussian!(arr, sigma=eltype(arr)(1); real_space_kernel=false, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
216+
function filter_gaussian!(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
205217
if real_space_kernel
206218
mysum = sum(arr)
207219
fourier_filter!(arr, gaussian; transform_win=true, sigma=sigma, kwargs...)

src/fourier_shear.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ function shear!(arr::TA, Δ, shear_dir_dim=1, shear_dim=2; fix_nyquist=false, as
4545
fft!(arr, shear_dir_dim)
4646

4747
# stores the maximum amount of shift
48-
TR = real_arr_type(TA)
49-
# shift = similar(arr, real(eltype(arr)), select_sizes(arr, shear_dir_dim))
50-
# shift = TR(reshape(fftfreq(size(arr, shear_dir_dim)), NDTools.select_sizes(arr, shear_dir_dim)))
51-
shift = TR(reorient(fftfreq(size(arr, shear_dir_dim)),shear_dir_dim, Val(N)))
48+
# TR = real_arr_type(TA)
49+
shift = similar(arr, real(eltype(arr)), select_sizes(arr, shear_dir_dim))
50+
shift .= reshape(fftfreq(size(arr, shear_dir_dim)), NDTools.select_sizes(arr, shear_dir_dim))
51+
# shift = TR(reorient(fftfreq(size(arr, shear_dir_dim)), shear_dir_dim, Val(N)))
5252

5353
apply_shift_strength!(arr, arr, shift, shear_dir_dim, shear_dim, Δ, fix_nyquist)
5454

@@ -65,10 +65,10 @@ function shear!(arr::TA, Δ, shear_dir_dim=1, shear_dim=2; fix_nyquist=false, as
6565
arr_ft = p * arr
6666

6767
# stores the maximum amount of shift
68-
TR = real_arr_type(TA)
69-
# shift = similar(arr, real(eltype(arr_ft)), select_sizes(arr_ft, shear_dir_dim))
70-
# shift = TR(reshape(rfftfreq(size(arr, shear_dir_dim)), NDTools.select_sizes(arr_ft, shear_dir_dim)))
71-
shift = TR(reorient(rfftfreq(size(arr, shear_dir_dim)),shear_dir_dim, Val(N)))
68+
# TR = real_arr_type(TA)
69+
shift = similar(arr, real(eltype(arr_ft)), select_sizes(arr_ft, shear_dir_dim))
70+
shift .= reshape(rfftfreq(size(arr, shear_dir_dim)), NDTools.select_sizes(arr_ft, shear_dir_dim))
71+
# shift = TR(reorient(rfftfreq(size(arr, shear_dir_dim)),shear_dir_dim, Val(N)))
7272

7373
apply_shift_strength!(arr_ft, arr, shift, shear_dir_dim, shear_dim, Δ, fix_nyquist)
7474
# go back to real space

src/fourier_shifting.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ function shift_by_1D_FT!(arr::TA, shifts; soft_fraction=0, take_real=false, fix_
8787
continue
8888
end
8989
# better use reorient from NDTools here?
90-
TR = real_arr_type(TA)
91-
# freqs = similar(arr, real(eltype(arr)), select_sizes(arr, d))
92-
freqs = TR(reorient(fftfreq(size(arr, d)),d, Val(N)))
93-
# freqs = TR(reshape(fftfreq(size(arr, d)), ntuple(i -> 1, Val(d-1))..., size(arr,d)))
90+
# TR = real_arr_type(TA)
91+
freqs = similar(arr, real(eltype(arr)), select_sizes(arr, d))
92+
# freqs = TR(reorient(fftfreq(size(arr, d)),d, Val(N)))
93+
freqs .= reorient(fftfreq(size(arr, d)),d, Val(N))
9494
# @show size(freqs)
9595
# allocates a 1D slice of exp values
9696
if iszero(soft_fraction)
@@ -144,9 +144,10 @@ function shift_by_1D_RFT!(arr::TA, shifts; soft_fraction=0, fix_nyquist_frequenc
144144
# @show size(arr, d) ÷ 2 + 1
145145
# freqs = TR(reshape(fftfreq(size(arr, d))[1:s], ntuple(i -> 1, d-1)..., s1))
146146

147-
TR = real_arr_type(TA)
148-
# freqs = similar(arr, real(eltype(arr_ft)), select_sizes(arr_ft, d))
149-
freqs = TR(reorient(fftfreq(size(arr, d))[1:s], d, Val(N)))
147+
# TR = real_arr_type(TA)
148+
freqs = similar(arr, real(eltype(arr_ft)), select_sizes(arr_ft, d))
149+
# freqs = TR(reorient(fftfreq(size(arr, d))[1:s], d, Val(N)))
150+
freqs .= reorient(rfftfreq(size(arr, d)), d, Val(N))
150151
if iszero(soft_fraction)
151152
ϕ = cispi.(-freqs .* 2 .* shift)
152153
else

test/fourier_filtering.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Random.seed!(42)
66
sz = (21, 22)
77
x = randn(ComplexF32, sz)
88
sigma = (1.1,2.2)
9-
gf = filter_gaussian(x, sigma)
9+
gf = filter_gaussian(x, sigma, real_space_kernel=false)
1010
# Note that this is not the same, since one kernel is generated in real space and one in Fourier space!
1111
# with sizes around 10, the difference is huge!
1212
k = gaussian(Float32, sz, sigma=sigma)
@@ -21,7 +21,7 @@ Random.seed!(42)
2121
sz = (21, 22)
2222
x = randn(Float32, sz)
2323
sigma = (1.1,2.2)
24-
gf = filter_gaussian(x, sigma)
24+
gf = filter_gaussian(x, sigma, real_space_kernel=true)
2525
# Note that this is not the same, since one kernel is generated in real space and one in Fourier space!
2626
# with sizes around 10, the difference is huge!
2727
k = gaussian(sz, sigma=sigma)

0 commit comments

Comments
 (0)