使用 eigen3/sparse 的稀疏特征值
Sparse eigenvalues using eigen3/sparse
在 Eigen3 中,是否有一种独特而有效的方法来查找实数、对称、非常大(比方说 10000x10000)稀疏矩阵的特征值和特征向量?有一个用于稠密矩阵的特征值求解器,但它没有使用矩阵的 属性,例如它是对称的。此外,我不想密集存储矩阵。
或者(替代)是否有更好的(+更好的文档)库来做到这一点?
Armadillo will do this using eigs_sym
请注意,无论您做什么,计算 所有 特征值都是非常昂贵的操作,通常所做的只是找到 k 个最大或最小的特征值(这就是这个会做的)。
对于 Eigen,有一个名为 Spectra 的库。如其网页所述,Spectra 是使用 C++ 语言重新设计的 ARPACK 库。
与 中建议的 Armadillo 不同,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';
}
}
在 Eigen3 中,是否有一种独特而有效的方法来查找实数、对称、非常大(比方说 10000x10000)稀疏矩阵的特征值和特征向量?有一个用于稠密矩阵的特征值求解器,但它没有使用矩阵的 属性,例如它是对称的。此外,我不想密集存储矩阵。
或者(替代)是否有更好的(+更好的文档)库来做到这一点?
Armadillo will do this using eigs_sym
请注意,无论您做什么,计算 所有 特征值都是非常昂贵的操作,通常所做的只是找到 k 个最大或最小的特征值(这就是这个会做的)。
对于 Eigen,有一个名为 Spectra 的库。如其网页所述,Spectra 是使用 C++ 语言重新设计的 ARPACK 库。
与 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';
}
}