Skip to content

eigvecs(A::Hermitian, eigvals) method? #1248

@stevengj

Description

@stevengj

Currently, we implement eigvecs(A, eigvals) only for real SymTridiagonal matrices, but it would be easy to extend this to Hermitian matrices via a Hessenberg factorization as explained in this discourse post

using LinearAlgebra
import LinearAlgebra: eigvecs, RealHermSymComplexHerm

function eigvecs(A::RealHermSymComplexHerm, eigvals::AbstractVector{<:Real})
    F = hessenberg(A) # transform to SymTridiagonal form
    X = eigvecs(F.H, eigvals)
    return F.Q * X    # transform eigvecs of F.H back to eigvecs of A
end

A quick benchmark with LinearAlgebra.BLAS.set_num_threads(1) shows that it is significantly faster than eigvecs(A) at computing a single eigenvector, for example (slightly faster than using eigen(A, k:k) if you already have the eigenvalues):

julia> A = hermitianpart!(randn(1000,1000));

julia> λ = @btime eigvals($A);
  69.372 ms (21 allocations: 7.99 MiB)

julia> Q = @btime eigvecs($A);
  212.195 ms (25 allocations: 23.25 MiB)

julia> Q[:,17]  @btime eigvecs($A, [λ[17]])
  54.133 ms (73 allocations: 7.99 MiB)
true

julia> @btime eigen($A, 17:17); # computing 17th eigvec and eigval by eigen
  58.106 ms (24 allocations: 15.62 MiB)

Since the implementation above is already working, it should be an easy PR for someone to add it with a test and updated documentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions