Skip to content

Commit 0752928

Browse files
committed
Rename all fft routines to generic_fft
1 parent c00b38b commit 0752928

File tree

1 file changed

+57
-45
lines changed

1 file changed

+57
-45
lines changed

src/fftBigFloat.jl

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,37 @@ 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<:AbstractFloats
16+
17+
function generic_fft(x::Vector{T}) where T<:AbstractFloats
1718
n = length(x)
18-
ispow2(n) && return fft_pow2(x)
19+
ispow2(n) && return generic_fft_pow2(x)
1920
ks = range(zero(real(T)),stop=n-one(real(T)),length=n)
2021
Wks = exp.((-im).*convert(T,π).*ks.^2 ./ n)
2122
xq, wq = x.*Wks, conj([exp(-im*convert(T,π)*n);reverse(Wks);Wks[2:end]])
2223
return Wks.*conv(xq,wq)[n+1:2n]
2324
end
2425

2526

26-
function fft!(x::Vector{T}) where T<:AbstractFloats
27-
x[:] = fft(x)
27+
function generic_fft!(x::Vector{T}) where T<:AbstractFloats
28+
x[:] = generic_fft(x)
2829
return x
2930
end
3031

3132
# add rfft for AbstractFloat, by calling fft
3233
# this creates ToeplitzMatrices.rfft, so avoids changing rfft
3334

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
35+
generic_rfft(v::Vector{T}) where T<:AbstractFloats = fft(v)[1:div(length(v),2)+1]
36+
function generic_irfft(v::Vector{T},n::Integer) where T<:AbstractFloats
3637
@assert n==2length(v)-1
3738
r = Vector{Complex{real(T)}}(undef, n)
3839
r[1:length(v)]=v
3940
r[length(v)+1:end]=reverse(conj(v[2:end]))
40-
real(ifft(r))
41+
real(generic_ifft(r))
4142
end
4243

43-
ifft(x::Vector{T}) where {T<:AbstractFloats} = conj!(fft(conj(x)))/length(x)
44-
function ifft!(x::Vector{T}) where T<:AbstractFloats
45-
x[:] = ifft(x)
44+
generic_ifft(x::Vector{T}) where {T<:AbstractFloats} = conj!(generic_fft(conj(x)))/length(x)
45+
function generic_ifft!(x::Vector{T}) where T<:AbstractFloats
46+
x[:] = generic_ifft(x)
4647
return x
4748
end
4849

@@ -51,7 +52,7 @@ function conv(u::StridedVector{T}, v::StridedVector{T}) where T<:AbstractFloats
5152
n = nu + nv - 1
5253
np2 = nextpow(2,n)
5354
append!(u,zeros(T,np2-nu)),append!(v,zeros(T,np2-nv))
54-
y = ifft_pow2(fft_pow2(u).*fft_pow2(v))
55+
y = generic_ifft_pow2(generic_fft_pow2(u).*generic_fft_pow2(v))
5556
#TODO This would not handle Dual/ComplexDual numbers correctly
5657
y = T<:Real ? real(y[1:n]) : y[1:n]
5758
end
@@ -60,7 +61,7 @@ end
6061
# c_radix2.c in the GNU Scientific Library and four1 in the Numerical Recipes in C.
6162
# However, the trigonometric recurrence is improved for greater efficiency.
6263
# The algorithm starts with bit-reversal, then divides and conquers in-place.
63-
function fft_pow2!(x::Vector{T}) where T<:AbstractFloat
64+
function generic_fft_pow2!(x::Vector{T}) where T<:AbstractFloat
6465
n,big2=length(x),2one(T)
6566
nn,j=n÷2,1
6667
for i=1:2:n-1
@@ -96,32 +97,32 @@ function fft_pow2!(x::Vector{T}) where T<:AbstractFloat
9697
return x
9798
end
9899

99-
function fft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
100+
function generic_fft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
100101
y = interlace(real(x),imag(x))
101-
fft_pow2!(y)
102+
generic_fft_pow2!(y)
102103
return complex.(y[1:2:end],y[2:2:end])
103104
end
104-
fft_pow2(x::Vector{T}) where {T<:AbstractFloat} = fft_pow2(complex(x))
105+
generic_fft_pow2(x::Vector{T}) where {T<:AbstractFloat} = generic_fft_pow2(complex(x))
105106

106-
function ifft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
107+
function generic_ifft_pow2(x::Vector{Complex{T}}) where T<:AbstractFloat
107108
y = interlace(real(x),-imag(x))
108-
fft_pow2!(y)
109+
generic_fft_pow2!(y)
109110
return complex.(y[1:2:end],-y[2:2:end])/length(x)
110111
end
111112

112-
function dct(a::AbstractVector{Complex{T}}) where {T <: AbstractFloat}
113+
function generic_dct(a::AbstractVector{Complex{T}}) where {T <: AbstractFloat}
113114
N = length(a)
114115
twoN = convert(T,2) * N
115-
c = fft([a; flipdim(a,1)])
116+
c = generic_fft([a; flipdim(a,1)])
116117
d = c[1:N]
117118
d .*= exp.((-im*convert(T, pi)).*(0:N-1)./twoN)
118119
d[1] = d[1] / sqrt(convert(T, 2))
119120
lmul!(inv(sqrt(twoN)), d)
120121
end
121122

