1
1
# This file contains code that was formerly part of Julia. License is MIT: https://julialang.org/license
2
2
3
- module AbstractFFTsTestUtilsExt
3
+ module AbstractFFTsTestExt
4
4
5
5
using AbstractFFTs
6
6
using AbstractFFTs: TestUtils
7
7
using AbstractFFTs. LinearAlgebra
8
8
using Test
9
9
10
- # Ground truth _x_fft computed using FFTW library
10
+ # Ground truth x_fft computed using FFTW library
11
11
const TEST_CASES = (
12
12
(; x = collect (1 : 7 ), dims = 1 ,
13
13
x_fft = [28.0 + 0.0im ,
@@ -51,29 +51,47 @@ const TEST_CASES = (
51
51
dims= 3 )),
52
52
)
53
53
54
- function TestUtils. test_plan_adjoint (P:: AbstractFFTs.Plan , x:: AbstractArray ; real_plan= false )
55
- y = rand (eltype (P * x), size (P * x))
54
+
55
+ function TestUtils. test_plan (P:: AbstractFFTs.Plan , x:: AbstractArray , x_transformed:: AbstractArray ; inplace_plan= false , copy_input= false )
56
+ _copy = copy_input ? copy : identity
57
+ if ! inplace_plan
58
+ @test P * _copy (x) ≈ x_transformed
59
+ @test P \ (P * _copy (x)) ≈ x
60
+ _x_out = similar (P * _copy (x))
61
+ @test mul! (_x_out, P, _copy (x)) ≈ x_transformed
62
+ @test _x_out ≈ x_transformed
63
+ else
64
+ _x = copy (x)
65
+ @test P * _copy (_x) ≈ x_transformed
66
+ @test _x ≈ x_transformed
67
+ @test P \ _copy (_x) ≈ x
68
+ @test _x ≈ x
69
+ end
70
+ end
71
+
72
+ function TestUtils. test_plan_adjoint (P:: AbstractFFTs.Plan , x:: AbstractArray ; real_plan= false , copy_input= false )
73
+ _copy = copy_input ? copy : identity
74
+ y = rand (eltype (P * _copy (x)), size (P * _copy (x)))
56
75
# test basic properties
57
- @test_broken eltype (P' ) === typeof (y) # (AbstractFFTs.jl#110)
58
- @test fftdims (P' ) == fftdims (P)
76
+ @test_skip eltype (P' ) === typeof (y) # (AbstractFFTs.jl#110)
59
77
@test (P' )' === P # test adjoint of adjoint
60
78
@test size (P' ) == AbstractFFTs. output_size (P) # test size of adjoint
61
79
# test correctness of adjoint and its inverse via the dot test
62
80
if ! real_plan
63
- @test dot (y, P * x) ≈ dot (P' * y , x)
64
- @test dot (y, P \ x) ≈ dot (P' \ y , x)
81
+ @test dot (y, P * _copy (x)) ≈ dot (P' * _copy (y) , x)
82
+ @test dot (y, P \ _copy (x)) ≈ dot (P' \ _copy (y) , x)
65
83
else
66
84
_component_dot (x, y) = dot (real .(x), real .(y)) + dot (imag .(x), imag .(y))
67
- @test _component_dot (y, P * copy (x)) ≈ _component_dot (P' * copy (y), x)
68
- @test _component_dot (x, P \ copy (y)) ≈ _component_dot (P' \ copy (x), y)
85
+ @test _component_dot (y, P * _copy (x)) ≈ _component_dot (P' * _copy (y), x)
86
+ @test _component_dot (x, P \ _copy (y)) ≈ _component_dot (P' \ _copy (x), y)
69
87
end
70
88
@test_throws MethodError mul! (x, P' , y)
71
89
end
72
90
73
- function TestUtils. test_complex_fft (ArrayType= Array; test_inplace= true , test_adjoint= true )
91
+ function TestUtils. test_complex_ffts (ArrayType= Array; test_inplace= true , test_adjoint= true )
74
92
@testset " correctness of fft, bfft, ifft" begin
75
93
for test_case in TEST_CASES
76
- _x, dims, _x_fft = test_case. x, test_case. dims, test_case. x_fft
94
+ _x, dims, _x_fft = copy ( test_case. x) , test_case. dims, copy ( test_case. x_fft)
77
95
x = convert (ArrayType, _x) # dummy array that will be passed to plans
78
96
x_complexf = convert (ArrayType, complex .(float .(x))) # for testing mutating complex FFTs
79
97
x_fft = convert (ArrayType, _x_fft)
@@ -90,25 +108,16 @@ function TestUtils.test_complex_fft(ArrayType=Array; test_inplace=true, test_adj
90
108
for P in (plan_fft (similar (x_complexf), dims), inv (plan_ifft (similar (x_complexf), dims)))
91
109
@test eltype (P) <: Complex
92
110
@test fftdims (P) == dims
93
- @test P * x ≈ x_fft
94
- @test P \ (P * x) ≈ x
95
- _x_out = similar (x_fft)
96
- @test mul! (_x_out, P, x_complexf) ≈ x_fft
97
- @test _x_out ≈ x_fft
111
+ TestUtils. test_plan (P, x_complexf, x_fft)
98
112
if test_adjoint
113
+ @test fftdims (P' ) == fftdims (P)
99
114
TestUtils. test_plan_adjoint (P, x_complexf)
100
115
end
101
116
end
102
117
if test_inplace
103
118
# test IIP plans
104
119
for P in (plan_fft! (similar (x_complexf), dims), inv (plan_ifft! (similar (x_complexf), dims)))
105
- @test eltype (P) <: Complex
106
- @test fftdims (P) == dims
107
- _x_complexf = copy (x_complexf)
108
- @test P * _x_complexf ≈ x_fft
109
- @test _x_complexf ≈ x_fft
110
- @test P \ _x_complexf ≈ x
111
- @test _x_complexf ≈ x
120
+ TestUtils. test_plan (P, x_complexf, x_fft; inplace_plan= true )
112
121
end
113
122
end
114
123
@@ -124,24 +133,16 @@ function TestUtils.test_complex_fft(ArrayType=Array; test_inplace=true, test_adj
124
133
for P in (plan_bfft (similar (x_fft), dims),)
125
134
@test eltype (P) <: Complex
126
135
@test fftdims (P) == dims
127
- @test P * x_fft ≈ x_scaled
128
- @test P \ (P * x_fft) ≈ x_fft
129
- _x_complexf = similar (x_complexf)
130
- @test mul! (_x_complexf, P, x_fft) ≈ x_scaled
131
- @test _x_complexf ≈ x_scaled
136
+ TestUtils. test_plan (P, x_fft, x_scaled)
132
137
if test_adjoint
133
- TestUtils. test_plan_adjoint (P, x_complexf )
138
+ TestUtils. test_plan_adjoint (P, x_fft )
134
139
end
135
140
end
136
141
# test IIP plans
137
142
for P in (plan_bfft! (similar (x_fft), dims),)
138
143
@test eltype (P) <: Complex
139
144
@test fftdims (P) == dims
140
- _x_fft = copy (x_fft)
141
- @test P * _x_fft ≈ x_scaled
142
- @test _x_fft ≈ x_scaled
143
- @test P \ _x_fft ≈ x_fft
144
- @test _x_fft ≈ x_fft
145
+ TestUtils. test_plan (P, x_fft, x_scaled; inplace_plan= true )
145
146
end
146
147
147
148
# IFFT
@@ -155,35 +156,27 @@ function TestUtils.test_complex_fft(ArrayType=Array; test_inplace=true, test_adj
155
156
for P in (plan_ifft (similar (x_complexf), dims), inv (plan_fft (similar (x_complexf), dims)))
156
157
@test eltype (P) <: Complex
157
158
@test fftdims (P) == dims
158
- @test P * x_fft ≈ x
159
- @test P \ (P * x_fft) ≈ x_fft
160
- _x_complexf = similar (x_complexf)
161
- @test mul! (_x_complexf, P, x_fft) ≈ x
162
- @test _x_complexf ≈ x
159
+ TestUtils. test_plan (P, x_fft, x)
163
160
if test_adjoint
164
- TestUtils. test_plan_adjoint (P, x_complexf )
161
+ TestUtils. test_plan_adjoint (P, x_fft )
165
162
end
166
163
end
167
164
# test IIP plans
168
165
if test_inplace
169
166
for P in (plan_ifft! (similar (x_complexf), dims), inv (plan_fft! (similar (x_complexf), dims)))
170
167
@test eltype (P) <: Complex
171
168
@test fftdims (P) == dims
172
- _x_fft = copy (x_fft)
173
- @test P * _x_fft ≈ x
174
- @test _x_fft ≈ x
175
- @test P \ _x_fft ≈ x_fft
176
- @test _x_fft ≈ x_fft
169
+ TestUtils. test_plan (P, x_fft, x; inplace_plan= true )
177
170
end
178
171
end
179
172
end
180
173
end
181
174
end
182
175
183
- function TestUtils. test_real_fft (ArrayType= Array; test_inplace = true , test_adjoint = true )
176
+ function TestUtils. test_real_ffts (ArrayType= Array; test_adjoint = true , copy_input = false )
184
177
@testset " correctness of rfft, brfft, irfft" begin
185
178
for test_case in TEST_CASES
186
- _x, dims, _x_fft = test_case. x, test_case. dims, test_case. x_fft
179
+ _x, dims, _x_fft = copy ( test_case. x) , test_case. dims, copy ( test_case. x_fft)
187
180
x = convert (ArrayType, _x) # dummy array that will be passed to plans
188
181
x_real = float .(x) # for testing mutating real FFTs
189
182
x_fft = convert (ArrayType, _x_fft)
@@ -198,14 +191,9 @@ function TestUtils.test_real_fft(ArrayType=Array; test_inplace=true, test_adjoin
198
191
for P in (plan_rfft (similar (x_real), dims), inv (plan_irfft (similar (x_rfft), size (x, first (dims)), dims)))
199
192
@test eltype (P) <: Real
200
193
@test fftdims (P) == dims
201
- # Always copy input before application due to FFTW real plans possibly mutating input (AbstractFFTs.jl#101)
202
- @test P * copy (x) ≈ x_rfft
203
- @test P \ (P * copy (x)) ≈ x
204
- _x_rfft = similar (x_rfft)
205
- @test mul! (_x_rfft, P, copy (x_real)) ≈ x_rfft
206
- @test _x_rfft ≈ x_rfft
194
+ TestUtils. test_plan (P, x_real, x_rfft; copy_input)
207
195
if test_adjoint
208
- TestUtils. test_plan_adjoint (P, x_real; real_plan= true )
196
+ TestUtils. test_plan_adjoint (P, x_real; real_plan= true , copy_input )
209
197
end
210
198
end
211
199
@@ -215,25 +203,18 @@ function TestUtils.test_real_fft(ArrayType=Array; test_inplace=true, test_adjoin
215
203
for P in (plan_brfft (similar (x_rfft), size (x, first (dims)), dims),)
216
204
@test eltype (P) <: Complex
217
205
@test fftdims (P) == dims
218
- @test P * copy (x_rfft) ≈ x_scaled
219
- @test P \ (P * copy (x_rfft)) ≈ x_rfft
220
- _x_scaled = similar (x_real)
221
- @test mul! (_x_scaled, P, copy (x_rfft)) ≈ x_scaled
222
- @test _x_scaled ≈ x_scaled
206
+ TestUtils. test_plan (P, x_rfft, x_scaled; copy_input)
223
207
end
224
208
225
209
# IRFFT
226
210
@test irfft (x_rfft, size (x, first (dims)), dims) ≈ x
227
211
for P in (plan_irfft (similar (x_rfft), size (x, first (dims)), dims), inv (plan_rfft (similar (x_real), dims)))
228
212
@test eltype (P) <: Complex
229
213
@test fftdims (P) == dims
230
- @test P * copy (x_rfft) ≈ x
231
- @test P \ (P * copy (x_rfft)) ≈ x_rfft
232
- _x_real = similar (x_real)
233
- @test mul! (_x_real, P, copy (x_rfft)) ≈ x_real
214
+ TestUtils. test_plan (P, x_rfft, x; copy_input)
234
215
end
235
216
end
236
217
end
237
218
end
238
219
239
- end
220
+ end
0 commit comments