1- # This file contains code that was formerly part of Julia. License is MIT: https://julialang.org/license
2-
31using AbstractFFTs
42using AbstractFFTs: Plan
53using ChainRulesTestUtils
@@ -12,235 +10,16 @@ import Unitful
1210
1311Random. seed! (1234 )
1412
15- include (" testplans.jl" )
16-
17- @testset " rfft sizes" begin
18- A = rand (11 , 10 )
19- @test @inferred (AbstractFFTs. rfft_output_size (A, 1 )) == (6 , 10 )
20- @test @inferred (AbstractFFTs. rfft_output_size (A, 2 )) == (11 , 6 )
21- A1 = rand (6 , 10 ); A2 = rand (11 , 6 )
22- @test @inferred (AbstractFFTs. brfft_output_size (A1, 11 , 1 )) == (11 , 10 )
23- @test @inferred (AbstractFFTs. brfft_output_size (A2, 10 , 2 )) == (11 , 10 )
24- @test_throws AssertionError AbstractFFTs. brfft_output_size (A1, 10 , 2 )
25- end
26-
27- @testset " Custom Plan" begin
28- # DFT along last dimension, results computed using FFTW
29- for (x, fftw_fft) in (
30- (collect (1 : 7 ),
31- [28.0 + 0.0im ,
32- - 3.5 + 7.267824888003178im ,
33- - 3.5 + 2.7911568610884143im ,
34- - 3.5 + 0.7988521603655248im ,
35- - 3.5 - 0.7988521603655248im ,
36- - 3.5 - 2.7911568610884143im ,
37- - 3.5 - 7.267824888003178im ]),
38- (collect (1 : 8 ),
39- [36.0 + 0.0im ,
40- - 4.0 + 9.65685424949238im ,
41- - 4.0 + 4.0im ,
42- - 4.0 + 1.6568542494923806im ,
43- - 4.0 + 0.0im ,
44- - 4.0 - 1.6568542494923806im ,
45- - 4.0 - 4.0im ,
46- - 4.0 - 9.65685424949238im ]),
47- (collect (reshape (1 : 8 , 2 , 4 )),
48- [16.0 + 0.0im - 4.0 + 4.0im - 4.0 + 0.0im - 4.0 - 4.0im ;
49- 20.0 + 0.0im - 4.0 + 4.0im - 4.0 + 0.0im - 4.0 - 4.0im ]),
50- (collect (reshape (1 : 9 , 3 , 3 )),
51- [12.0 + 0.0im - 4.5 + 2.598076211353316im - 4.5 - 2.598076211353316im ;
52- 15.0 + 0.0im - 4.5 + 2.598076211353316im - 4.5 - 2.598076211353316im ;
53- 18.0 + 0.0im - 4.5 + 2.598076211353316im - 4.5 - 2.598076211353316im ]),
54- )
55- # FFT
56- dims = ndims (x)
57- y = AbstractFFTs. fft (x, dims)
58- @test y ≈ fftw_fft
59- P = plan_fft (x, dims)
60- @test eltype (P) === ComplexF64
61- @test P * x ≈ fftw_fft
62- @test P \ (P * x) ≈ x
63- @test fftdims (P) == dims
64-
65- fftw_bfft = complex .(size (x, dims) .* x)
66- @test AbstractFFTs. bfft (y, dims) ≈ fftw_bfft
67- P = plan_bfft (x, dims)
68- @test P * y ≈ fftw_bfft
69- @test P \ (P * y) ≈ y
70- @test fftdims (P) == dims
71-
72- fftw_ifft = complex .(x)
73- @test AbstractFFTs. ifft (y, dims) ≈ fftw_ifft
74- P = plan_ifft (x, dims)
75- @test P * y ≈ fftw_ifft
76- @test P \ (P * y) ≈ y
77- @test fftdims (P) == dims
78-
79- # real FFT
80- fftw_rfft = fftw_fft[
81- (Colon () for _ in 1 : (ndims (fftw_fft) - 1 )). .. ,
82- 1 : (size (fftw_fft, ndims (fftw_fft)) ÷ 2 + 1 )
83- ]
84- ry = AbstractFFTs. rfft (x, dims)
85- @test ry ≈ fftw_rfft
86- P = plan_rfft (x, dims)
87- @test eltype (P) === Int
88- @test P * x ≈ fftw_rfft
89- @test P \ (P * x) ≈ x
90- @test fftdims (P) == dims
91-
92- fftw_brfft = complex .(size (x, dims) .* x)
93- @test AbstractFFTs. brfft (ry, size (x, dims), dims) ≈ fftw_brfft
94- P = plan_brfft (ry, size (x, dims), dims)
95- @test P * ry ≈ fftw_brfft
96- @test P \ (P * ry) ≈ ry
97- @test fftdims (P) == dims
13+ const GROUP = get (ENV , " GROUP" , " All" )
9814
99- fftw_irfft = complex .(x)
100- @test AbstractFFTs. irfft (ry, size (x, dims), dims) ≈ fftw_irfft
101- P = plan_irfft (ry, size (x, dims), dims)
102- @test P * ry ≈ fftw_irfft
103- @test P \ (P * ry) ≈ ry
104- @test fftdims (P) == dims
105- end
106- end
107-
108- @testset " Shift functions" begin
109- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ])) == [3 1 2 ]
110- @test @inferred (AbstractFFTs. fftshift ([1 , 2 , 3 ])) == [3 , 1 , 2 ]
111- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ])) == [6 4 5 ; 3 1 2 ]
112- a = [0 0 0 ]
113- b = [0 , 0 , 0 ]
114- c = [0 0 0 ; 0 0 0 ]
115- @test (AbstractFFTs. fftshift! (a, [1 2 3 ]); a == [3 1 2 ])
116- @test (AbstractFFTs. fftshift! (b, [1 , 2 , 3 ]); b == [3 , 1 , 2 ])
117- @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ]); c == [6 4 5 ; 3 1 2 ])
118-
119- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], 1 )) == [4 5 6 ; 1 2 3 ]
120- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], ())) == [1 2 3 ; 4 5 6 ]
121- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], (1 ,2 ))) == [6 4 5 ; 3 1 2 ]
122- @test @inferred (AbstractFFTs. fftshift ([1 2 3 ; 4 5 6 ], 1 : 2 )) == [6 4 5 ; 3 1 2 ]
123- @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], 1 ); c == [4 5 6 ; 1 2 3 ])
124- @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], ()); c == [1 2 3 ; 4 5 6 ])
125- @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], (1 ,2 )); c == [6 4 5 ; 3 1 2 ])
126- @test (AbstractFFTs. fftshift! (c, [1 2 3 ; 4 5 6 ], 1 : 2 ); c == [6 4 5 ; 3 1 2 ])
127-
128- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ])) == [2 3 1 ]
129- @test @inferred (AbstractFFTs. ifftshift ([1 , 2 , 3 ])) == [2 , 3 , 1 ]
130- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ])) == [5 6 4 ; 2 3 1 ]
131- @test (AbstractFFTs. ifftshift! (a, [1 2 3 ]); a == [2 3 1 ])
132- @test (AbstractFFTs. ifftshift! (b, [1 , 2 , 3 ]); b == [2 , 3 , 1 ])
133- @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ]); c == [5 6 4 ; 2 3 1 ])
15+ include (" TestPlans.jl" )
16+ include (" testfft.jl" )
13417
135- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], 1 )) == [4 5 6 ; 1 2 3 ]
136- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], ())) == [1 2 3 ; 4 5 6 ]
137- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], (1 ,2 ))) == [5 6 4 ; 2 3 1 ]
138- @test @inferred (AbstractFFTs. ifftshift ([1 2 3 ; 4 5 6 ], 1 : 2 )) == [5 6 4 ; 2 3 1 ]
139- @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], 1 ); c == [4 5 6 ; 1 2 3 ])
140- @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], ()); c == [1 2 3 ; 4 5 6 ])
141- @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], (1 ,2 )); c == [5 6 4 ; 2 3 1 ])
142- @test (AbstractFFTs. ifftshift! (c, [1 2 3 ; 4 5 6 ], 1 : 2 ); c == [5 6 4 ; 2 3 1 ])
18+ if GROUP == " All" || GROUP == " TestPlans"
19+ using . TestPlans
20+ testfft ()
21+ elseif GROUP == " All" || GROUP == " FFTW" # integration test with FFTW
22+ using FFTW
23+ testfft ()
14324end
14425
145- @testset " FFT Frequencies" begin
146- @test fftfreq (8 ) isa Frequencies
147- @test copy (fftfreq (8 )) isa Frequencies
148-
149- # N even
150- @test fftfreq (8 ) == [0.0 , 0.125 , 0.25 , 0.375 , - 0.5 , - 0.375 , - 0.25 , - 0.125 ]
151- @test rfftfreq (8 ) == [0.0 , 0.125 , 0.25 , 0.375 , 0.5 ]
152- @test fftshift (fftfreq (8 )) == - 0.5 : 0.125 : 0.375
153-
154- # N odd
155- @test fftfreq (5 ) == [0.0 , 0.2 , 0.4 , - 0.4 , - 0.2 ]
156- @test rfftfreq (5 ) == [0.0 , 0.2 , 0.4 ]
157- @test fftshift (fftfreq (5 )) == - 0.4 : 0.2 : 0.4
158-
159- # Sampling Frequency
160- @test fftfreq (5 , 2 ) == [0.0 , 0.4 , 0.8 , - 0.8 , - 0.4 ]
161- # <:Number type compatibility
162- @test eltype (fftfreq (5 , ComplexF64 (2 ))) == ComplexF64
163-
164- @test_throws ArgumentError Frequencies (12 , 10 , 1 )
165-
166- @testset " scaling" begin
167- @test fftfreq (4 , 1 ) * 2 === fftfreq (4 , 2 )
168- @test fftfreq (4 , 1 ) .* 2 === fftfreq (4 , 2 )
169- @test 2 * fftfreq (4 , 1 ) === fftfreq (4 , 2 )
170- @test 2 .* fftfreq (4 , 1 ) === fftfreq (4 , 2 )
171-
172- @test fftfreq (4 , 1 ) / 2 === fftfreq (4 , 1 / 2 )
173- @test fftfreq (4 , 1 ) ./ 2 === fftfreq (4 , 1 / 2 )
174-
175- @test 2 \ fftfreq (4 , 1 ) === fftfreq (4 , 1 / 2 )
176- @test 2 .\ fftfreq (4 , 1 ) === fftfreq (4 , 1 / 2 )
177- end
178-
179- @testset " extrema" begin
180- function check_extrema (freqs)
181- for f in [minimum, maximum, extrema]
182- @test f (freqs) == f (collect (freqs)) == f (fftshift (freqs))
183- end
184- end
185- for f in (fftfreq, rfftfreq), n in (8 , 9 ), multiplier in (2 , 1 / 3 , - 1 / 7 , 1.0 * Unitful. mm)
186- freqs = f (n, multiplier)
187- check_extrema (freqs)
188- end
189- end
190- end
191-
192- @testset " normalization" begin
193- # normalization should be inferable even if region is only inferred as ::Any,
194- # need to wrap in another function to test this (note that p.region::Any for
195- # p::TestPlan)
196- f9 (p:: Plan{T} , sz) where {T} = AbstractFFTs. normalization (real (T), sz, fftdims (p))
197- @test @inferred (f9 (plan_fft (zeros (10 ), 1 ), 10 )) == 1 / 10
198- end
199-
200- @testset " ChainRules" begin
201- @testset " shift functions" begin
202- for x in (randn (3 ), randn (3 , 4 ), randn (3 , 4 , 5 ))
203- for dims in ((), 1 , 2 , (1 ,2 ), 1 : 2 )
204- any (d > ndims (x) for d in dims) && continue
205-
206- # type inference checks of `rrule` fail on old Julia versions
207- # for higher-dimensional arrays:
208- # https://github.com/JuliaMath/AbstractFFTs.jl/pull/58#issuecomment-916530016
209- check_inferred = ndims (x) < 3 || VERSION >= v " 1.6"
210-
211- test_frule (AbstractFFTs. fftshift, x, dims)
212- test_rrule (AbstractFFTs. fftshift, x, dims; check_inferred= check_inferred)
213-
214- test_frule (AbstractFFTs. ifftshift, x, dims)
215- test_rrule (AbstractFFTs. ifftshift, x, dims; check_inferred= check_inferred)
216- end
217- end
218- end
219-
220- @testset " fft" begin
221- for x in (randn (3 ), randn (3 , 4 ), randn (3 , 4 , 5 ))
222- N = ndims (x)
223- complex_x = complex .(x)
224- for dims in unique ((1 , 1 : N, N))
225- for f in (fft, ifft, bfft)
226- test_frule (f, x, dims)
227- test_rrule (f, x, dims)
228- test_frule (f, complex_x, dims)
229- test_rrule (f, complex_x, dims)
230- end
231-
232- test_frule (rfft, x, dims)
233- test_rrule (rfft, x, dims)
234-
235- for f in (irfft, brfft)
236- for d in (2 * size (x, first (dims)) - 1 , 2 * size (x, first (dims)) - 2 )
237- test_frule (f, x, d, dims)
238- test_rrule (f, x, d, dims)
239- test_frule (f, complex_x, d, dims)
240- test_rrule (f, complex_x, d, dims)
241- end
242- end
243- end
244- end
245- end
246- end
0 commit comments