4

What is the easiest and fastest way (with some library, of course) to compute k largest eigenvalues and eigenvectors for a large dense matrix in C++? I'm looking for an equivalent of MATLAB's eigs function; I've looked through Armadillo and Eigen but couldn't find one, and computing all eigenvalues takes forever in my case (I need top 10 eigenvectors for an approx. 30000x30000 dense non-symmetric real matrix).

Desperate, I've even tried to implement power iterations by myself with Armadillo's QR decomposition but ran into complex pairs of eigenvalues and gave up. :)

snikolenko
  • 135
  • 1
  • 2
  • 6

4 Answers4

4

Did you tried https://github.com/yixuan/spectra ? It similar to ARPACK but with nice Eigen-like interface (it compatible with Eigen!)

I used it for 30kx30k matrices (PCA) and it was quite ok

Daiver
  • 1,488
  • 3
  • 18
  • 47
  • 3
    Just tried this myself in my app that uses Eigen for all linear algebra related things and this is super convenient: header only (like Eigen) so no build issues, just #include + 4 lines of code and I have my eigenvalues, input and output in Eigen format, and much faster than my own implementation of Lanczos' iteration, 100 eigenvalues (highest or smallest by choice) in 80k x 80k sparse matrix in a few seconds. – tomj Apr 06 '17 at 15:35
2

AFAIK the problem of finding the first k eigenvalues of a generic matrix has no easy solution. The Matlab function eigs you mentioned is supposed to work with sparse matrices.

Matlab probably uses Arnoldi/Lanczos, you might try if it works decently in your case even if your matrix is not sparse. The reference package for Arnlodi is ARPACK which has a C++ interface.

sbabbi
  • 11,070
  • 2
  • 29
  • 57
  • I'm not sure which algorithms it uses, but Matlab's `eigs` does work radically faster than finding all eigenvalues for a large dense matrix. – snikolenko Jun 28 '14 at 16:52
  • `eigs` uses Arnoldi, which is designed to output the first `k` larger eigenvalues. Whether faster or slower than finding all the eigenvalues depends on how big is your `k`. – sbabbi Jun 28 '14 at 17:57
  • 1
    Thank you! Arpack does not have the most friendly interface in the world, but it worked. 4m20s on a problem of my size (10 eigenvectors for a matrix of size 30K x 30K) is excellent. – snikolenko Jun 28 '14 at 19:01
1

Here is how I get the k largest eigenvectors of a NxN real-valued (float), dense, symmetric matrix A in C++ Eigen:

#include <Eigen/Dense>
...
Eigen::MatrixXf A(N,N);
...
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> solver(N);
solver.compute(A);
Eigen::VectorXf lambda = solver.eigenvalues().reverse();
Eigen::MatrixXf X = solver.eigenvectors().block(0,N-k,N,k).rowwise().reverse();

Note that the eigenvalues and associated eigenvectors are returned in ascending order so I reverse them to get the largest values first.

If you want eigenvalues and eigenvectors for other (non-symmetric) matrices they will, in general, be complex and you will need to use the Eigen::EigenSolver class instead.

wcochran
  • 10,089
  • 6
  • 61
  • 69
0

Eigen has an EigenValues module that works pretty well.. But, I've never used it on anything quite that large.

Yeraze
  • 3,269
  • 4
  • 28
  • 42
  • Yes, but I couldn't find anything there that computes top `k` eigenvalues. Finding all eigenvalues would be very slow. – snikolenko Jun 28 '14 at 17:00
  • I see some example functions [here](http://forum.kde.org/viewtopic.php?f=74&t=108033) that compute the dominant Eigenvalue/vector. – Yeraze Jun 28 '14 at 18:27