![](/img/trans.png)
[英]scipy.sparse.linalg.eigsh returns different eigenvalues for the same matrix
[英]scipy.sparse.linalg.eigsh() doesn't give out the same result as Matlab's eigs(), why?
我正在使用scipy.sparse.linalg.eigsh()
解決廣義特征值問題。 我要使用eigsh()
因為我正在處理一些大型的稀疏矩陣。 問題是我無法得到正確的答案, eigsh()
輸出的特征值和特征向量與我從Matlab的eigs()
獲得的特征完全不同。
看起來像這樣:數據:
a:
304.7179 103.1667 36.9583 61.3478 11.5724
35.5242 111.4789 -9.8928 8.2586 -4.7405
10.8358 4.3433 145.6586 26.5153 13.1871
-1.1924 -2.5430 0.4322 43.1886 -0.6098
-18.7751 -8.8031 -4.3962 -5.8791 17.6588
b:
736.9822 615.7946 587.6828 595.7169 545.1878
615.7946 678.2142 575.7579 587.3469 524.7201
587.6828 575.7579 698.6223 593.5402 534.3675
595.7169 587.3469 593.5402 646.0410 530.1114
545.1878 524.7201 534.3675 530.1114 590.1373
在python中:a,b是numpy.ndarray
In [11]: import scipy.sparse.linalg as lg
In [14]: x,y=lg.eigsh(a,M=b,k=2,which='SM')
In [15]: x
Out[15]: array([ 0.01456738, 0.22578463])
In [16]: y
Out[16]:
array([[ 0.00052614, 0.00807034],
[ 0.00514091, -0.01593113],
[ 0.00233622, -0.00429671],
[ 0.01877451, -0.06259276],
[ 0.01491696, 0.08002341]])
In [18]: a.dot(y[:,0])-x[0]*b.dot(y[:,0])
Out[18]: array([ 1.74827445, 0.30325634, 0.71299604, 0.42842245, -0.24724681])
In [19]: a.dot(y[:,1])-x[1]*b.dot(y[:,1])
Out[19]: array([-2.2463206 , -1.64704567, -0.80086734, -1.56796329, 0.03027861])
可以看出,特征值和特征向量不足以重組原始矩陣。
但是,在MATLAB中它運作良好:
[y,x] = eigs(a,b,2,'sm');
y =
0.0037 -0.0141
-0.0056 0.0151
0.0015 0.0079
-0.0117 0.0666
-0.0298 -0.0753
x =
0.0202 0
0 0.3499
a*x(:,1)-y(1,1)*b*x(:,1)
ans =
1.0e-14 *
-0.3775
0.0777
0.0777
0.0555
0.0666
另外,數據b是正定的:
In [24]: np.linalg.eigvals(b)
Out[24]:
array([ 2951.07297125, 137.81545217, 90.40223937, 107.04818229,
63.65818086])
誰能解釋為什么我無法在python中獲得正確的答案?
使用lg.eigs()
我們確實獲得了與MATLAB中相同的輸出。 但是...問題在矩陣變大時發生,如下所示:
在MATLAB中,我們有類似以下內容:
>> [x,y] = eigs(A,B,4,'sm');
y =
0.0001 0 0 0
0 0.0543 0 0
0 0 0.1177 0
0 0 0 0.1350
而在python(python3.5.2,scipy1.0.0)中使用lg.eigs(A,M=B,k=4,which='SM')
其特征值如下:
array([ 4.43277284e+51 +0.00000000e+00j,
1.04797857e+48 +8.30096152e+47j,
1.04797857e+48 -8.30096152e+47j, -1.45582240e+31 +0.00000000e+00j])
正如Paul Panzer所說,“ eigsh”中的“ h”代表Hermitian ,而矩陣A不是。 (此外,具有正特征值並不意味着是正定的;僅當矩陣以Hermitian開頭時才是正確的。) eigsh
方法不檢查輸入是否為Hermitian。 它只是遵循一個假設的過程; 因此,當假設失敗時,輸出將不正確。
使用eigs方法產生的結果與Matlab相同:
x, y = lg.eigs(a,M=b,k=2,which='SM')
np.real(x), np.real(y) # x and y have tiny imaginary parts due to float math errors
(array([ 0.02022333, 0.34993346]),
array([[-0.00368007, -0.0140898 ],
[ 0.0056435 , 0.01509067],
[-0.00154725, 0.00790518],
[ 0.01170563, 0.06664118],
[ 0.02981777, -0.07528778]]))
當然,運行eigsh
比運行eigs
需要更長的時間。
您的第二個示例是一個34 x 34的密集矩陣,它根本沒有零。 在上面使用稀疏線性代數是不合理的。 並警告說該方法尚未收斂。 常規線性代數模塊工作正常。
import scipy.linalg as la
sorted_eigenvals = np.sort(np.real(la.eigvals(Am, Bm)))
這返回
5.90947734e-05,5.42521180e-02,1.17669899e-01,1.34952286e-01,...
與您引用的MATLAB輸出一致(Matlab舍入數字除外)
0.0001、0.0543、0.1177、0.1350
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.