@@ -9,6 +9,145 @@ Random.seed!(1234)
99include (" TestPlans.jl" )
1010
1111using . TestPlans
12- test_fft_backend ()
12+ test_fft_backend () # Tests for FFT plans (and operations in AbstractFFTs that derive from them)
1313
14- include (" chainrules.jl" )
14+ @testset " Shift functions" begin
15+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ])) == [3 1 2 ]
16+ @test @inferred (AbstractFFTs. fftshift ([1 , 2 , 3 ])) == [3 , 1 , 2 ]
17+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ])) == [6 4 5 ; 3 1 2 ]
18+ a = [0 0 0 ]
19+ b = [0 , 0 , 0 ]
20+ c = [0 0 0 ; 0 0 0 ]
21+ @test (AbstractFFTs. fftshift! (a, [1 2 3 ]); a == [3 1 2 ])
22+ @test (AbstractFFTs. fftshift! (b, [1 , 2 , 3 ]); b == [3 , 1 , 2 ])
23+ @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ]); c == [6 4 5 ; 3 1 2 ])
24+
25+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], 1 )) == [4 5 6 ; 1 2 3 ]
26+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], ())) == [1 2 3 ; 4 5 6 ]
27+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], (1 ,2 ))) == [6 4 5 ; 3 1 2 ]
28+ @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], 1 : 2 )) == [6 4 5 ; 3 1 2 ]
29+ @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], 1 ); c == [4 5 6 ; 1 2 3 ])
30+ @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], ()); c == [1 2 3 ; 4 5 6 ])
31+ @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], (1 ,2 )); c == [6 4 5 ; 3 1 2 ])
32+ @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], 1 : 2 ); c == [6 4 5 ; 3 1 2 ])
33+
34+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ])) == [2 3 1 ]
35+ @test @inferred (AbstractFFTs. ifftshift ([1 , 2 , 3 ])) == [2 , 3 , 1 ]
36+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ])) == [5 6 4 ; 2 3 1 ]
37+ @test (AbstractFFTs. ifftshift! (a, [1 2 3 ]); a == [2 3 1 ])
38+ @test (AbstractFFTs. ifftshift! (b, [1 , 2 , 3 ]); b == [2 , 3 , 1 ])
39+ @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ]); c == [5 6 4 ; 2 3 1 ])
40+
41+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], 1 )) == [4 5 6 ; 1 2 3 ]
42+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], ())) == [1 2 3 ; 4 5 6 ]
43+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], (1 ,2 ))) == [5 6 4 ; 2 3 1 ]
44+ @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], 1 : 2 )) == [5 6 4 ; 2 3 1 ]
45+ @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], 1 ); c == [4 5 6 ; 1 2 3 ])
46+ @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], ()); c == [1 2 3 ; 4 5 6 ])
47+ @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], (1 ,2 )); c == [5 6 4 ; 2 3 1 ])
48+ @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], 1 : 2 ); c == [5 6 4 ; 2 3 1 ])
49+ end
50+
51+ @testset " FFT Frequencies" begin
52+ @test fftfreq (8 ) isa Frequencies
53+ @test copy (fftfreq (8 )) isa Frequencies
54+
55+ # N even
56+ @test fftfreq (8 ) == [0.0 , 0.125 , 0.25 , 0.375 , - 0.5 , - 0.375 , - 0.25 , - 0.125 ]
57+ @test rfftfreq (8 ) == [0.0 , 0.125 , 0.25 , 0.375 , 0.5 ]
58+ @test fftshift (fftfreq (8 )) == - 0.5 : 0.125 : 0.375
59+
60+ # N odd
61+ @test fftfreq (5 ) == [0.0 , 0.2 , 0.4 , - 0.4 , - 0.2 ]
62+ @test rfftfreq (5 ) == [0.0 , 0.2 , 0.4 ]
63+ @test fftshift (fftfreq (5 )) == - 0.4 : 0.2 : 0.4
64+
65+ # Sampling Frequency
66+ @test fftfreq (5 , 2 ) == [0.0 , 0.4 , 0.8 , - 0.8 , - 0.4 ]
67+ # <:Number type compatibility
68+ @test eltype (fftfreq (5 , ComplexF64 (2 ))) == ComplexF64
69+
70+ @test_throws ArgumentError Frequencies (12 , 10 , 1 )
71+
72+ @testset " scaling" begin
73+ @test fftfreq (4 , 1 ) * 2 === fftfreq (4 , 2 )
74+ @test fftfreq (4 , 1 ) .* 2 === fftfreq (4 , 2 )
75+ @test 2 * fftfreq (4 , 1 ) === fftfreq (4 , 2 )
76+ @test 2 .* fftfreq (4 , 1 ) === fftfreq (4 , 2 )
77+
78+ @test fftfreq (4 , 1 ) / 2 === fftfreq (4 , 1 / 2 )
79+ @test fftfreq (4 , 1 ) ./ 2 === fftfreq (4 , 1 / 2 )
80+
81+ @test 2 \ fftfreq (4 , 1 ) === fftfreq (4 , 1 / 2 )
82+ @test 2 .\ fftfreq (4 , 1 ) === fftfreq (4 , 1 / 2 )
83+ end
84+
85+ @testset " extrema" begin
86+ function check_extrema (freqs)
87+ for f in [minimum, maximum, extrema]
88+ @test f (freqs) == f (collect (freqs)) == f (fftshift (freqs))
89+ end
90+ end
91+ for f in (fftfreq, rfftfreq), n in (8 , 9 ), multiplier in (2 , 1 / 3 , - 1 / 7 , 1.0 * Unitful. mm)
92+ freqs = f (n, multiplier)
93+ check_extrema (freqs)
94+ end
95+ end
96+ end
97+
98+ @testset " normalization" begin
99+ # normalization should be inferable even if region is only inferred as ::Any,
100+ # need to wrap in another function to test this (note that p.region::Any for
101+ # p::TestPlan)
102+ f9 (p:: Plan{T} , sz) where {T} = AbstractFFTs. normalization (real (T), sz, fftdims (p))
103+ @test @inferred (f9 (plan_fft (zeros (10 ), 1 ), 10 )) == 1 / 10
104+ end
105+
106+ @testset " ChainRules" begin
107+ @testset " shift functions" begin
108+ for x in (randn (3 ), randn (3 , 4 ), randn (3 , 4 , 5 ))
109+ for dims in ((), 1 , 2 , (1 ,2 ), 1 : 2 )
110+ any (d > ndims (x) for d in dims) && continue
111+
112+ # type inference checks of `rrule` fail on old Julia versions
113+ # for higher-dimensional arrays:
114+ # https://github.com/JuliaMath/AbstractFFTs.jl/pull/58#issuecomment-916530016
115+ check_inferred = ndims (x) < 3 || VERSION >= v " 1.6"
116+
117+ test_frule (AbstractFFTs. fftshift, x, dims)
118+ test_rrule (AbstractFFTs. fftshift, x, dims; check_inferred= check_inferred)
119+
120+ test_frule (AbstractFFTs. ifftshift, x, dims)
121+ test_rrule (AbstractFFTs. ifftshift, x, dims; check_inferred= check_inferred)
122+ end
123+ end
124+ end
125+
126+ @testset " fft" begin
127+ for x in (randn (3 ), randn (3 , 4 ), randn (3 , 4 , 5 ))
128+ N = ndims (x)
129+ complex_x = complex .(x)
130+ for dims in unique ((1 , 1 : N, N))
131+ for f in (fft, ifft, bfft)
132+ test_frule (f, x, dims)
133+ test_rrule (f, x, dims)
134+ test_frule (f, complex_x, dims)
135+ test_rrule (f, complex_x, dims)
136+ end
137+
138+ test_frule (rfft, x, dims)
139+ test_rrule (rfft, x, dims)
140+
141+ for f in (irfft, brfft)
142+ for d in (2 * size (x, first (dims)) - 1 , 2 * size (x, first (dims)) - 2 )
143+ test_frule (f, x, d, dims)
144+ test_rrule (f, x, d, dims)
145+ test_frule (f, complex_x, d, dims)
146+ test_rrule (f, complex_x, d, dims)
147+ end
148+ end
149+ end
150+ end
151+ end
152+ end
153+
0 commit comments