Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于过大的矩阵,特征值分解会因犰狳eigs_sym()而失败_C++_Armadillo - Fatal编程技术网

C++ 对于过大的矩阵,特征值分解会因犰狳eigs_sym()而失败

C++ 对于过大的矩阵,特征值分解会因犰狳eigs_sym()而失败,c++,armadillo,C++,Armadillo,我最近安装了犰狳并尝试了稀疏矩阵的特征值问题。不幸的是,分解失败的原因是参数“N”(下面的代码)太大,e.q.1000。我不知道这里发生了什么事。矩阵不是很复杂,它有对角结构 更新 Mathematica也有这个矩阵的问题。它告诉我Arnoldi算法不收敛。也许我需要在arnoldi arpack例程中手动指定一些参数以确保收敛 这是我的密码: #include <armadillo> int main () { double N = 1000.0; // cre

我最近安装了犰狳并尝试了稀疏矩阵的特征值问题。不幸的是,分解失败的原因是参数“N”(下面的代码)太大,e.q.1000。我不知道这里发生了什么事。矩阵不是很复杂,它有对角结构

更新

Mathematica也有这个矩阵的问题。它告诉我Arnoldi算法不收敛。也许我需要在arnoldi arpack例程中手动指定一些参数以确保收敛

这是我的密码:

#include <armadillo>

int main ()
{
    double N = 1000.0;

    // create matrix
    int kmin = 0;
    int kmax = static_cast<int>( std::floor( N/2.0 ) );
    int dim = (kmax - kmin) + 1;

    // locations and values in sparse matrices
    arma::umat hc_locations (2, 3*dim-2);
    arma::vec hc_values (3*dim-2);

    // diagonal part
    for (int k=0; k<dim; k++)
    {
        hc_locations (0,k) = k;
        hc_locations (1,k) = k;
        hc_values (k) = 2.0/N*static_cast<double>(kmin + k)*( 2.0*( N-2.0*static_cast<double>(k + kmin) ) - 1.0 );

    }
    // upper and lower diagonal
    for (int k=0; k<dim-1; k++)
    {
        hc_locations (0,k+dim) = k;
        hc_locations (1,k+dim) = k+1;
        hc_values (k+dim) = 2.0/N*std::sqrt( ( static_cast<double>(k+1+kmin) ) *
                                             ( static_cast<double>(k+1+kmin) ) *
                                             ( N - static_cast<double>(2*(k+1+kmin)) + 1.0 ) * 
                                             ( N - static_cast<double>(2*(k+1+kmin)) + 2.0 ) );

        hc_locations (0, k+2*dim-1) = k+1;
        hc_locations (1, k+2*dim-1) = k;
        hc_values (k+2*dim-1) = 2.0/N*std::sqrt ( ( static_cast<double>(k+1+kmin) ) * 
                                                   ( static_cast<double>(k+1+kmin) ) *
                                                   ( N - static_cast<double>(2*(k+kmin)) ) *
                                                   ( N - static_cast<double>(2*(k+kmin)) - 1.0 ) );
    }

    arma::sp_mat Ham(hc_locations, hc_values);

    // eigenvalue problem
    arma::vec eigval;
    arma::mat eigvec;

    arma::eigs_sym( eigval, eigvec, Ham, 3, "sa"); 
#包括
int main()
{
双N=1000.0;
//创建矩阵
int-kmin=0;
int kmax=静态铸件(标准::地板(N/2.0));
int dim=(kmax-kmin)+1;
//稀疏矩阵中的位置和值
arma:umat hc_位置(2,3*dim-2);
arma::vec hc_值(3*dim-2);
//对角线部分

对于(int k=0;k大小为2000左右的小矩阵,通常更容易找到所有特征值和特征向量,因为这些方法不太容易受到近似奇异矩阵的影响

我替换了你的代码

arma::eigs_sym( eigval, eigvec, Ham, 3, "sa"); 


在2015年末的Macbook Pro上,编译后的程序只需不到一秒钟的时间就能解决问题。

我不久前就解决了这个问题。问题在于ARPACK库,更具体地说,Armadillo库不允许您像原始ARPACK库那样指定Krylov基的大小和最大迭代次数。smalle和该矩阵的st特征值对于5阶基(默认Armadillo 2*nev+1)来说太小。我用fortran编写了类似的程序,对于矩阵大小N=10000,我需要90阶基,以便使用Arnoldi迭代收敛。Mathematica 10.0还允许指定基向量的数量和最大迭代次数。它可以工作。
arma::mat fullMat = arma::mat(Ham);
arma::eig_sym( eigval, eigvec, fullMat);