-
Notifications
You must be signed in to change notification settings - Fork 28
Description
The generalized eigenvalue decomposition is not implemented in GenericLinearAlgebra:
julia> using GenericLinearAlgebra, DoubleFloats, LinearAlgebra
julia> A = rand(Double64, 5, 5); B = rand(Double64, 5, 5);
julia> eigvals(A, B)
ERROR: MethodError: no method matching eigvals!(::Matrix{Double64}, ::Matrix{Double64})
I am working on a pull request to implement this. It is based on code kindly provided to me by @thijssteel, who did his PhD on the topic. It uses the single shift or double shift QZ algorithm. The PR currently implements eigvals(A, B)
:
julia> using GenericLinearAlgebra
julia> eigvals(A, B)
5-element Vector{Complex{Double64}}:
-7.55847194974678743120673992727391194 + 0.0im
-7.6691169090262111372117306819298531e-01 + 0.0im
9.77704965303924447091419817528601559e-03 - 6.82491740678931004263096986923651618e-01im
9.77704965303924447091419817528601559e-03 + 6.82491740678931004263096986923651618e-01im
2.67081937010893995823217172351462554 + 0.0im
The speed and accuracy of the implementation seem somewhat comparable to that of LinearAlgebra for Float64
:
julia> n = 150; A = rand(n, n); B = rand(n, n);
julia> @time v1 = eigvals(A, B);
0.014203 seconds (16 allocations: 411.875 KiB)
julia> @time v2 = GenericLinearAlgebra.generalized_eigvals(A, B);
0.017426 seconds (5.10 k allocations: 754.531 KiB)
julia> norm(abs.(v1)-abs.(v2)) # abs to account for different ordering of complex conjugate pairs
8.884694390317172e-13
Further improvements may be possible, as the code does not include any of the optimizations that @thijssteel worked on (and which are made available in recent versions of LAPACK).
I have a use case for generalized eigenvalues as part of the AAA algorithm for computing rational approximations. It would be nice if it works with GenericLinearAlgebra.