我使用armadillo的eigs_gen來查找稀疏矩陣的最小代數特徵值。Armadillo:eigs_gen最小特徵值
如果我只是要求最小特徵值的函數,結果是不正確的,但是如果我要求它爲2個最小的特徵值,結果是正確的。該代碼是:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int
main(int argc, char** argv)
{
cout << "Armadillo version: " << arma_version::as_string() << endl;
sp_mat A(5,5);
A(1,2) = -1;
A(2,1) = -1;
A(3,4) = -1;
A(4,3) = -1;
cx_vec eigval;
cx_mat eigvec;
eigs_gen(eigval, eigvec, A, 1, "sr"); // find smallest eigenvalue ---> INCORRECT RESULTS
eigval.print("Smallest real eigval:");
eigs_gen(eigval, eigvec, A, 2, "sr"); // find 2 smallest eigenvalues ---> ALMOST CORRECT RESULTS
eigval.print("Two smallest real eigvals:");
return 0;
}
我的編譯命令是:
g++ file.cpp -o file.exe -O2 -I/path-to-armadillo/armadillo-4.600.3/include -DARMA_DONT_USE_WRAPPER -lblas -llapack -larpack
輸出是:
Armadillo version: 4.600.3 (Off The Reservation)
Smallest real eigval:
(+1.000e+00,+0.000e+00)
Two smallest real eigvals:
(-1.000e+00,+0.000e+00)
(-1.164e-17,+0.000e+00)
爲什麼發生這種情況以及如何克服這個任何想法表示讚賞。
注意:第二個結果只是幾乎正確,因爲我們期望-1,-1作爲兩個最低的特徵值,但可能重複的特徵值被忽略。
更新:包括測試矩陣結構,它之後,瑞安的變化包括「SA」選項庫,似乎並沒有收斂:
#define ARMA_64BIT_WORD
#include <armadillo>
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace arma;
using namespace std;
int main(){
size_t l(3), ls(l*l*l);
sp_mat A = sprandn<sp_mat>(ls, ls, 0.01);
sp_mat B = A.t()*A;
vec eigval;
mat eigvec;
eigs_sym(eigval, eigvec, B, 1, "sa");
return 0;
}
感興趣的矩陣大小是多少更大,例如ls = 8000 - 27000
,並不完全是這裏構建的矩陣,但我認爲問題應該是相同的。
謝謝,這實際上是圖書館非常希望和實質性的改進。 – MaviPranav 2015-02-18 14:18:42
實際上似乎存在「sa」選項的收斂問題,缺少「lm」選項。我已經包含了代碼的更新,顯示了一個測試矩陣結構,這似乎並不適合我。 – MaviPranav 2015-02-20 17:31:42
我建議這裏的問題不是Armadillo的ARPACK包裝,而是ARPACK使用的數值方法。對輸入矩陣的屬性進行更好的調查,以及隱式重新啓動的Arnoldi方法是否適合您的特定矩陣,可能是接下來要做的事情。 – ryan 2015-02-23 22:42:35