Skip to content

Commit a56adb5

Browse files
added fourier_reverse operations
1 parent de6204a commit a56adb5

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

src/utils.jl

Lines changed: 59 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 odd_view, 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,60 @@ 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` the 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+
411+
# Examples
412+
```jldoctest
413+
julia> odd_view([1 2 3; 4 5 6])
414+
1×3 view(::Matrix{Int64}, 2:2, 1:3) with eltype Int64:
415+
4 5 6
416+
```
417+
"""
418+
function odd_view(arr)
419+
s_idx = ntuple((d)->firstindex(arr,d) + iseven.(size(arr,d)), Val(ndims(arr)))
420+
ids = ntuple((d)->s_idx[d]:lastindex(arr,d), Val(ndims(arr)))
421+
return @view arr[ids...]
422+
end
423+
424+
"""
425+
fourier_reverse!(arr; dims=1:ndims(arr))
426+
427+
reverses the dimensions of the input array `arr` in place. This effectively mirrors these array.
428+
Note that for even-sized dimensions the first index is excluded from the reverse operation along this dimensions.
429+
430+
# Example
431+
```jldoctest
432+
julia> a = [1 2 3;4 5 6;7 8 9;10 11 12]
433+
4×3 Matrix{Int64}:
434+
1 2 3
435+
4 5 6
436+
7 8 9
437+
10 11 12
438+
439+
julia> fourier_reverse!(a);
440+
441+
julia> a
442+
4×3 Matrix{Int64}:
443+
3 2 1
444+
12 11 10
445+
9 8 7
446+
6 5 4
447+
```
448+
"""
449+
function fourier_reverse!(arr; dims=ntuple((d)->d,Val(ndims(arr))))
450+
reverse!(odd_view(arr),dims=dims)
451+
for d = 1:ndims(arr)
452+
if iseven(size(arr,d))
453+
fv = slice(arr,d,firstindex(arr,d))
454+
fourier_reverse!(fv; dims=dims)
455+
end
456+
end
457+
return arr
458+
end

test/utils.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,26 @@
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+
@test odd_view(a) == [4 5 6;7 8 9; 10 11 12]
121+
fourier_reverse!(a)
122+
@test a == [3 2 1;12 11 10;9 8 7;6 5 4]
123+
a = [1 2 3;4 5 6;7 8 9;10 11 12]
124+
b = copy(a);
125+
fourier_reverse!(a,dims=1);
126+
@test a[2:end,:] == b[end:-1:2,:]
127+
a = [1 2 3 4;5 6 7 8;9 10 11 12 ;13 14 15 16]
128+
b = copy(a);
129+
fourier_reverse!(a);
130+
@test a[2,2] == b[4,4]
131+
@test a[2,3] == b[4,3]
132+
fourier_reverse!(a);
133+
@test a == b
134+
fourier_reverse!(a;dims=1);
135+
@test a[2:end,:] == b[end:-1:2,:]
136+
@test sum(abs.(imag.(ift(fourier_reverse!(ft(rand(5,6,7))))))) < 1e-10
137+
sz = (10,9,6)
138+
@test sum(abs.(real.(ift(fourier_reverse!(ft(box((sz)))))) .- box(sz))) < 1e-10
139+
end
118140
end

0 commit comments

Comments
 (0)