If kl is non-negative, returns the highest k and lowest kl eigenvalues,
with their corresponding eigenvectors. If kl is negative, returns the largest magnitude k
eigenvalues, with corresponding eigenvectors.
The routine implements Lanczos iteration with full re-orthogonalization as described in Demmel (1997). Lanczos
iteraction iteratively constructs a tridiagonal matrix, the eigenvalues of which converge to the eigenvalues of A,
as the iteration proceeds (most extreme first). Eigenvectors can also be computed. For small k and kl the
approach is faster than computing the full symmetric eigendecompostion. The tridiagonal eigenproblems are handled using LAPACK.
The implementation is not optimal: in particular the inner triadiagonal problems could be handled more efficiently, and
there would be some savings to be made by not always returning eigenvectors.