1
1
@enum Direction FFT_FORWARD FFT_BACKWARD
2
2
abstract type AbstractFFTType end
3
3
4
+ function alternatingSum (x:: AbstractVector{T} ) where T
5
+ y = x[1 ]
6
+ @turbo for i in 2 : length (x)
7
+ y += (x[i] * convert (T,(2 * (i % 2 ) - 1 )))
8
+ end
9
+ y
10
+ end
11
+
4
12
# Represents a Composite Cooley-Tukey FFT
5
13
struct CompositeFFT <: AbstractFFTType end
6
14
@@ -104,6 +112,13 @@ function fft(x::AbstractVector{T}) where {T}
104
112
y
105
113
end
106
114
115
+ function fft (x:: AbstractVector{T} ) where {T <: Real }
116
+ y = similar (x, Complex{T})
117
+ g = CallGraph {Complex{T}} (length (x))
118
+ fft! (y, x, Val (FFT_FORWARD), g[1 ]. type, g, 1 )
119
+ y
120
+ end
121
+
107
122
function fft (x:: AbstractMatrix{T} ) where {T}
108
123
M,N = size (x)
109
124
y1 = similar (x)
@@ -277,11 +292,13 @@ function fft_pow2!(out::AbstractVector{Complex{T}}, in::AbstractVector{T}, ::Val
277
292
w1 = convert (Complex{T}, cispi (- 2 / N))
278
293
wj = one (Complex{T})
279
294
m = N ÷ 2
280
- for j in 2 : m
281
- out[j] = out[j] + wj* out[j+ m]
295
+ @turbo for j in 2 : m
296
+ out[j] = out[j] + wj* out[j+ m]
282
297
wj *= w1
283
298
end
284
- out[m+ 2 : end ] = conj .(out[m: - 1 : 2 ])
299
+ @turbo for j in 2 : m
300
+ out[m+ j] = conj (out[m- j+ 2 ])
301
+ end
285
302
end
286
303
287
304
"""
@@ -300,11 +317,11 @@ function fft_pow2!(out::AbstractVector{Complex{T}}, in::AbstractVector{T}, ::Val
300
317
w1 = convert (Complex{T}, cispi (2 / N))
301
318
wj = one (Complex{T})
302
319
m = N ÷ 2
303
- for j in 2 : m
304
- out[j] = out[j] + wj* out[j+ m]
320
+ @turbo for j in 2 : m
321
+ out[j] = out[j] + wj* out[j+ m]
322
+ out[m+ j] = conj (out[m- i+ 2 ])
305
323
wj *= w1
306
324
end
307
- out[m+ 2 : end ] = conj .(out[m: - 1 : 2 ])
308
325
end
309
326
310
327
function fft_dft! (out:: AbstractVector{T} , in:: AbstractVector{T} , :: Val{FFT_FORWARD} ) where {T}
@@ -360,38 +377,36 @@ end
360
377
function fft_dft! (out:: AbstractVector{Complex{T}} , in:: AbstractVector{T} , :: Val{FFT_FORWARD} ) where {T<: Real }
361
378
N = length (out)
362
379
halfN = N÷ 2
363
- wn² = wn = w = convert (T, cispi (- 2 / N))
364
- wn_1 = one (T)
380
+ wk = wkn = w = convert (Complex{T}, cispi (- 2 / N))
365
381
366
- out .= in[1 ]
382
+ out[ 2 : N] .= in[1 ]
367
383
out[1 ] = sum (in)
368
- iseven (N) && (out[halfN+ 1 ] = foldr (- ,in))
369
-
370
- wk = wn²;
371
- for d in 2 : halfN
372
- out[d] = in[d]* wk + out[d]
373
- for k in (d+ 1 ): halfN
374
- wk *= wn
375
- out[d] = in[k]* wk + out[d]
376
- out[k] = in[d]* wk + out[k]
384
+ iseven (N) && (out[halfN+ 1 ] = alternatingSum (in))
385
+
386
+ for d in 2 : halfN+ 1
387
+ tmp = in[1 ]
388
+ for k in 2 : N
389
+ tmp += wkn* in[k]
390
+ wkn *= wk
377
391
end
378
- wn_1 = wn
379
- wn *= w
380
- wn² *= (wn* wn_1)
381
- wk = wn²
392
+ out[d] = tmp
393
+ wk *= w
394
+ wkn = wk
395
+ end
396
+ @turbo for i in 0 : halfN- 1
397
+ out[N- i] = conj (out[halfN- i])
382
398
end
383
- out[(N- halfN+ 2 ): end ] .= conj .(out[halfN: - 1 : 2 ])
384
399
end
385
400
386
401
function fft_dft! (out:: AbstractVector{Complex{T}} , in:: AbstractVector{T} , :: Val{FFT_BACKWARD} ) where {T<: Real }
387
402
N = length (out)
388
403
halfN = N÷ 2
389
- wn² = wn = w = convert (T , cispi (2 / N))
404
+ wn² = wn = w = convert (Complex{T} , cispi (2 / N))
390
405
wn_1 = one (T)
391
406
392
407
out .= in[1 ]
393
408
out[1 ] = sum (in)
394
- iseven (N) && (out[halfN+ 1 ] = foldr ( - , in))
409
+ iseven (N) && (out[halfN+ 1 ] = alternatingSum ( in))
395
410
396
411
wk = wn²;
397
412
for d in 2 : halfN
@@ -410,10 +425,10 @@ function fft_dft!(out::AbstractVector{Complex{T}}, in::AbstractVector{T}, ::Val{
410
425
end
411
426
412
427
413
- function fft! (out:: AbstractVector{T} , in:: AbstractVector{T } , :: Val{FFT_FORWARD} , :: DFT , :: CallGraph{T} , :: Int ) where {T}
428
+ function fft! (out:: AbstractVector{T} , in:: AbstractVector{U } , :: Val{FFT_FORWARD} , :: DFT , :: CallGraph{T} , :: Int ) where {T,U }
414
429
fft_dft! (out, in, Val (FFT_FORWARD))
415
430
end
416
431
417
- function fft! (out:: AbstractVector{T} , in:: AbstractVector{T } , :: Val{FFT_BACKWARD} , :: DFT , :: CallGraph{T} , :: Int ) where {T}
432
+ function fft! (out:: AbstractVector{T} , in:: AbstractVector{U } , :: Val{FFT_BACKWARD} , :: DFT , :: CallGraph{T} , :: Int ) where {T,U }
418
433
fft_dft! (out, in, Val (FFT_BACKWARD))
419
434
end
0 commit comments