@@ -8,6 +8,42 @@ const ComplexFloats = Complex{T} where T<:AbstractFloat
8
8
# The following implements Bluestein's algorithm, following http://www.dsprelated.com/dspbooks/mdft/Bluestein_s_FFT_Algorithm.html
9
9
# To add more types, add them in the union of the function's signature.
10
10
11
+ function generic_fft (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
12
+ region == 1 && (ret = generic_fft (x))
13
+ ret
14
+ end
15
+
16
+ function generic_fft! (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
17
+ region == 1 && (x[:] .= generic_fft (x))
18
+ x
19
+ end
20
+
21
+ function generic_fft (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
22
+ region == 1 : 1 && (ret = generic_fft (x))
23
+ ret
24
+ end
25
+
26
+ function generic_fft! (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
27
+ region == 1 : 1 && (x[:] .= generic_fft (x))
28
+ x
29
+ end
30
+
31
+ function generic_fft (x:: StridedMatrix{T} , region:: Integer ) where T<: AbstractFloats
32
+ if region == 1
33
+ ret = hcat ([generic_fft (x[:, j]) for j in 1 : size (x, 2 )]. .. )
34
+ end
35
+ ret
36
+ end
37
+
38
+ function generic_fft! (x:: StridedMatrix{T} , region:: Integer ) where T<: AbstractFloats
39
+ if region == 1
40
+ for j in 1 : size (x, 2 )
41
+ x[:, j] .= generic_fft (x[:, j])
42
+ end
43
+ end
44
+ x
45
+ end
46
+
11
47
function generic_fft (x:: Vector{T} ) where T<: AbstractFloats
12
48
T <: FFTW.fftwNumber && (@warn (" Using generic fft for FFTW number type." ))
13
49
n = length (x)
@@ -18,36 +54,20 @@ function generic_fft(x::Vector{T}) where T<:AbstractFloats
18
54
return Wks.* conv (xq,wq)[n+ 1 : 2 n]
19
55
end
20
56
57
+ generic_bfft (x:: StridedArray{T, N} , region) where {T <: AbstractFloats , N} = conj! (generic_fft (conj (x), region))
58
+ generic_bfft! (x:: StridedArray{T, N} , region) where {T <: AbstractFloats , N} = conj! (generic_fft! (conj! (x), region))
59
+ generic_ifft (x:: StridedArray{T, N} , region) where {T<: AbstractFloats , N} = ldiv! (length (x), conj! (generic_fft (conj (x), region)))
60
+ generic_ifft! (x:: StridedArray{T, N} , region) where {T<: AbstractFloats , N} = ldiv! (length (x), conj! (generic_fft! (conj! (x), region)))
21
61
22
- function generic_fft! (x:: Vector{T} ) where T<: AbstractFloats
23
- x[:] = generic_fft (x)
24
- return x
25
- end
26
-
27
- # add rfft for AbstractFloat, by calling fft
28
- generic_rfft (v:: Vector{T} ) where T<: AbstractFloats = generic_fft (v)[1 : div (length (v),2 )+ 1 ]
29
-
30
- function generic_irfft (v:: Vector{T} , n:: Integer ) where T<: ComplexFloats
62
+ generic_rfft (v:: Vector{T} , region) where T<: AbstractFloats = generic_fft (v, region)[1 : div (length (v),2 )+ 1 ]
63
+ function generic_irfft (v:: Vector{T} , n:: Integer , region) where T<: ComplexFloats
31
64
@assert n== 2 length (v)- 1
32
65
r = Vector {T} (undef, n)
33
66
r[1 : length (v)]= v
34
67
r[length (v)+ 1 : end ]= reverse (conj (v[2 : end ]))
35
- real (generic_ifft (r))
36
- end
37
-
38
- generic_bfft (x:: Vector{T} ) where {T <: AbstractFloats } = conj! (generic_fft (conj (x)))
39
- function generic_bfft! (x:: Vector{T} ) where {T <: AbstractFloats }
40
- x[:] = generic_bfft (x)
41
- return x
42
- end
43
-
44
- generic_brfft (v:: Vector , n:: Integer ) = generic_irfft (v, n)* n
45
-
46
- generic_ifft (x:: Vector{T} ) where {T<: AbstractFloats } = conj! (generic_fft (conj (x)))/ length (x)
47
- function generic_ifft! (x:: Vector{T} ) where T<: AbstractFloats
48
- x[:] = generic_ifft (x)
49
- return x
68
+ real (generic_ifft (r, region))
50
69
end
70
+ generic_brfft (v:: StridedArray , n:: Integer , region) = generic_irfft (v, n, region)* n
51
71
52
72
function conv (u:: StridedVector{T} , v:: StridedVector{T} ) where T<: AbstractFloats
53
73
nu,nv = length (u),length (v)
@@ -112,6 +132,46 @@ function generic_ifft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
112
132
return complex .(y[1 : 2 : end ],- y[2 : 2 : end ])/ length (x)
113
133
end
114
134
135
+ function generic_dct (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
136
+ region == 1 && (ret = generic_dct (x))
137
+ ret
138
+ end
139
+
140
+ function generic_dct! (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
141
+ region == 1 && (x[:] .= generic_dct (x))
142
+ x
143
+ end
144
+
145
+ function generic_idct (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
146
+ region == 1 && (ret = generic_idct (x))
147
+ ret
148
+ end
149
+
150
+ function generic_idct! (x:: StridedVector{T} , region:: Integer ) where T<: AbstractFloats
151
+ region == 1 && (x[:] .= generic_idct (x))
152
+ x
153
+ end
154
+
155
+ function generic_dct (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
156
+ region == 1 : 1 && (ret = generic_dct (x))
157
+ ret
158
+ end
159
+
160
+ function generic_dct! (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
161
+ region == 1 : 1 && (x[:] .= generic_dct (x))
162
+ x
163
+ end
164
+
165
+ function generic_idct (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
166
+ region == 1 : 1 && (ret = generic_idct (x))
167
+ ret
168
+ end
169
+
170
+ function generic_idct! (x:: StridedVector{T} , region:: UnitRange{I} ) where {T<: AbstractFloats , I<: Integer }
171
+ region == 1 : 1 && (x[:] .= generic_idct (x))
172
+ x
173
+ end
174
+
115
175
function generic_dct (a:: AbstractVector{Complex{T}} ) where {T <: AbstractFloat }
116
176
T <: FFTW.fftwNumber && (@warn (" Using generic dct for FFTW number type." ))
117
177
N = length (a)
139
199
140
200
generic_idct (a:: AbstractArray{T} ) where {T <: AbstractFloat } = real (generic_idct (complex (a)))
141
201
142
- generic_dct! (a:: AbstractArray{T} ) where {T<: AbstractFloats } = (b = generic_dct (a); a[:] = b)
143
- generic_idct! (a:: AbstractArray{T} ) where {T<: AbstractFloats } = (b = generic_idct (a); a[:] = b)
144
202
145
203
# These lines mimick the corresponding ones in FFTW/src/dct.jl, but with
146
204
# AbstractFloat rather than fftwNumber.
@@ -157,33 +215,35 @@ abstract type DummyPlan{T} <: Plan{T} end
157
215
for P in (:DummyFFTPlan , :DummyiFFTPlan , :DummybFFTPlan , :DummyDCTPlan , :DummyiDCTPlan )
158
216
# All plans need an initially undefined pinv field
159
217
@eval begin
160
- mutable struct $ P{T,inplace} <: DummyPlan{T}
218
+ mutable struct $ P{T,inplace,G} <: DummyPlan{T}
219
+ region:: G # region (iterable) of dims that are transformed
161
220
pinv:: DummyPlan{T}
162
- $ P {T,inplace} ( ) where {T<: AbstractFloats , inplace} = new ()
221
+ $ P {T,inplace,G} (region :: G ) where {T<: AbstractFloats , inplace, G } = new (region )
163
222
end
164
223
end
165
224
end
166
225
for P in (:DummyrFFTPlan , :DummyirFFTPlan , :DummybrFFTPlan )
167
226
@eval begin
168
- mutable struct $ P{T,inplace} <: DummyPlan{T}
227
+ mutable struct $ P{T,inplace,G } <: DummyPlan{T}
169
228
n:: Integer
229
+ region:: G # region (iterable) of dims that are transformed
170
230
pinv:: DummyPlan{T}
171
- $ P {T,inplace} (n:: Integer ) where {T<: AbstractFloats , inplace} = new (n)
231
+ $ P {T,inplace,G } (n:: Integer , region :: G ) where {T<: AbstractFloats , inplace, G } = new (n, region )
172
232
end
173
233
end
174
234
end
175
235
176
236
for (Plan,iPlan) in ((:DummyFFTPlan ,:DummyiFFTPlan ),
177
237
(:DummyDCTPlan ,:DummyiDCTPlan ))
178
238
@eval begin
179
- plan_inv (:: $Plan{T,inplace} ) where {T,inplace} = $ iPlan {T,inplace} ( )
180
- plan_inv (:: $iPlan{T,inplace} ) where {T,inplace} = $ Plan {T,inplace} ( )
239
+ plan_inv (p :: $Plan{T,inplace,G } ) where {T,inplace,G } = $ iPlan {T,inplace,G} (p . region )
240
+ plan_inv (p :: $iPlan{T,inplace,G } ) where {T,inplace,G } = $ Plan {T,inplace,G} (p . region )
181
241
end
182
242
end
183
243
184
244
# Specific for rfft, irfft and brfft:
185
- plan_inv (p:: DummyirFFTPlan{T,inplace} ) where {T,inplace} = DummyrFFTPlan {T,Inplace} (p. n)
186
- plan_inv (p:: DummyrFFTPlan{T,inplace} ) where {T,inplace} = DummyirFFTPlan {T,Inplace} (p. n)
245
+ plan_inv (p:: DummyirFFTPlan{T,inplace,G } ) where {T,inplace,G } = DummyrFFTPlan {T,Inplace,G } (p. n, p . region )
246
+ plan_inv (p:: DummyrFFTPlan{T,inplace,G } ) where {T,inplace,G } = DummyirFFTPlan {T,Inplace,G } (p. n, p . region )
187
247
188
248
189
249
@@ -194,26 +254,26 @@ for (Plan,ff,ff!) in ((:DummyFFTPlan,:generic_fft,:generic_fft!),
194
254
(:DummyDCTPlan ,:generic_dct ,:generic_dct! ),
195
255
(:DummyiDCTPlan ,:generic_idct ,:generic_idct! ))
196
256
@eval begin
197
- * (p:: $Plan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = $ ff! (x)
198
- * (p:: $Plan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = $ ff (x)
257
+ * (p:: $Plan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = $ ff! (x, p . region )
258
+ * (p:: $Plan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = $ ff (x, p . region )
199
259
function mul! (C:: StridedVector , p:: $Plan , x:: StridedVector )
200
- C[:] = $ ff (x)
260
+ C[:] = $ ff (x, p . region )
201
261
C
202
262
end
203
263
end
204
264
end
205
265
206
266
# Specific for irfft and brfft:
207
- * (p:: DummyirFFTPlan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_irfft! (x, p. n)
208
- * (p:: DummyirFFTPlan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_irfft (x, p. n)
267
+ * (p:: DummyirFFTPlan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_irfft! (x, p. n, p . region )
268
+ * (p:: DummyirFFTPlan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_irfft (x, p. n, p . region )
209
269
function mul! (C:: StridedVector , p:: DummyirFFTPlan , x:: StridedVector )
210
- C[:] = generic_irfft (x, p. n)
270
+ C[:] = generic_irfft (x, p. n, p . region )
211
271
C
212
272
end
213
- * (p:: DummybrFFTPlan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_brfft! (x, p. n)
214
- * (p:: DummybrFFTPlan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_brfft (x, p. n)
273
+ * (p:: DummybrFFTPlan{T,true} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_brfft! (x, p. n, p . region )
274
+ * (p:: DummybrFFTPlan{T,false} , x:: StridedArray{T,N} ) where {T<: AbstractFloats ,N} = generic_brfft (x, p. n, p . region )
215
275
function mul! (C:: StridedVector , p:: DummybrFFTPlan , x:: StridedVector )
216
- C[:] = generic_brfft (x, p. n)
276
+ C[:] = generic_brfft (x, p. n, p . region )
217
277
C
218
278
end
219
279
@@ -233,27 +293,27 @@ AbstractFFTs._fftfloat(::Type{T}) where {T <: AbstractFloat} = T
233
293
# This is the reason for using StridedArray below. We also have to carefully
234
294
# distinguish between real and complex arguments.
235
295
236
- plan_fft (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummyFFTPlan {Complex{real(T)},false} ( )
237
- plan_fft! (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummyFFTPlan {Complex{real(T)},true} ( )
296
+ plan_fft (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummyFFTPlan {Complex{real(T)},false,typeof(region)} (region )
297
+ plan_fft! (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummyFFTPlan {Complex{real(T)},true,typeof(region)} (region )
238
298
239
- plan_bfft (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummybFFTPlan {Complex{real(T)},false} ( )
240
- plan_bfft! (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummybFFTPlan {Complex{real(T)},true} ( )
299
+ plan_bfft (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummybFFTPlan {Complex{real(T)},false,typeof(region)} (region )
300
+ plan_bfft! (x:: StridedArray{T} , region) where {T <: ComplexFloats } = DummybFFTPlan {Complex{real(T)},true,typeof(region)} (region )
241
301
242
302
# The ifft plans are automatically provided in terms of the bfft plans above.
243
- # plan_ifft(x::StridedArray{T}, region) where {T <: ComplexFloats} = DummyiFFTPlan{Complex{real(T)},false}( )
244
- # plan_ifft!(x::StridedArray{T}, region) where {T <: ComplexFloats} = DummyiFFTPlan{Complex{real(T)},true}( )
303
+ # plan_ifft(x::StridedArray{T}, region) where {T <: ComplexFloats} = DummyiFFTPlan{Complex{real(T)},false,typeof(region)}(region )
304
+ # plan_ifft!(x::StridedArray{T}, region) where {T <: ComplexFloats} = DummyiFFTPlan{Complex{real(T)},true,typeof(region)}(region )
245
305
246
- plan_dct (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyDCTPlan {T,false} ( )
247
- plan_dct! (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyDCTPlan {T,true} ( )
306
+ plan_dct (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyDCTPlan {T,false,typeof(region)} (region )
307
+ plan_dct! (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyDCTPlan {T,true,typeof(region)} (region )
248
308
249
- plan_idct (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyiDCTPlan {T,false} ( )
250
- plan_idct! (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyiDCTPlan {T,true} ( )
309
+ plan_idct (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyiDCTPlan {T,false,typeof(region)} (region )
310
+ plan_idct! (x:: StridedArray{T} , region) where {T <: AbstractFloats } = DummyiDCTPlan {T,true,typeof(region)} (region )
251
311
252
- plan_rfft (x:: StridedArray{T} , region) where {T <: RealFloats } = DummyrFFTPlan {Complex{real(T)},false} (length (x))
253
- plan_brfft (x:: StridedArray{T} , n:: Integer , region) where {T <: ComplexFloats } = DummybrFFTPlan {Complex{real(T)},false} (n)
312
+ plan_rfft (x:: StridedArray{T} , region) where {T <: RealFloats } = DummyrFFTPlan {Complex{real(T)},false,typeof(region) } (length (x), region )
313
+ plan_brfft (x:: StridedArray{T} , n:: Integer , region) where {T <: ComplexFloats } = DummybrFFTPlan {Complex{real(T)},false,typeof(region) } (n, region )
254
314
255
315
# A plan for irfft is created in terms of a plan for brfft.
256
- # plan_irfft(x::StridedArray{T}, n::Integer, region) where {T <: ComplexFloats} = DummyirFFTPlan{Complex{real(T)},false}(n)
316
+ # plan_irfft(x::StridedArray{T}, n::Integer, region) where {T <: ComplexFloats} = DummyirFFTPlan{Complex{real(T)},false,typeof(region) }(n, region )
257
317
258
318
# These don't exist for now:
259
319
# plan_rfft!(x::StridedArray{T}) where {T <: RealFloats} = DummyrFFTPlan{Complex{real(T)},true}()
0 commit comments