Skip to content

Why is the return type of eigen a Union? #1498

@albertomercurio

Description

@albertomercurio

Hello,

I see a small Union type when diagonalizing a matrix

julia> A = rand(10, 10);

julia> eigen(A);

julia> @code_warntype eigen(A)
MethodInstance for eigen(::Matrix{Float64})
  from eigen(A::AbstractMatrix{T}; permute, scale, sortby) where T @ LinearAlgebra ~/.julia/juliaup/julia-1.12.2+0.x64.linux.gnu/share/julia/stdlib/v1.12/LinearAlgebra/src/eigen.jl:238
Static Parameters
  T = Float64
Arguments
  #self#::Core.Const(LinearAlgebra.eigen)
  A::Matrix{Float64}
Body::Union{Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}, Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}}
1%1 = LinearAlgebra.:(var"#eigen#102")::Core.Const(LinearAlgebra.var"#eigen#102")
│   %2 = LinearAlgebra.eigsortby::Core.Const(LinearAlgebra.eigsortby)
│   %3 = (%1)(true, true, %2, #self#, A)::Union{Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}, Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}}
└──      return %3

I think this happens because it is checking if the matrix is Hermitian at runtime here

function _eigen(A::AbstractMatrix{T}; permute=true, scale=true, sortby=eigsortby) where {T}
isdiag(A) && return eigen(Diagonal{eigtype(T)}(diag(A)); sortby)
if ishermitian(A)
eigen!(eigencopy_oftype(Hermitian(A), eigtype(T)); sortby)
else
eigen!(eigencopy_oftype(A, eigtype(T)); permute, scale, sortby)
end
end

And this returns the Union type between real or complex numbers.

I was wondering if one should remove that check, and implement specific methods for Hermitian or Symmetric matrices. If so, I can do a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions