2016-05-18 42 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