【问题标题】:Sparse eigenvalues using eigen3/sparse使用 eigen3/sparse 的稀疏特征值
【发布时间】:2015-07-23 04:27:46
【问题描述】:

Eigen3 中,是否有一种独特而有效的方法来查找实数、对称、非常大(例如 10000x10000)稀疏矩阵的特征值和特征向量?稠密矩阵有一个特征值求解器,但它没有利用矩阵的属性,例如这是对称的。此外,我不想密集存储矩阵。

或者(替代)是否有更好的(+更好的文档记录)库来做到这一点?

【问题讨论】:

    标签: c++ eigenvalue eigen3


    【解决方案1】:

    对于 Eigen,有一个名为 Spectra 的库。正如其网页上所述,Spectra 是使用 C++ 语言重新设计的 ARPACK 库。

    another answer 中建议的犰狳不同,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';
        }
    }
    

    【讨论】:

      【解决方案2】:

      Armadillo 将使用 eigs_sym 执行此操作

      请注意,无论您做什么,计算所有特征值都是一项非常昂贵的操作,通常所做的只是找到 k 个最大或最小的特征值(这就是这样做的)。

      【讨论】:

      • 这正是我一直在寻找的,此外它似乎是一个快速的库。由于这是对我问题的回答,我会将其标记为已接受,但是您是否有使用 Eigen 完成此类任务的经验?
      • 恐怕没有使用 Eigen 处理这类事情的个人经验。我倾向于将犰狳专门用于 C++ 中的线性代数。快速浏览一下文档,在我看来,如果不使用带有稀疏矩阵的 QR 分解手动编码,就可以有任何其他方式来做你想做的事情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2012-08-20
      • 2013-09-25
      • 2017-08-14
      • 2015-08-27
      • 1970-01-01
      • 2015-11-28
      相关资源
      最近更新 更多