2015-05-12 39 views
5

Gibt es eine eindeutige und effektive Möglichkeit zum Finden von Eigenwerten und Eigenvektoren einer realen, symmetrischen, sehr großen, sagen wir 10000x10000, spärlich Matrix in Eigen3? Es gibt einen Eigenwertlöser für dichte Matrizen, der jedoch die Eigenschaft der Matrix, z. es ist Symmetrie. Außerdem möchte ich die Matrix nicht in dicht lagern.Sparse Eigenwerte mit Eigen3/Sparse

Oder (Alternative) gibt es eine bessere (+ besser dokumentierte) Bibliothek, um das zu tun?

Antwort

4

Armadillo tun dies mit eigs_sym

Beachten Sie, dass alle die Eigenwerte der Berechnung ist eine sehr teure Operation, was auch immer Sie tun, in der Regel, was geschehen ist, ist nur die k größten zu finden, oder kleinsten Eigenwerte (das, was Das wird es tun).

+0

Das ist genau das, was ich für und zusätzlich suchte es zu sein scheint eine schnelle Bibliothek. Da dies eine Antwort auf meine Frage ist, werde ich es als akzeptiert markieren, aber haben Sie Erfahrung mit Eigen für diese Art von Aufgabe? – Philipp

+0

Keine persönliche Erfahrung mit Eigen für diese Art von Dingen, fürchte ich. Ich neige dazu, Armadillo fast ausschließlich für lineare Algebra in C++ zu verwenden. Von einem kurzen Blick auf die Dokumente sah es für mich nicht anders aus, als wenn man etwas anderes tun würde, was man wollte, ohne etwas mit einer QR-Dekomposition mit spärlichen Matrizen zu codieren. –

1

Für Eigen gibt es eine Bibliothek mit dem Namen Spectra. Wie auf der Webseite beschrieben, ist Spectra ein Redesign der ARPACK-Bibliothek in C++ Sprache.

Im Gegensatz zu Armadillo, vorgeschlagen in another answer, unterstützt Spectra long double und jeden anderen realen Fließkommatyp (z. B. boost::multiprecision::float128).

Hier ist ein Beispiel für die Nutzung (wie bei der Version in der Dokumentation, sondern auch für Experimente mit verschiedenen Gleitkommatypen angepasst):

#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'; 
    } 
}