dim*_*_tz 5 c++ armadillo eigen eigen3
作为我的管道的一部分,我需要按 6000x6000 的顺序执行大矩阵的特征分解。矩阵是密集的,所以除非我简化问题(如果可能的话),否则不能使用稀疏方法。
目前我玩玩具数据。使用 Eigen 库处理 513x513 矩阵我需要大约 6.5 秒,而对于 2049x2049 矩阵我需要大约 130 秒,这听起来令人望而却步,因为增长不是线性的。这是通过 实现的Eigen::SelfAdjointEigenSolver,而使用其他方法,例如Eigen::EigenSolveror Eigen::ComplexEigenSolverI 并没有得到显着的改进。当我尝试使用 Armadillo 时,arma::eig_sym即使使用选项“dc”` 也发生了同样的情况,该选项应该提供更快但近似的结果。Armadillo 有一些方法只返回前 X 个特征值以进行加速,但这仅适用于稀疏方法。目前我可能可以摆脱前 10-20 个特征值。
有没有办法或库/方法可以给我显着的加速?
Spectra用于检索大型矩阵的几个特征值。
计算最大和最小 10 个特征值的示例代码可能如下所示:
#include <Eigen/Core>
#include <Eigen/Eigenvalues>
#include <MatOp/DenseGenMatProd.h>
#include <MatOp/DenseSymShiftSolve.h>
#include <SymEigsSolver.h>
#include <iostream>
using namespace Spectra;
int main()
{
srand(0);
// We are going to calculate the eigenvalues of M
Eigen::MatrixXd A = Eigen::MatrixXd::Random(1000, 1000);
Eigen::MatrixXd M = A.transpose() * A;
// Matrix operation objects
DenseGenMatProd<double> op_largest(M);
DenseSymShiftSolve<double> op_smallest(M);
// Construct solver object, requesting the largest 10 eigenvalues
SymEigsSolver< double, LARGEST_MAGN, DenseGenMatProd<double> >
eigs_largest(&op_largest, 10, 30);
// Initialize and compute
eigs_largest.init();
eigs_largest.compute();
std::cout << "Largest 10 Eigenvalues :\n" <<
eigs_largest.eigenvalues() << std::endl;
// Construct solver object, requesting the smallest 10 eigenvalues
SymEigsShiftSolver< double, LARGEST_MAGN, DenseSymShiftSolve<double> >
eigs_smallest(&op_smallest, 10, 30, 0.0);
eigs_smallest.init();
eigs_smallest.compute();
std::cout << "Smallest 10 Eigenvalues :\n" <<
eigs_smallest.eigenvalues() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我建议尝试 Arpack-Eigen。我从 Octave/Matlab 知道它可以在一秒内计算出随机 2049x2049 的最大特征值,并在 5-20 秒内计算出最大的 10 eigs(rand(2049), 10)。现在,它的文档help eigs指向 ARPACK。Arpack-Eigen
https://github.com/yixuan/arpack-eigen允许您从更大的矩阵中请求 10 个特征值,如下所示:SymEigsSolver< double, LARGEST_ALGE, DenseGenMatProd<double> > eigs(&op, 10, 30);。
| 归档时间: |
|
| 查看次数: |
1546 次 |
| 最近记录: |