PaddedViews.jl icon indicating copy to clipboard operation
PaddedViews.jl copied to clipboard

FFT support for ComplexFloat?`

Open AshtonSBradley opened this issue 5 years ago • 1 comments

I find I can

using FFTW, PaddedViews
a = reshape(1:9, 3, 3)
x = PaddedView(-1, a, (4, 5))
fft(x)

and get complex float array of the right size.

But if instead I try to use complex floats, I get a method error

a = reshape(1.:9., 3, 3) |> complex
x=PaddedView(-1., a, (4, 5))
fft(x)

I get a method error

ERROR: MethodError: no method matching plan_fft(::PaddedView{Complex{Float64},2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},Array{Complex{Float64},2}}, ::UnitRange{Int64})
Closest candidates are:
  plan_fft(::Union{DenseArray{T<:Union{Complex{Float32}, Complex{Float64}},N}, Base.ReinterpretArray{T<:Union{Complex{Float32}, Complex{Float64}},N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray}, Base.ReshapedArray{T<:Union{Complex{Float32}, Complex{Float64}},N,A,MI} where MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{Base.ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray}, SubArray{T<:Union{Complex{Float32}, Complex{Float64}},N,A,I,L} where L where I<:Tuple{Vararg{Union{Int64, AbstractRange{Int64}, Base.AbstractCartesianIndex},N} where N} where A<:Union{Base.ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray} where N where T, Base.ReshapedArray{T,N,A,MI} where MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{Base.ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Union{Tuple{Vararg{Real,N} where N}, Tuple{AbstractUnitRange,Vararg{Any,N} where N}} where A<:DenseArray where N where T, DenseArray} where N where T, DenseArray}}, ::Any; flags, timelimit) where {T<:Union{Complex{Float32}, Complex{Float64}}, N} at /Users/abradley/.julia/packages/FFTW/MJ7kl/src/fft.jl:619
  plan_fft(::AbstractArray{#s16,N} where N where #s16<:Real, ::Any; kws...) at /Users/abradley/.julia/packages/AbstractFFTs/PUqOK/src/definitions.jl:199
  plan_fft(::AbstractArray{#s25,N} where N where #s25<:(Complex{#s26} where #s26<:Union{Integer, Rational}), ::Any; kws...) at /Users/abradley/.julia/packages/AbstractFFTs/PUqOK/src/definitions.jl:201
  ...
Stacktrace:
 [1] #plan_fft#1(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(plan_fft), ::PaddedView{Complex{Float64},2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},Array{Complex{Float64},2}}) at /Users/abradley/.julia/packages/AbstractFFTs/PUqOK/src/definitions.jl:52
 [2] plan_fft(::PaddedView{Complex{Float64},2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},Array{Complex{Float64},2}}) at /Users/abradley/.julia/packages/AbstractFFTs/PUqOK/src/definitions.jl:52
 [3] fft(::PaddedView{Complex{Float64},2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},Array{Complex{Float64},2}}) at /Users/abradley/.julia/packages/AbstractFFTs/PUqOK/src/definitions.jl:50
 [4] top-level scope at none:0

Is there anything fundamentally in the way here? It would be great to be able to pad before transforming as this simplifies many common operations such as convolution and some more specialised operations that turn up in quantum mechanics involving projections.

AshtonSBradley avatar Sep 25 '19 04:09 AshtonSBradley

Hm, quite an old issue, but a workaround is to collect before.

a = reshape(1.:9., 3, 3) |> complex
x=PaddedView(-1., a, (4, 5))
fft(collect(x))

I believe that FFTW.jl in the case when you provide the Padded Array with real inputs it anyways copies that to a complex one. When it is already complex, it tries to work with that, which fails since the underlying FFTW library cannot handle this datatype

roflmaostc avatar May 19 '21 12:05 roflmaostc