|
1 | | -const BigFloats = Union{BigFloat,Complex{BigFloat}} |
2 | | - |
3 | | -function fft(x::AbstractVector{F}) where F<:Fun |
4 | | - n,T = length(x),mapreduce(eltype,promote_type,x) |
| 1 | +function fft(x::AbstractVector{<:Fun}) |
| 2 | + n,T = length(x),mapreduce(cfstype,promote_type,x) |
5 | 3 | if ispow2(n) return fft_pow2(x) end |
6 | 4 | ks = range(zero(real(T)),stop=n-one(real(T)),length=n) |
7 | | - Wks = exp(-im*convert(T,π)*ks.^2/n) |
8 | | - xq,wq = x.*Wks,conj([exp(-im*convert(T,π)*n);reverse(Wks);Wks[2:end]]) |
9 | | - return Wks.*conv(xq,wq)[n+1:2n] |
| 5 | + Wks = cis.(-convert(T,π)/n .* ks.^2) |
| 6 | + xq,wq = x.*Wks,conj([cis(-convert(T,π)*n);reverse(Wks); @view Wks[2:end]]) |
| 7 | + return Wks.* @view conv(xq,wq)[n+1:2n] |
10 | 8 | end |
11 | 9 |
|
12 | | -ifft(x::AbstractVector{F}) where {F<:Fun} = conj(fft(conj(x)))/length(x) |
13 | | -function ifft!(x::AbstractVector{F}) where F<:Fun |
| 10 | +ifft(x::AbstractVector{<:Fun}) = conj(fft(conj(x)))/length(x) |
| 11 | +function ifft!(x::AbstractVector{<:Fun}) |
14 | 12 | y = conj(fft(conj(x)))/length(x) |
15 | | - x[:] = y |
| 13 | + x .= y |
16 | 14 | return x |
17 | 15 | end |
18 | 16 |
|
19 | | -function conv(u::StridedVector{F}, v::StridedVector) where F<:Fun |
| 17 | +nextpow2(n) = 2^ceil(Int, Base.log2(n)) |
| 18 | +function conv(u::StridedVector{<:Fun}, v::StridedVector) |
20 | 19 | nu,nv = length(u),length(v) |
21 | 20 | n = nu + nv - 1 |
22 | 21 | np2 = nextpow2(n) |
23 | 22 | pad!(u,np2),pad!(v,np2) |
24 | 23 | y = ifft_pow2(fft_pow2(u).*fft_pow2(v)) |
25 | 24 | #TODO This would not handle Dual/ComplexDual numbers correctly |
26 | 25 | T = promote_type(mapreduce(eltype,promote_type,u),mapreduce(eltype,promote_type,v)) |
27 | | - y = T<:Real ? real(y[1:n]) : y[1:n] |
| 26 | + y = T<:Real ? real(@view y[1:n]) : y[1:n] |
28 | 27 | end |
29 | 28 |
|
30 | 29 | ###################################################################### |
|
33 | 32 |
|
34 | 33 | # plan_fft for BigFloats (covers Laurent svfft) |
35 | 34 |
|
36 | | -plan_fft(x::Vector{F}) where {F<:Fun} = fft |
37 | | -plan_ifft(x::Vector{F}) where {F<:Fun} = ifft |
38 | | -plan_ifft!(x::Vector{F}) where {F<:Fun} = ifft |
| 35 | +plan_fft(x::Vector{<:Fun}) = fft |
| 36 | +plan_ifft(x::Vector{<:Fun}) = ifft |
| 37 | +plan_ifft!(x::Vector{<:Fun}) = ifft |
39 | 38 |
|
40 | 39 |
|
41 | 40 | # Fourier space plans for BigFloat |
|
0 commit comments