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

Complex valued expv! gives MethodError in some cases

Open Lazersmoke opened this issue 4 years ago • 1 comments

A = Diagonal(1 .* ones(ComplexF64,8))
b = ones(ComplexF64,8)

Ks = KrylovSubspace{ComplexF64,ComplexF64}(8,8)
arnoldi!(Ks,A,b) # After this like, Ks.H = [ 1 - epsilon + 0i ; epsilon + 0i ]
out = Vector{ComplexF64}(undef,8)
expv!(out,1.0,Ks) # Causes error

Since H[1:1,1] is hermitian, this branch goes through: https://github.com/SciML/ExponentialUtilities.jl/blob/5460b95594a9e23f418710e568db3a92d7bcfd26/src/krylov_phiv.jl#L82-L85 but the efficient eigen! for SymTridiagonal matrices only works for reals (see https://github.com/JuliaLang/julia/commit/fc4c69de3935206589d25c251f5423cee1601726) so you get this error:

ERROR: LoadError: MethodError: no method matching eigen!(::SymTridiagonal{ComplexF64, Vector{ComplexF64}})
Closest candidates are:
  eigen!(!Matched::SymTridiagonal{var"#s832", V} where {var"#s832"<:Union{Float32, Float64}, V<:AbstractVector{var"#s832"}}) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:280
  eigen!(!Matched::SymTridiagonal{var"#s832", V} where {var"#s832"<:Union{Float32, Float64}, V<:AbstractVector{var"#s832"}}, !Matched::UnitRange) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:283
  eigen!(!Matched::SymTridiagonal{var"#s832", V} where {var"#s832"<:Union{Float32, Float64}, V<:AbstractVector{var"#s832"}}, !Matched::Real, !Matched::Real) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:288
  ...

In the expv! code for complex t, there is this line: https://github.com/SciML/ExponentialUtilities.jl/blob/5460b95594a9e23f418710e568db3a92d7bcfd26/src/krylov_phiv.jl#L116 which just takes the real part to make it work, but this seems bad... how do you know the matrix is actually real?

Related: https://github.com/SciML/OrdinaryDiffEq.jl/issues/1447#issuecomment-878757049

Lazersmoke avatar Jul 13 '21 05:07 Lazersmoke

The MethodError is quite common in Julia when there is no specialized version of the code for that type so I'm not sure what you want instead. Somtimes it is better to throw an error than give wrong results or slow computations.

For the expv!-case, can you construct an MWE?

jarlebring avatar Aug 24 '21 07:08 jarlebring