5

Is there an distinct and effective way of finding eigenvalues and eigenvectors of a real, symmetrical, very large, let's say 10000x10000, sparse matrix in Eigen3? There is an eigenvalue solver for dense matrices but that doesn't make use of the property of the matrix e.g. it's symmetry. Furthermore I don't want to store the matrix in dense.

Or (alternative) is there a better (+better documented) library to do that?

Philipp
  • 159
  • 1
  • 9

2 Answers2

5

For Eigen, there's a library named Spectra. As is described on its web page, Spectra is a redesign of the ARPACK library using C++ language.

Unlike Armadillo, suggested in another answer, Spectra does support long double and any other real floating-point type (e.g. boost::multiprecision::float128).

Here's an example of usage (same as the version in documentation, but adapted for experiments with different floating-point types):

#include <Eigen/Core>
#include <SymEigsSolver.h>  // Also includes <MatOp/DenseSymMatProd.h>
#include <iostream>
#include <limits>

int main()
{
    using Real=long double;
    using Matrix=Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>;

    // We are going to calculate the eigenvalues of M
    const auto A = Matrix::Random(10, 10);
    const Matrix M = A + A.transpose();

    // Construct matrix operation object using the wrapper class DenseGenMatProd
    Spectra::DenseSymMatProd<Real> op(M);

    // Construct eigen solver object, requesting the largest three eigenvalues
    Spectra::SymEigsSolver<Real,
                           Spectra::LARGEST_ALGE,
                           Spectra::DenseSymMatProd<Real>> eigs(&op, 3, 6);

    // Initialize and compute
    eigs.init();
    const auto nconv = eigs.compute();
    std::cout << nconv << " eigenvalues converged.\n";

    // Retrieve results
    if(eigs.info() == Spectra::SUCCESSFUL)
    {
        const auto evalues = eigs.eigenvalues();
        std::cout.precision(std::numeric_limits<Real>::digits10);
        std::cout << "Eigenvalues found:\n" << evalues << '\n';
    }
}
Ruslan
  • 18,162
  • 8
  • 67
  • 136
4

Armadillo will do this using eigs_sym

Note that computing all the eigenvalues is a very expensive operation whatever you do, usually what is done is to find only the k largest, or smallest eigenvalues (which is what this will do).

Simon Gibbons
  • 6,969
  • 1
  • 21
  • 34
  • This is exactly what i was looking for and in addition it seems to be a fast library. As this is an answer to my question i will mark it as accepted, but do you have experience using Eigen for that kind of task? – Philipp May 12 '15 at 16:26
  • No personal experience using Eigen for these kinds of things I'm afraid. I tend to use armadillo pretty much exclusively for linear algebra in c++. From a quick glance over the docs it didn't look to me there would be any other way of doing what you wanted without hand coding something using a QR decomposition with sparse matrices. – Simon Gibbons May 12 '15 at 17:57