Skip to content

Commit c00b38b

Browse files
committed
make fft more generic
1 parent c21bcbd commit c00b38b

File tree

1 file changed

+44
-43
lines changed

1 file changed

+44
-43
lines changed

src/fftBigFloat.jl

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
const BigFloats = Union{BigFloat,Complex{BigFloat}}
1+
const AbstractFloats = Union{AbstractFloat,Complex{T} where T<:AbstractFloat}
22

33
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!,
55
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
66
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
77
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!,
99
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
1010
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
1111
import DSP: conv
1212
end
1313

1414
# The following implements Bluestein's algorithm, following http://www.dsprelated.com/dspbooks/mdft/Bluestein_s_FFT_Algorithm.html
1515
# 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
1717
n = length(x)
1818
ispow2(n) && return fft_pow2(x)
1919
ks = range(zero(real(T)),stop=n-one(real(T)),length=n)
@@ -23,30 +23,30 @@ function fft(x::Vector{T}) where T<:BigFloats
2323
end
2424

2525

26-
function fft!(x::Vector{T}) where T<:BigFloats
26+
function fft!(x::Vector{T}) where T<:AbstractFloats
2727
x[:] = fft(x)
2828
return x
2929
end
3030

31-
# add rfft for BigFloat, by calling fft
31+
# add rfft for AbstractFloat, by calling fft
3232
# this creates ToeplitzMatrices.rfft, so avoids changing rfft
3333

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
3636
@assert n==2length(v)-1
37-
r = Vector{Complex{BigFloat}}(undef, n)
37+
r = Vector{Complex{real(T)}}(undef, n)
3838
r[1:length(v)]=v
3939
r[length(v)+1:end]=reverse(conj(v[2:end]))
4040
real(ifft(r))
4141
end
4242

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
4545
x[:] = ifft(x)
4646
return x
4747
end
4848

49-
function conv(u::StridedVector{T}, v::StridedVector{T}) where T<:BigFloats
49+
function conv(u::StridedVector{T}, v::StridedVector{T}) where T<:AbstractFloats
5050
nu,nv = length(u),length(v)
5151
n = nu + nv - 1
5252
np2 = nextpow(2,n)
@@ -60,7 +60,7 @@ end
6060
# c_radix2.c in the GNU Scientific Library and four1 in the Numerical Recipes in C.
6161
# However, the trigonometric recurrence is improved for greater efficiency.
6262
# 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
6464
n,big2=length(x),2one(T)
6565
nn,j=n÷2,1
6666
for i=1:2:n-1
@@ -96,45 +96,46 @@ function fft_pow2!(x::Vector{T}) where T<:BigFloat
9696
return x
9797
end
9898

99-
function fft_pow2(x::Vector{Complex{T}}) where T<:BigFloat
99+
function fft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
100100
y = interlace(real(x),imag(x))
101101
fft_pow2!(y)
102102
return complex.(y[1:2:end],y[2:2:end])
103103
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))
105105

106-
function ifft_pow2(x::Vector{Complex{T}}) where T<:BigFloat
106+
function ifft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
107107
y = interlace(real(x),-imag(x))
108108
fft_pow2!(y)
109109
return complex.(y[1:2:end],-y[2:2:end])/length(x)
110110
end
111111

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
115115
c = fft([a; flipdim(a,1)])
116116
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(2N)), 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)
120120
end
121121

122-
dct(a::AbstractArray{BigFloat}) = real(dct(complex(a)))
122+
dct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(dct(complex(a)))
123123

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:(2N-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:(2N-1)) / twoN)
129130
b = [b; 0; -flipdim(b[2:end],1)] .* shift
130131
c = ifft(b)
131132
flipdim(c[1:N],1)
132133
end
133134

134-
idct(a::AbstractArray{BigFloat}) = real(idct(complex(a)))
135+
idct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(idct(complex(a)))
135136

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)
138139

139140
# dummy plans
140141
struct DummyFFTPlan{T,inplace} <: Plan{T} end
@@ -173,20 +174,20 @@ end
173174

174175

175176

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}()
178179

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}()
183184

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}()
190191

191192

192193
function interlace(a::Vector{S},b::Vector{V}) where {S<:Number,V<:Number}

0 commit comments

Comments
 (0)