2016-05-18 41 views
2

我使用numpy來計算循環矩陣的特徵值和特徵向量。這裏是我的代碼(Hji for j = 1,2 ... 6是預定義的):numpy似乎爲循環矩陣返回錯誤的本徵向量

>>> import numpy as np 
>>> H = np.array([H1i, H2i, H3i, H4i, H5i, H6i]) 
>>> H 
array([[ 0., 1., 0., 0., 0., 1.], 
     [ 1., 0., 1., 0., 0., 0.], 
     [ 0., 1., 0., 1., 0., 0.], 
     [ 0., 0., 1., 0., 1., 0.], 
     [ 0., 0., 0., 1., 0., 1.], 
     [ 1., 0., 0., 0., 1., 0.]]) 
>>> from numpy import linalg as LA 
>>> w, v = LA.eig(H) 

>>> w 
array([-2., 2., 1., -1., -1., 1.]) 
>>> v 
array([[ 0.40824829, -0.40824829, -0.57735027, 0.57732307, 0.06604706, 
     0.09791921], 
     [-0.40824829, -0.40824829, -0.28867513, -0.29351503, -0.5297411 , 
     -0.4437968 ], 
     [ 0.40824829, -0.40824829, 0.28867513, -0.28380804, 0.46369403, 
     -0.54171601], 
     [-0.40824829, -0.40824829, 0.57735027, 0.57732307, 0.06604706, 
     -0.09791921], 
     [ 0.40824829, -0.40824829, 0.28867513, -0.29351503, -0.5297411 , 
     0.4437968 ], 
     [-0.40824829, -0.40824829, -0.28867513, -0.28380804, 0.46369403, 
     0.54171601]]) 

特徵值是正確的。然而,對於本徵向量,我發現它們不是線性獨立

>>> V = np.zeros((6,6)) 
>>> for i in range(6): 
...  for j in range(6): 
...   V[i,j] = np.dot(v[:,i], v[:,j]) 
... 

>>> V 
array([[ 1.00000000e+00, -2.77555756e-17, -2.49800181e-16, 
     -3.19189120e-16, -1.11022302e-16, 2.77555756e-17], 
     [ -2.77555756e-17, 1.00000000e+00, -1.24900090e-16, 
     -1.11022302e-16, -8.32667268e-17, 0.00000000e+00], 
     [ -2.49800181e-16, -1.24900090e-16, 1.00000000e+00, 
     -1.52655666e-16, 8.32667268e-17, -1.69601044e-01], 
     [ -3.19189120e-16, -1.11022302e-16, -1.52655666e-16, 
      1.00000000e+00, 1.24034735e-01, -8.32667268e-17], 
     [ -1.11022302e-16, -8.32667268e-17, 8.32667268e-17, 
      1.24034735e-01, 1.00000000e+00, -1.66533454e-16], 
     [ 2.77555756e-17, 0.00000000e+00, -1.69601044e-01, 
     -8.32667268e-17, -1.66533454e-16, 1.00000000e+00]]) 
>>> 

可以看到有非對角線項(查看V [2,5] = -1.69601044e-01),這意味着它們不是線性獨立向量。由於這是一個Hermitian矩陣,它的特徵向量如何變得依賴?

順便說一句,我也用MATLAB來計算的話,它返回正確的價值

V = 

    0.4082 -0.2887 -0.5000 0.5000 0.2887 -0.4082 
    -0.4082 -0.2887 0.5000 0.5000 -0.2887 -0.4082 
    0.4082 0.5774   0   0 -0.5774 -0.4082 
    -0.4082 -0.2887 -0.5000 -0.5000 -0.2887 -0.4082 
    0.4082 -0.2887 0.5000 -0.5000 0.2887 -0.4082 
    -0.4082 0.5774   0   0 0.5774 -0.4082 


D = 

    -2.0000   0   0   0   0   0 
     0 -1.0000   0   0   0   0 
     0   0 -1.0000   0   0   0 
     0   0   0 1.0000   0   0 
     0   0   0   0 1.0000   0 
     0   0   0   0   0 2.0000 
+1

非對角線項大致爲0.0000000000000001。由於浮點數學的不精確性,它們只是「舍入誤差」。 – BrenBarn

