Разреженные собственные значения с использованием собственного 3 / разреженного

Существует ли отличный и эффективный способ поиска собственных значений и собственных векторов реальной, симметричной, очень большой, скажем, 10000×10000, разреженной матрицы в Eigen3? Для плотных матриц существует решатель собственных значений, но в нем не используется свойство матрицы, например, это симметрия Кроме того, я не хочу хранить матрицу в плотном.

Или (альтернатива) есть лучшая (+ лучше задокументированная) библиотека для этого?

5

Решение

броненосец будет делать это с помощью eigs_sym

Обратите внимание, что вычисления все Собственные значения — это очень дорогая операция, что бы вы ни делали, обычно то, что нужно сделать, это найти только k самых больших или самых маленьких собственных значений (именно это и будет делать).

4

Другие решения

Для Эйгена есть библиотека с именем спектры. Как описано на его веб-странице, Spectra представляет собой редизайн библиотеки ARPACK с использованием языка C ++.

В отличие от броненосца, предложенного в другой ответ, Spectra поддерживает long double и любой другой реальный тип с плавающей запятой (например, boost::multiprecision::float128).

Вот пример использования (такой же, как версия в документации, но адаптированный для экспериментов с различными типами с плавающей точкой):

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

По вопросам рекламы [email protected]