c++ 特征分解速度大

c++ Large eigendecomposition speed

本文关键字:速度 分解 特征 c++      更新时间:2023-10-16

作为我的管道的一部分,我需要以 6000x6000 的数量级执行大矩阵的特征分解。矩阵是密集的,所以除非我简化问题(如果可能的话),否则不能使用稀疏方法。

目前我玩玩具数据。将特征库用于 513x513 矩阵我需要 ~6.5 秒,而对于 2049x2049 矩阵我需要 ~130 秒,这听起来令人望而却步,因为增加不是线性的。这是通过Eigen::SelfAdjointEigenSolver实现的,而使用其他方法(如Eigen::EigenSolverEigen::ComplexEigenSolver)我没有得到显着的改善。当我尝试使用arma::eig_sym犰狳时,即使使用"dc"选项,也发生了同样的情况,该选项应该提供更快但近似的结果。犰狳有一些方法只返回加速的前 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;
}

我建议尝试Arpack-Eigen。我从Octave/Matlab知道它可以在一秒钟内计算随机2049x2049的最大特征值,并在5-20秒内计算最大的10特征值,eigs(rand(2049), 10)。现在,它的文档help eigs指向ARPACK。阿帕克-本根https://github.com/yixuan/arpack-eigen 允许您从较大的矩阵请求 10 个特征值,如下所示:SymEigsSolver< double, LARGEST_ALGE, DenseGenMatProd<double> > eigs(&op, 10, 30); .