c ++大的特征分解速度

时间:2016-02-22 16:46:27

标签: c++ eigen armadillo eigen3

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

目前我玩玩具数据。使用513x513矩阵的特征库我需要~6.5秒,而对于2049x2049矩阵我需要~130秒,这听起来很禁止,因为增加不是线性的。这是通过Eigen::SelfAdjointEigenSolver实现的,而对于其他方法,例如Eigen::EigenSolverEigen::ComplexEigenSolver,我没有得到显着改善。当我用arma::eig_sym尝试犰狳甚至选择“dc”时,也会发生同样的事情,这个选项可以提供更快但近似的结果。犰狳有一些方法只返回加速的第一个X特征值,但这只适用于稀疏方法。目前,我可能会逃脱前10-20个特征值。

有没有办法或图书馆/方法可以给我一个显着的加速?

2 个答案:

答案 0 :(得分:4)

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;
}

答案 1 :(得分:0)

我建议尝试使用Arpack-Eigen。我从Octave / Matlab得知它可以在一秒内计算随机2049x2049的最大特征值,在5-20秒内计算最大的10 [{1}}。 现在,它的文档eigs(rand(2049), 10)指向ARPACK。 ARPACK - 艾根 https://github.com/yixuan/arpack-eigen允许您从更大的矩阵中请求10个特征值:help eigs