Skip to content

Commit 8fbc1ca

Browse files
authored
Merge pull request #33 from bionanoimaging/FourierReverse
added fourier_reverse! operations
2 parents de6204a + 0e1f04e commit 8fbc1ca

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

docs/src/utils.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ FourierTools.select_region
66
FourierTools.center_set!
77
FourierTools.get_indices_around_center
88
FourierTools.center_extract
9+
FourierTools.odd_view
10+
FourierTools.fourier_reverse!
911
```

src/utils.jl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export rft_size, fft_center, fftpos
22
export expanddims, fourierspace_pixelsize, realspace_pixelsize
33
export δ
4+
export fourier_reverse!
5+
46

57
#get_RFT_scale(real_size) = 0.5 ./ (max.(real_size ./ 2, 1)) # The same as the FFT scale but for the full array in real space!
68

@@ -397,3 +399,61 @@ Base.@propagate_inbounds function Base.setindex!(A::PaddedView{T, N}, v, i::Vara
397399
return A
398400
end
399401
=#
402+
403+
"""
404+
odd_view(arr)
405+
406+
creates a view of `arr` that for each even dimension excludes the
407+
starting index yielding a view of the array with only odd dimensions.
408+
This is useful for operations in Fourier-space which should leave the first index unaltered
409+
such as reverse!
410+
Note that an array reversal can also be achieved by using two ffts instead of one fft and one ifft.
411+
412+
# Examples
413+
```jldoctest
414+
julia> odd_view([1 2 3; 4 5 6])
415+
1×3 view(::Matrix{Int64}, 2:2, 1:3) with eltype Int64:
416+
4 5 6
417+
```
418+
"""
419+
function odd_view(arr)
420+
s_idx = ntuple((d)->firstindex(arr,d) + iseven.(size(arr,d)), Val(ndims(arr)))
421+
ids = ntuple((d)->s_idx[d]:lastindex(arr,d), Val(ndims(arr)))
422+
return @view arr[ids...]
423+
end
424+
425+
"""
426+
fourier_reverse!(arr; dims=1:ndims(arr))
427+
428+
reverses the dimensions of the input array `arr` in place. This effectively mirrors these array.
429+
Note that for even-sized dimensions the first index is excluded from the reverse operation along this dimensions.
430+
431+
# Example
432+
```jldoctest
433+
julia> a = [1 2 3;4 5 6;7 8 9;10 11 12]
434+
4×3 Matrix{Int64}:
435+
1 2 3
436+
4 5 6
437+
7 8 9
438+
10 11 12
439+
440+
julia> fourier_reverse!(a);
441+
442+
julia> a
443+
4×3 Matrix{Int64}:
444+
3 2 1
445+
12 11 10
446+
9 8 7
447+
6 5 4
448+
```
449+
"""
450+
function fourier_reverse!(arr; dims=ntuple((d)->d,Val(ndims(arr))))
451+
reverse!(odd_view(arr),dims=dims)
452+
for d = 1:ndims(arr)
453+
if iseven(size(arr,d))
454+
fv = slice(arr,d,firstindex(arr,d))
455+
fourier_reverse!(fv; dims=dims)
456+
end
457+
end
458+
return arr
459+
end

test/utils.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,27 @@
115115
@test_throws ArgumentError FourierTools.eltype_error(Float32, Float64)
116116
@test isnothing(FourierTools.eltype_error(Int, Int))
117117
end
118+
119+
@testset "odd_view, fourier_reverse!" begin
120+
a = [1 2 3;4 5 6;7 8 9;10 11 12]
121+
@test FourierTools.odd_view(a) == [4 5 6;7 8 9; 10 11 12]
122+
fourier_reverse!(a)
123+
@test a == [3 2 1;12 11 10;9 8 7;6 5 4]
124+
a = [1 2 3;4 5 6;7 8 9;10 11 12]
125+
b = copy(a);
126+
fourier_reverse!(a,dims=1);
127+
@test a[2:end,:] == b[end:-1:2,:]
128+
a = [1 2 3 4;5 6 7 8;9 10 11 12 ;13 14 15 16]
129+
b = copy(a);
130+
fourier_reverse!(a);
131+
@test a[2,2] == b[4,4]
132+
@test a[2,3] == b[4,3]
133+
fourier_reverse!(a);
134+
@test a == b
135+
fourier_reverse!(a;dims=1);
136+
@test a[2:end,:] == b[end:-1:2,:]
137+
@test sum(abs.(imag.(ift(fourier_reverse!(ft(rand(5,6,7))))))) < 1e-10
138+
sz = (10,9,6)
139+
@test sum(abs.(real.(ift(fourier_reverse!(ft(box((sz)))))) .- box(sz))) < 1e-10
140+
end
118141
end

0 commit comments

Comments
 (0)