JuliaLinearAlgebra / ArnoldiMethod.jl

The Arnoldi Method with Krylov-Schur restart, natively in Julia.

Home Page:https://julialinearalgebra.github.io/ArnoldiMethod.jl/dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

partial_schur not respecting argument nev

jpfairbanks opened this issue · comments

commented

This is an unintuitive behavior for me given the way that eigs used to work.

julia> A = randn(100,21); A = A*A';

julia> schur_to_eigen(partial_schur(A, nev=8, which=LM())[1])[1]
9-element Array{Float64,1}:
 181.35175628108203
 174.42634344552079
 142.31044226550978
 132.80295154586017
 126.68141410737701
 121.75800101083811
 109.79068655370247
 104.68006588968174
 100.09676418940714

julia> schur_to_eigen(partial_schur(A, nev=12, which=LM())[1])[1]
21-element Array{Float64,1}:
 181.3517562810819
 174.42634344552076
 142.31044226550975
...

I expected partial_schur to return a schur decomposition of order exactly nev, or schur_to_eigen to take an argument of nev too.

You're right, it is a bit unintuitive. What happens is that multiple eigenvalues converge simultaneously, so that nev is rather a lower bound for the number of converged eigenvalues than an exact number; the upper bound would be max. And in fact this is sometimes desirable behaviour, for instance when you have a complex conjugate pair of eigenvalues, then you probably need both of them -- might exceed nev by 1 then.

But in case unwanted eigenvalues converge, it turns out there are numerical issues when removing them in the obvious way (losing a lot of precision in the other eigenvalues is what @NymanLauri and I observed). In ARPACK there is this concept of purging unwanted eigenvalues, but when I looked at it it seemed rather convoluted. It is in the todo list of #67 however!

The simplest solution is indeed to do some post-processing in this schur_to_eigen function. I'll try something soon!

commented

My use case only needs real eigenvalues, both LR for matrices with +/- (adjacency matrix) eigenvalues and SR for when they are all positive (Laplacian matrix). Can I just use nev=k and then sort and take the first k? I usually need the eigenvector too.

Yeah, so sortperm should work then. I think schur_to_eigen is type unstable btw, but that is on Julia's side (eigen is type-unstable). So maybe wrap the vector of eigenvalues in real(...) to be sure.

Closed via #81