Skip to content

Commit bfec169

Browse files
committed
Improve rfft and irfft
1 parent 0752928 commit bfec169

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

src/fftBigFloat.jl

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ if VERSION < v"0.7-"
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, ifft!, dct, idct, dct!, idct!,
9-
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
10-
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
8+
import FFTW: dct, dct!, idct, idct!,
9+
plan_fft!, plan_ifft!, plan_dct!, plan_idct!,
10+
plan_fft, plan_ifft, plan_rfft, plan_irfft, plan_dct, plan_idct
1111
import DSP: conv
1212
end
1313

@@ -32,7 +32,8 @@ end
3232
# add rfft for AbstractFloat, by calling fft
3333
# this creates ToeplitzMatrices.rfft, so avoids changing rfft
3434

35-
generic_rfft(v::Vector{T}) where T<:AbstractFloats = fft(v)[1:div(length(v),2)+1]
35+
generic_rfft(v::Vector{T}) where T<:AbstractFloats = generic_fft(v)[1:div(length(v),2)+1]
36+
3637
function generic_irfft(v::Vector{T},n::Integer) where T<:AbstractFloats
3738
@assert n==2length(v)-1
3839
r = Vector{Complex{real(T)}}(undef, n)
@@ -138,6 +139,8 @@ generic_idct(a::AbstractArray{T}) where {T <: AbstractFloat} = real(generic_idct
138139
generic_dct!(a::AbstractArray{T}) where {T<:AbstractFloats} = (b = generic_dct(a); a[:] = b)
139140
generic_idct!(a::AbstractArray{T}) where {T<:AbstractFloats} = (b = generic_idct(a); a[:] = b)
140141

142+
# These lines mimick the corresponding ones in FFTW/src/dct.jl, but with
143+
# AbstractFloat rather than fftwNumber.
141144
for f in (:dct, :dct!, :idct, :idct!)
142145
pf = Symbol("plan_", f)
143146
@eval begin
@@ -149,25 +152,33 @@ end
149152
# dummy plans
150153
struct DummyFFTPlan{T,inplace} <: Plan{T} end
151154
struct DummyiFFTPlan{T,inplace} <: Plan{T} end
152-
struct DummyrFFTPlan{T,inplace} <: Plan{T} end
153-
struct DummyirFFTPlan{T,inplace} <: Plan{T} end
154155
struct DummyDCTPlan{T,inplace} <: Plan{T} end
155156
struct DummyiDCTPlan{T,inplace} <: Plan{T} end
157+
struct DummyrFFTPlan{T,inplace} <: Plan{T}
158+
n :: Integer
159+
end
160+
struct DummyirFFTPlan{T,inplace} <: Plan{T}
161+
n :: Integer
162+
end
156163

157164
for (Plan,iPlan) in ((:DummyFFTPlan,:DummyiFFTPlan),
158-
(:DummyrFFTPlan,:DummyirFFTPlan),
165+
# (:DummyrFFTPlan,:DummyirFFTPlan),
159166
(:DummyDCTPlan,:DummyiDCTPlan))
160167
@eval begin
161168
Base.inv(::$Plan{T,inplace}) where {T,inplace} = $iPlan{T,inplace}()
162169
Base.inv(::$iPlan{T,inplace}) where {T,inplace} = $Plan{T,inplace}()
163170
end
164171
end
165172

173+
# Specific for rfft and irfft:
174+
Base.inv(::DummyirFFTPlan{T,inplace}) where {T,inplace} = DummyrFFTPlan{T,Inplace}(p.n)
175+
Base.inv(::DummyrFFTPlan{T,inplace}) where {T,inplace} = DummyirFFTPlan{T,Inplace}(p.n)
176+
166177

167178
for (Plan,ff,ff!) in ((:DummyFFTPlan,:generic_fft,:generic_fft!),
168179
(:DummyiFFTPlan,:generic_ifft,:generic_ifft!),
169180
(:DummyrFFTPlan,:generic_rfft,:generic_rfft!),
170-
(:DummyirFFTPlan,:generic_irfft,:generic_irfft!),
181+
# (:DummyirFFTPlan,:generic_irfft,:generic_irfft!),
171182
(:DummyDCTPlan,:generic_dct,:generic_dct!),
172183
(:DummyiDCTPlan,:generic_idct,:generic_idct!))
173184
@eval begin
@@ -180,24 +191,34 @@ for (Plan,ff,ff!) in ((:DummyFFTPlan,:generic_fft,:generic_fft!),
180191
end
181192
end
182193

194+
# Specific for irfft:
195+
*(p::DummyirFFTPlan{T,true}, x::StridedArray{T,N}) where {T<:AbstractFloats,N} = generic_irfft!(x, p.n)
196+
*(p::DummyirFFTPlan{T,false}, x::StridedArray{T,N}) where {T<:AbstractFloats,N} = generic_irfft(x, p.n)
197+
function LAmul!(C::StridedVector, p::DummyirFFTPlan, x::StridedVector)
198+
C[:] = generic_irfft(x, p.n)
199+
C
200+
end
201+
183202
# We override these for AbstractFloat, so that conversion from reals to
184203
# complex numbers works for any AbstractFloat (instead of only BlasFloat's)
185204
AbstractFFTs.complexfloat(x::StridedArray{Complex{<:AbstractFloat}}) = x
186205
AbstractFFTs.realfloat(x::StridedArray{<:Real}) = x
206+
# We override this one in order to avoid throwing an error that the type is
207+
# unsupported (as defined in AbstractFFTs)
187208
AbstractFFTs._fftfloat(::Type{T}) where {T <: AbstractFloat} = T
188209

189210
plan_fft!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyFFTPlan{Complex{real(T)},true}()
190211
plan_ifft!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiFFTPlan{Complex{real(T)},true}()
191212

192-
#plan_rfft!{T<:AbstractFloats}(x::Vector{T}) = DummyrFFTPlan{Complex{real(T)},true}()
193-
#plan_irfft!{T<:AbstractFloats}(x::Vector{T},n::Integer) = DummyirFFTPlan{Complex{real(T)},true}()
213+
# plan_rfft!(x::StridedArray{T}) where {T <: AbstractFloat} = DummyrFFTPlan{Complex{real(T)},true}()
214+
# plan_irfft!(x::StridedArray{T},n::Integer) where {T <: AbstractFloat} = DummyirFFTPlan{Complex{real(T)},true}()
194215
plan_dct!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyDCTPlan{T,true}()
195216
plan_idct!(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiDCTPlan{T,true}()
196217

197218
plan_fft(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyFFTPlan{Complex{real(T)},false}()
198219
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}()
220+
plan_rfft(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyrFFTPlan{Complex{real(T)},false}(length(x))
221+
plan_irfft(x::StridedArray{T}, n::Integer, region) where {T <: AbstractFloats} = DummyirFFTPlan{Complex{real(T)},false}(n)
201222
plan_dct(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyDCTPlan{T,false}()
202223
plan_idct(x::StridedArray{T}, region) where {T <: AbstractFloats} = DummyiDCTPlan{T,false}()
203224

test/fftBigFloattests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ end
1414
@test norm(ifft(fft(c))-c) < 200norm(c)eps(BigFloat)
1515

1616
p = plan_dct(c)
17-
@test norm(dct(c) - p*c) == 0
17+
@test norm(FastTransforms.generic_dct(c) - p*c) == 0
1818

1919
pi = plan_idct!(c)
2020
@test norm(pi*dct(c) - c) < 1000norm(c)*eps(BigFloat)

0 commit comments

Comments
 (0)