2015-05-12 10 views
5

Czy istnieje wyraźny i skuteczny sposób na znalezienie wartości własnych i wektorów własnych rzeczywistej, symetrycznej, bardzo dużej, powiedzmy, 10000x10000, rzadkiej macierzy w Eigen3? Istnieje solwerter wartości własnej dla gęstych macierzy, ale nie wykorzystuje on właściwości macierzy, np. to symetria. Ponadto nie chcę przechowywać matrycy w gęstej postaci.Rzadkie wartości własne przy użyciu eigen3/sparse

Czy (alternatywnie) istnieje lepsza (+ lepiej udokumentowana) biblioteka, aby to zrobić?

Odpowiedz

4

Armadillo zrobi to za pomocą eigs_sym

Zauważ, że obliczeniowej wszystkie wartości własnych jest bardzo kosztowna operacja cokolwiek robisz, zwykle co zrobić, to znaleźć tylko k największej lub najmniejszej wartości własnych (co jest co to wystarczy).

+0

To jest dokładnie to, czego szukasz, a ponadto wydaje się być szybka biblioteka. Ponieważ jest to odpowiedź na moje pytanie, oznaczę ją jako zaakceptowaną, ale czy masz doświadczenie w korzystaniu z Eigen do tego rodzaju zadań? – Philipp

+0

Brak osobistego doświadczenia z wykorzystaniem Eigen do tego typu rzeczy, obawiam się. Zazwyczaj używam Armadillo wyłącznie do algebry liniowej w C++. Od szybkiego spojrzenia na dokumenty nie wyglądało na to, że byłby jakikolwiek inny sposób robienia tego, co chciałeś, bez ręcznego kodowania czegoś przy dekompozycji QR z rzadkimi macierzami. –

1

Dla Eigen istnieje biblioteka o nazwie Spectra. Jak opisano na stronie internetowej, Spectra to przeprojektowanie biblioteki ARPACK za pomocą języka C++.

W przeciwieństwie do Pancernika, zasugerowanego w another answer, Spectra obsługuje long double i każdy inny prawdziwy typ zmiennoprzecinkowy (np. boost::multiprecision::float128).

Oto przykład użycia (tak samo jak w wersji w dokumentacji, ale dostosowany do eksperymentów z różnymi rodzajami zmiennoprzecinkowych):

#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'; 
    } 
} 
Powiązane problemy