2016-04-25 124 views
2

我最近安裝了犰狳並嘗試了稀疏矩陣的特徵值問題。不幸的是,分解失敗是參數'N'(下面的代碼)太大e.q.我想知道這裏發生了什麼。矩陣不是很複雜 - 它具有對角結構。對於太大的矩陣,特徵值分解失敗,armadillo eigs_sym()

UPDATE

數學也有這個矩陣的問題。它告訴我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"); 

}

回答

0

對於大小爲2000的小矩陣左右,它往往是時間更容易找到所有的特徵向量,因爲這些方法都是不敏感接近奇異矩陣。

我換成你的代碼

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

arma::mat fullMat = arma::mat(Ham); 
arma::eig_sym(eigval, eigvec, fullMat); 

和編譯的程序只需要不到一秒鐘就解決了我的已故2015年的MacBook Pro。

+0

前段時間我已經解決了這個問題。問題在於ARPACK庫。更具體地說,Armadillo庫不允許你指定Krylov基礎的大小和最大迭代次數,就像原始的ARPACK庫一樣。該矩陣的最小特徵值之間的距離對於階數5的基礎來說太小(默認Armadillo 2 * nev + 1)。我在Fortran中編寫了類似的程序,對於矩陣大小N = 10000,我需要90階的基本大小以便使用Arnoldi迭代進行收斂。 Mathematica 10.0還允許您指定基向量數和最大迭代次數。有用。 – Bociek