作为我的管道的一部分,我需要按 6000x6000 的顺序执行大矩阵的特征分解。矩阵是密集的,所以除非我简化问题(如果可能的话请确定),否则不能使用稀疏方法。
目前我在玩玩具数据。将 Eigen 库用于 513x513 矩阵需要约 6.5 秒,而对于 2049x2049 矩阵我需要约 130 秒,这听起来令人望而却步,因为增长不是线性的。这是通过 Eigen::SelfAdjointEigenSolver
实现的,而使用其他方法,如 Eigen::EigenSolver
或 Eigen::ComplexEigenSolver
我没有得到显着改进。当我使用 arma::eig_sym
尝试 Armadillo 时,同样发生了同样的情况,即使使用选项“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;
}
关于c++大型特征分解速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35559152/