1
- # This file contains code that was formerly part of Julia. License is MIT: https://julialang.org/license
2
-
3
1
using AbstractFFTs
4
2
using AbstractFFTs: Plan
5
3
using ChainRulesTestUtils
@@ -12,235 +10,16 @@ import Unitful
12
10
13
11
Random. seed! (1234 )
14
12
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" )
98
14
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" )
134
17
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 ()
143
24
end
144
25
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