+0

@BrenBarn。對不起,我沒有說清楚,你可以查看V [2,5] = -1.69601044e-01。 – Aaron

回答

1

對於埃爾米特和對稱矩陣你應該使用其他功能:eigh

import numpy as np 
from numpy import linalg as LA 

H = np.array([[ 0., 1., 0., 0., 0., 1.], 
     [ 1., 0., 1., 0., 0., 0.], 
     [ 0., 1., 0., 1., 0., 0.], 
     [ 0., 0., 1., 0., 1., 0.], 
     [ 0., 0., 0., 1., 0., 1.], 
     [ 1., 0., 0., 0., 1., 0.]]) 

w, v = LA.eigh(H) 

V = np.zeros((6,6)) 
for i in range(6): 
    for j in range(6): 
     V[i,j] = np.dot(v[:,i], v[:,j]) 

w 
Out[19]: array([-2., -1., -1., 1., 1., 2.]) 

v 
Out[20]: 
array([[-0.40824829, -0.57735027, 0.  , 0.  , 0.57735027, 
     0.40824829], 
     [ 0.40824829, 0.28867513, -0.5  , -0.5  , 0.28867513, 
     0.40824829], 
     [-0.40824829, 0.28867513, 0.5  , -0.5  , -0.28867513, 
     0.40824829], 
     [ 0.40824829, -0.57735027, 0.  , 0.  , -0.57735027, 
     0.40824829], 
     [-0.40824829, 0.28867513, -0.5  , 0.5  , -0.28867513, 
     0.40824829], 
     [ 0.40824829, 0.28867513, 0.5  , 0.5  , 0.28867513, 
     0.40824829]]) 

V 
Out[21]: 
array([[ 1.00000000e+00, 8.32667268e-17, 2.77555756e-17, 
      8.32667268e-17, -2.08166817e-16, 0.00000000e+00], 
     [ 8.32667268e-17, 1.00000000e+00, 5.55111512e-17, 
      5.55111512e-17, -2.22044605e-16, -1.11022302e-16], 
     [ 2.77555756e-17, 5.55111512e-17, 1.00000000e+00, 
      0.00000000e+00, 2.77555756e-17, 1.11022302e-16], 
     [ 8.32667268e-17, 5.55111512e-17, 0.00000000e+00, 
      1.00000000e+00, 8.32667268e-17, 5.55111512e-17], 
     [ -2.08166817e-16, -2.22044605e-16, 2.77555756e-17, 
      8.32667268e-17, 1.00000000e+00, 0.00000000e+00], 
     [ 0.00000000e+00, -1.11022302e-16, 1.11022302e-16, 
      5.55111512e-17, 0.00000000e+00, 1.00000000e+00]]) 
+0

感謝您的幫助。但是,爲什麼LA.eig不起作用? – Aaron

+0

@Aaron有不同的算法用於計算。從numpy文檔:'eig'「使用_geev LAPACK例程」和'eigh' - 「使用LAPACK例程_syevd,_heevd」來實現。您可以在英特爾網站上閱讀以下差異:[對稱](https://software.intel.com/zh-cn/node/521045)和[非對稱](https://software.intel.com/zh-cn//node/521079)特徵值問題。如果你想要更深入的信息,請閱讀[Lapack](http://www.netlib.org/lapack/lug/)。 –

+0

感謝您的回覆。 – Aaron

2

eig返回的結果非常好。這可以通過

np.allclose(v.dot(np.diag(w)).dot(LA.inv(v)),H) 
True 

注意的eig的輸出對應於形式v * diag(w) * inv(v),它保存用於一般對角化矩陣的輸入矩陣的因數分解中可以看出。由於eigH視爲沒有特殊結構,所以返回的特徵向量不期望具有特殊結構,例如正交。 (不要與線性無關混淆正交 - 的v列確實是線性無關的可以由非零LA.det(v)簡單地驗證。)

功能eigh知道該輸入矩陣是厄密,並返回一個更方便,即,正交的一組特徵向量。

+0

謝謝。我誤解了線性獨立性和正交性的定義。 Hermitian矩陣的eigtenvector應該是線性獨立的,但是線性獨立並不意味着正交性(正交性意味着線性獨立性)。 – Aaron