122-
dct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(dct(complex(a)))
123+
generic_dct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(generic_dct(complex(a)))
123124

124-
function idct(a::AbstractVector{Complex{T}}) where {T <: AbstractFloat}
125+
function generic_idct(a::AbstractVector{Complex{T}}) where {T <: AbstractFloat}
125126
N = length(a)
126127
twoN = convert(T,2)*N
127128
b = a * sqrt(twoN)
@@ -132,10 +133,18 @@ function idct(a::AbstractVector{Complex{T}}) where {T <: AbstractFloat}
132133
flipdim(c[1:N],1)
133134
end
134135

135-
idct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(idct(complex(a)))
136+
generic_idct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(generic_idct(complex(a)))
136137

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+
generic_dct!(a::AbstractArray{T}) where {T<:AbstractFloats} = (b = generic_dct(a); a[:] = b)
139+
generic_idct!(a::AbstractArray{T}) where {T<:AbstractFloats} = (b = generic_idct(a); a[:] = b)
140+
141+
for f in (:dct, :dct!, :idct, :idct!)
142+
pf = Symbol("plan_", f)
143+
@eval begin
144+
$f(x::AbstractArray{<:AbstractFloats}) = $pf(x) * x
145+
$f(x::AbstractArray{<:AbstractFloats}, region) = $pf(x, region) * x
146+
end
147+
end
139148

140149
# dummy plans
141150
struct DummyFFTPlan{T,inplace} <: Plan{T} end
@@ -155,39 +164,42 @@ for (Plan,iPlan) in ((:DummyFFTPlan,:DummyiFFTPlan),
155164
end
156165

157166

158-
for (Plan,ff,ff!) in ((:DummyFFTPlan,:fft,:fft!),
159-
(:DummyiFFTPlan,:ifft,:ifft!),
160-
(:DummyrFFTPlan,:rfft,:rfft!),
161-
(:DummyirFFTPlan,:irfft,:irfft!),
162-
(:DummyDCTPlan,:dct,:dct!),
163-
(:DummyiDCTPlan,:idct,:idct!))
167+
for (Plan,ff,ff!) in ((:DummyFFTPlan,:generic_fft,:generic_fft!),
168+
(:DummyiFFTPlan,:generic_ifft,:generic_ifft!),
169+
(:DummyrFFTPlan,:generic_rfft,:generic_rfft!),
170+
(:DummyirFFTPlan,:generic_irfft,:generic_irfft!),
171+
(:DummyDCTPlan,:generic_dct,:generic_dct!),
172+
(:DummyiDCTPlan,:generic_idct,:generic_idct!))
164173
@eval begin
165-
*(p::$Plan{T,true}, x::StridedArray{T,N}) where {T,N} = $ff!(x)
166-
*(p::$Plan{T,false}, x::StridedArray{T,N}) where {T,N} = $ff(x)
174+
*(p::$Plan{T,true}, x::StridedArray{T,N}) where {T<:AbstractFloats,N} = $ff!(x)
175+
*(p::$Plan{T,false}, x::StridedArray{T,N}) where {T<:AbstractFloats,N} = $ff(x)
167176
function LAmul!(C::StridedVector, p::$Plan, x::StridedVector)
168177
C[:] = $ff(x)
169178
C
170179
end
171180
end
172181
end
173182

183+
# We override these for AbstractFloat, so that conversion from reals to
184+
# complex numbers works for any AbstractFloat (instead of only BlasFloat's)
185+
AbstractFFTs.complexfloat(x::StridedArray{Complex{<:AbstractFloat}}) = x
186+
AbstractFFTs.realfloat(x::StridedArray{<:Real}) = x
187+
AbstractFFTs._fftfloat(::Type{T}) where {T <: AbstractFloat} = T
174188

175-
176-
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}()
189+
plan_fft!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyFFTPlan{Complex{real(T)},true}()
190+
plan_ifft!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiFFTPlan{Complex{real(T)},true}()
179191

180192
#plan_rfft!{T<:AbstractFloats}(x::Vector{T}) = DummyrFFTPlan{Complex{real(T)},true}()
181193
#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}()
184-
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}()
194+
plan_dct!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyDCTPlan{T,true}()
195+
plan_idct!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiDCTPlan{T,true}()
196+
197+
plan_fft(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyFFTPlan{Complex{real(T)},false}()
198+
plan_ifft(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiFFTPlan{Complex{real(T)},false}()
199+
plan_rfft(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyrFFTPlan{Complex{real(T)},false}()
200+
plan_irfft(x::StridedArray{T},n::Integer) where {T <: AbstractFloats} = DummyirFFTPlan{Complex{real(T)},false}()
201+
plan_dct(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyDCTPlan{T,false}()
202+
plan_idct(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiDCTPlan{T,false}()
191203

192204

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

0 commit comments

Comments
 (0)