Skip to content

Commit

Permalink
Merge pull request #66 from Gregstrq/prealloc_fftshift
Browse files Browse the repository at this point in the history
`fftshift!` and `ifftshift!`
  • Loading branch information
stevengj authored Mar 31, 2022
2 parents 4f630d6 + bdcf670 commit 6434327
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/AbstractFFTs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ChainRulesCore
export fft, ifft, bfft, fft!, ifft!, bfft!,
plan_fft, plan_ifft, plan_bfft, plan_fft!, plan_ifft!, plan_bfft!,
rfft, irfft, brfft, plan_rfft, plan_irfft, plan_brfft,
fftshift, ifftshift, Frequencies, fftfreq, rfftfreq
fftshift, ifftshift, fftshift!, ifftshift!, Frequencies, fftfreq, rfftfreq

include("definitions.jl")
include("chainrules.jl")
Expand Down
32 changes: 25 additions & 7 deletions src/definitions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,16 @@ plan_irfft

##############################################################################

"""
fftshift!(dest, src, [dim])
Nonallocating version of [`fftshift`](@ref). Stores the result of the shift of the `src` array into the `dest` array.
"""
function fftshift!(dest, src, dim = 1:ndims(src))
s = ntuple(d -> d in dim ? div(size(dest,d),2) : 0, Val(ndims(dest)))
circshift!(dest, src, s)
end

"""
fftshift(x, [dim])
Expand All @@ -356,12 +366,21 @@ swapping the first and second halves, so `fftshift` and [`ifftshift`](@ref) are
the same.
If `dim` is not given then the signal is shifted along each dimension.
The output of `fftshift` is allocated. If one desires to store the output in a preallocated array, use [`fftshift!`](@ref) instead.
"""
fftshift

function fftshift(x, dim = 1:ndims(x))
s = ntuple(d -> d in dim ? div(size(x,d),2) : 0, Val(ndims(x)))
circshift(x, s)
fftshift(x, dim = 1:ndims(x)) = fftshift!(similar(x), x, dim)

"""
ifftshift!(dest, src, [dim])
Nonallocating version of [`ifftshift`](@ref). Stores the result of the shift of the `src` array into the `dest` array.
"""
function ifftshift!(dest, src, dim = 1:ndims(src))
s = ntuple(d -> d in dim ? -div(size(src,d),2) : 0, Val(ndims(src)))
circshift!(dest, src, s)
end

"""
Expand All @@ -376,13 +395,12 @@ swapping the first and second halves, so [`fftshift`](@ref) and `ifftshift` are
the same.
If `dim` is not given then the signal is shifted along each dimension.
The output of `ifftshift` is allocated. If one desires to store the output in a preallocated array, use [`ifftshift!`](@ref) instead.
"""
ifftshift

function ifftshift(x, dim = 1:ndims(x))
s = ntuple(d -> d in dim ? -div(size(x,d),2) : 0, Val(ndims(x)))
circshift(x, s)
end
ifftshift(x, dim = 1:ndims(x)) = ifftshift!(similar(x), x, dim)

##############################################################################

Expand Down
17 changes: 17 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,37 @@ end
@test @inferred(AbstractFFTs.fftshift([1 2 3])) == [3 1 2]
@test @inferred(AbstractFFTs.fftshift([1, 2, 3])) == [3, 1, 2]
@test @inferred(AbstractFFTs.fftshift([1 2 3; 4 5 6])) == [6 4 5; 3 1 2]
a = [0 0 0]
b = [0, 0, 0]
c = [0 0 0; 0 0 0]
@test (AbstractFFTs.fftshift!(a, [1 2 3]); a == [3 1 2])
@test (AbstractFFTs.fftshift!(b, [1, 2, 3]); b == [3, 1, 2])
@test (AbstractFFTs.fftshift!(c, [1 2 3; 4 5 6]); c == [6 4 5; 3 1 2])

@test @inferred(AbstractFFTs.fftshift([1 2 3; 4 5 6], 1)) == [4 5 6; 1 2 3]
@test @inferred(AbstractFFTs.fftshift([1 2 3; 4 5 6], ())) == [1 2 3; 4 5 6]
@test @inferred(AbstractFFTs.fftshift([1 2 3; 4 5 6], (1,2))) == [6 4 5; 3 1 2]
@test @inferred(AbstractFFTs.fftshift([1 2 3; 4 5 6], 1:2)) == [6 4 5; 3 1 2]
@test (AbstractFFTs.fftshift!(c, [1 2 3; 4 5 6], 1); c == [4 5 6; 1 2 3])
@test (AbstractFFTs.fftshift!(c, [1 2 3; 4 5 6], ()); c == [1 2 3; 4 5 6])
@test (AbstractFFTs.fftshift!(c, [1 2 3; 4 5 6], (1,2)); c == [6 4 5; 3 1 2])
@test (AbstractFFTs.fftshift!(c, [1 2 3; 4 5 6], 1:2); c == [6 4 5; 3 1 2])

@test @inferred(AbstractFFTs.ifftshift([1 2 3])) == [2 3 1]
@test @inferred(AbstractFFTs.ifftshift([1, 2, 3])) == [2, 3, 1]
@test @inferred(AbstractFFTs.ifftshift([1 2 3; 4 5 6])) == [5 6 4; 2 3 1]
@test (AbstractFFTs.ifftshift!(a, [1 2 3]); a == [2 3 1])
@test (AbstractFFTs.ifftshift!(b, [1, 2, 3]); b == [2, 3, 1])
@test (AbstractFFTs.ifftshift!(c, [1 2 3; 4 5 6]); c == [5 6 4; 2 3 1])

@test @inferred(AbstractFFTs.ifftshift([1 2 3; 4 5 6], 1)) == [4 5 6; 1 2 3]
@test @inferred(AbstractFFTs.ifftshift([1 2 3; 4 5 6], ())) == [1 2 3; 4 5 6]
@test @inferred(AbstractFFTs.ifftshift([1 2 3; 4 5 6], (1,2))) == [5 6 4; 2 3 1]
@test @inferred(AbstractFFTs.ifftshift([1 2 3; 4 5 6], 1:2)) == [5 6 4; 2 3 1]
@test (AbstractFFTs.ifftshift!(c, [1 2 3; 4 5 6], 1); c == [4 5 6; 1 2 3])
@test (AbstractFFTs.ifftshift!(c, [1 2 3; 4 5 6], ()); c == [1 2 3; 4 5 6])
@test (AbstractFFTs.ifftshift!(c, [1 2 3; 4 5 6], (1,2)); c == [5 6 4; 2 3 1])
@test (AbstractFFTs.ifftshift!(c, [1 2 3; 4 5 6], 1:2); c == [5 6 4; 2 3 1])
end

@testset "FFT Frequencies" begin
Expand Down

0 comments on commit 6434327

Please sign in to comment.