1
- const BigFloats = Union{BigFloat ,Complex{BigFloat} }
1
+ const AbstractFloats = Union{AbstractFloat ,Complex{T} where T <: AbstractFloat }
2
2
3
3
if VERSION < v " 0.7-"
4
- import Base. FFTW: fft, fft!, rfft, irfft, ifft, conv, dct, idct, dct!, idct!,
4
+ import Base. FFTW: fft, fft!, rfft, irfft, ifft, ifft!, conv, dct, idct, dct!, idct!,
5
5
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
6
6
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
7
7
else
8
- import FFTW: fft, fft!, rfft, irfft, ifft, dct, idct, dct!, idct!,
8
+ import FFTW: fft, fft!, rfft, irfft, ifft, ifft!, dct, idct, dct!, idct!,
9
9
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
10
10
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
11
11
import DSP: conv
12
12
end
13
13
14
14
# The following implements Bluestein's algorithm, following http://www.dsprelated.com/dspbooks/mdft/Bluestein_s_FFT_Algorithm.html
15
15
# To add more types, add them in the union of the function's signature.
16
- function fft (x:: Vector{T} ) where T<: BigFloats
16
+ function fft (x:: Vector{T} ) where T<: AbstractFloats
17
17
n = length (x)
18
18
ispow2 (n) && return fft_pow2 (x)
19
19
ks = range (zero (real (T)),stop= n- one (real (T)),length= n)
@@ -23,30 +23,30 @@ function fft(x::Vector{T}) where T<:BigFloats
23
23
end
24
24
25
25
26
- function fft! (x:: Vector{T} ) where T<: BigFloats
26
+ function fft! (x:: Vector{T} ) where T<: AbstractFloats
27
27
x[:] = fft (x)
28
28
return x
29
29
end
30
30
31
- # add rfft for BigFloat , by calling fft
31
+ # add rfft for AbstractFloat , by calling fft
32
32
# this creates ToeplitzMatrices.rfft, so avoids changing rfft
33
33
34
- rfft (v:: Vector{T} ) where T<: BigFloats = fft (v)[1 : div (length (v),2 )+ 1 ]
35
- function irfft (v:: Vector{T} ,n:: Integer ) where T<: BigFloats
34
+ rfft (v:: Vector{T} ) where T<: AbstractFloats = fft (v)[1 : div (length (v),2 )+ 1 ]
35
+ function irfft (v:: Vector{T} ,n:: Integer ) where T<: AbstractFloats
36
36
@assert n== 2 length (v)- 1
37
- r = Vector {Complex{BigFloat }} (undef, n)
37
+ r = Vector {Complex{real(T) }} (undef, n)
38
38
r[1 : length (v)]= v
39
39
r[length (v)+ 1 : end ]= reverse (conj (v[2 : end ]))
40
40
real (ifft (r))
41
41
end
42
42
43
- ifft (x:: Vector{T} ) where {T<: BigFloats } = conj! (fft (conj (x)))/ length (x)
44
- function ifft! (x:: Vector{T} ) where T<: BigFloats
43
+ ifft (x:: Vector{T} ) where {T<: AbstractFloats } = conj! (fft (conj (x)))/ length (x)
44
+ function ifft! (x:: Vector{T} ) where T<: AbstractFloats
45
45
x[:] = ifft (x)
46
46
return x
47
47
end
48
48
49
- function conv (u:: StridedVector{T} , v:: StridedVector{T} ) where T<: BigFloats
49
+ function conv (u:: StridedVector{T} , v:: StridedVector{T} ) where T<: AbstractFloats
50
50
nu,nv = length (u),length (v)
51
51
n = nu + nv - 1
52
52
np2 = nextpow (2 ,n)
60
60
# c_radix2.c in the GNU Scientific Library and four1 in the Numerical Recipes in C.
61
61
# However, the trigonometric recurrence is improved for greater efficiency.
62
62
# The algorithm starts with bit-reversal, then divides and conquers in-place.
63
- function fft_pow2! (x:: Vector{T} ) where T<: BigFloat
63
+ function fft_pow2! (x:: Vector{T} ) where T<: AbstractFloat
64
64
n,big2= length (x),2 one (T)
65
65
nn,j= n÷ 2 ,1
66
66
for i= 1 : 2 : n- 1
@@ -96,45 +96,46 @@ function fft_pow2!(x::Vector{T}) where T<:BigFloat
96
96
return x
97
97
end
98
98
99
- function fft_pow2 (x:: Vector{Complex{T}} ) where T<: BigFloat
99
+ function fft_pow2 (x:: Vector{Complex{T}} ) where T<: AbstractFloat
100
100
y = interlace (real (x),imag (x))
101
101
fft_pow2! (y)
102
102
return complex .(y[1 : 2 : end ],y[2 : 2 : end ])
103
103
end
104
- fft_pow2 (x:: Vector{T} ) where {T<: BigFloat } = fft_pow2 (complex (x))
104
+ fft_pow2 (x:: Vector{T} ) where {T<: AbstractFloat } = fft_pow2 (complex (x))
105
105
106
- function ifft_pow2 (x:: Vector{Complex{T}} ) where T<: BigFloat
106
+ function ifft_pow2 (x:: Vector{Complex{T}} ) where T<: AbstractFloat
107
107
y = interlace (real (x),- imag (x))
108
108
fft_pow2! (y)
109
109
return complex .(y[1 : 2 : end ],- y[2 : 2 : end ])/ length (x)
110
110
end
111
111
112
-
113
- function dct (a :: AbstractVector{Complex{BigFloat}} )
114
- N = big ( length (a))
112
+ function dct (a :: AbstractVector{Complex{T}} ) where {T <: AbstractFloat }
113
+ N = length (a )
114
+ twoN = convert (T, 2 ) * N
115
115
c = fft ([a; flipdim (a,1 )])
116
116
d = c[1 : N]
117
- d .*= exp .((- im* big ( pi )). * (0 : N- 1 ). / ( 2 * N) )
118
- d[1 ] = d[1 ] / sqrt (big ( 2 ))
119
- lmul! (inv (sqrt (2 N )), d)
117
+ d .*= exp .((- im* convert (T, pi )). * (0 : N- 1 ). / twoN )
118
+ d[1 ] = d[1 ] / sqrt (convert (T, 2 ))
119
+ lmul! (inv (sqrt (twoN )), d)
120
120
end
121
121
122
- dct (a:: AbstractArray{BigFloat} ) = real (dct (complex (a)))
122
+ dct (a:: AbstractArray{T} ) where {T <: AbstractFloat } = real (dct (complex (a)))
123
123
124
- function idct (a:: AbstractVector{Complex{BigFloat}} )
125
- N = big (length (a))
126
- b = a * sqrt (2 * N)
127
- b[1 ] = b[1 ] * sqrt (big (2 ))
128
- shift = exp .(- im * 2 * big (pi ) * (N - big (1 )/ 2 ) * (0 : (2 N- 1 )) / (2 * N))
124
+ function idct (a:: AbstractVector{Complex{T}} ) where {T <: AbstractFloat }
125
+ N = length (a)
126
+ twoN = convert (T,2 )* N
127
+ b = a * sqrt (twoN)
128
+ b[1 ] = b[1 ] * sqrt (convert (T,2 ))
129
+ shift = exp .(- im * 2 * convert (T, pi ) * (N - convert (T,1 )/ 2 ) * (0 : (2 N- 1 )) / twoN)
129
130
b = [b; 0 ; - flipdim (b[2 : end ],1 )] .* shift
130
131
c = ifft (b)
131
132
flipdim (c[1 : N],1 )
132
133
end
133
134
134
- idct (a:: AbstractArray{BigFloat} ) = real (idct (complex (a)))
135
+ idct (a:: AbstractArray{T} ) where {T <: AbstractFloat } = real (idct (complex (a)))
135
136
136
- dct! (a:: AbstractArray{T} ) where {T<: BigFloats } = (b = dct (a); a[:] = b)
137
- idct! (a:: AbstractArray{T} ) where {T<: BigFloats } = (b = idct (a); a[:] = b)
137
+ dct! (a:: AbstractArray{T} ) where {T<: AbstractFloats } = (b = dct (a); a[:] = b)
138
+ idct! (a:: AbstractArray{T} ) where {T<: AbstractFloats } = (b = idct (a); a[:] = b)
138
139
139
140
# dummy plans
140
141
struct DummyFFTPlan{T,inplace} <: Plan{T} end
@@ -173,20 +174,20 @@ end
173
174
174
175
175
176
176
- plan_fft! (x:: Vector{T} ) where {T<: BigFloats } = DummyFFTPlan {Complex{BigFloat },true} ()
177
- plan_ifft! (x:: Vector{T} ) where {T<: BigFloats } = DummyiFFTPlan {Complex{BigFloat },true} ()
177
+ plan_fft! (x:: Vector{T} ) where {T<: AbstractFloats } = DummyFFTPlan {Complex{real(T) },true} ()
178
+ plan_ifft! (x:: Vector{T} ) where {T<: AbstractFloats } = DummyiFFTPlan {Complex{real(T) },true} ()
178
179
179
- # plan_rfft!{T<:BigFloats }(x::Vector{T}) = DummyrFFTPlan{Complex{BigFloat },true}()
180
- # plan_irfft!{T<:BigFloats }(x::Vector{T},n::Integer) = DummyirFFTPlan{Complex{BigFloat },true}()
181
- plan_dct! (x:: Vector{T} ) where {T<: BigFloats } = DummyDCTPlan {T,true} ()
182
- plan_idct! (x:: Vector{T} ) where {T<: BigFloats } = DummyiDCTPlan {T,true} ()
180
+ # plan_rfft!{T<:AbstractFloats }(x::Vector{T}) = DummyrFFTPlan{Complex{real(T) },true}()
181
+ # plan_irfft!{T<:AbstractFloats }(x::Vector{T},n::Integer) = DummyirFFTPlan{Complex{real(T) },true}()
182
+ plan_dct! (x:: Vector{T} ) where {T<: AbstractFloats } = DummyDCTPlan {T,true} ()
183
+ plan_idct! (x:: Vector{T} ) where {T<: AbstractFloats } = DummyiDCTPlan {T,true} ()
183
184
184
- plan_fft (x:: Vector{T} ) where {T<: BigFloats } = DummyFFTPlan {Complex{BigFloat },false} ()
185
- plan_ifft (x:: Vector{T} ) where {T<: BigFloats } = DummyiFFTPlan {Complex{BigFloat },false} ()
186
- plan_rfft (x:: Vector{T} ) where {T<: BigFloats } = DummyrFFTPlan {Complex{BigFloat },false} ()
187
- plan_irfft (x:: Vector{T} ,n:: Integer ) where {T<: BigFloats } = DummyirFFTPlan {Complex{BigFloat },false} ()
188
- plan_dct (x:: Vector{T} ) where {T<: BigFloats } = DummyDCTPlan {T,false} ()
189
- plan_idct (x:: Vector{T} ) where {T<: BigFloats } = DummyiDCTPlan {T,false} ()
185
+ plan_fft (x:: Vector{T} ) where {T<: AbstractFloats } = DummyFFTPlan {Complex{real(T) },false} ()
186
+ plan_ifft (x:: Vector{T} ) where {T<: AbstractFloats } = DummyiFFTPlan {Complex{real(T) },false} ()
187
+ plan_rfft (x:: Vector{T} ) where {T<: AbstractFloats } = DummyrFFTPlan {Complex{real(T) },false} ()
188
+ plan_irfft (x:: Vector{T} ,n:: Integer ) where {T<: AbstractFloats } = DummyirFFTPlan {Complex{real(T) },false} ()
189
+ plan_dct (x:: Vector{T} ) where {T<: AbstractFloats } = DummyDCTPlan {T,false} ()
190
+ plan_idct (x:: Vector{T} ) where {T<: AbstractFloats } = DummyiDCTPlan {T,false} ()
190
191
191
192
192
193
function interlace (a:: Vector{S} ,b:: Vector{V} ) where {S<: Number ,V<: Number }
0 commit comments