python/numpy: problems with numpy linal.eig



我刚刚发现numpy-linalg.eig算法的这种非常奇怪的行为。

如果运行

>>> import numpy as np
>>> a = np.array([[1., 0., 0., 0., 0., 0., 0., 0.],
... [0., -1., -0.5, 0., -0.5, 0., 0., 0.], 
... [0., -0.5, 0., 0., 0., 0., 0., 0.], 
... [0., 0., 0., 0., 0., 0., -0.5, 0.], 
... [0., -0.5, 0., 0., 0., 0., 0., 0.], 
... [0., 0., 0., 0., 0., 0., -0.5, 0.],  
... [0., 0., 0., -0.5, 0., -0.5, -1., 0.], 
... [0., 0., 0., 0., 0., 0., 0., 1.]])
>>> np.linalg.eig(a)
(array([-1.366,  0.366, -1.366,  0.366,  0.   ,  0.   ,  1.   ,  1.   ]),
array([[ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ,  0.   ],
   [-0.   ,  0.   , -0.822,  0.426,  0.   ,  0.   ,  0.   ,  0.   ],
   [ 0.   ,  0.   , -0.301, -0.581,  0.13 ,  0.   ,  0.   ,  0.   ],
   [-0.325, -0.628, -0.123, -0.237, -0.695, -0.707,  0.   ,  0.   ],
   [ 0.   ,  0.   , -0.301, -0.581, -0.13 , -0.   ,  0.   ,  0.   ],
   [-0.325, -0.628, -0.123, -0.237,  0.695,  0.707,  0.   ,  0.   ],
   [-0.888,  0.46 , -0.336,  0.174, -0.   , -0.   ,  0.   ,  0.   ],
   [ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ]]))

我得到了上面显示的错误的特征向量(在列中)。

给出了正确答案

>>> np.linalg.eigh(a)
(array([-1.366, -1.366, -0.   ,  0.   ,  0.366,  0.366,  1.   ,  1.   ]),
 array([[-0.   ,  0.   ,  0.   ,  0.   ,  0.   , -0.   ,  1.   ,  0.   ],
   [-0.   , -0.888,  0.   ,  0.   ,  0.   , -0.46 ,  0.   ,  0.   ],
   [-0.   , -0.325,  0.   , -0.707,  0.   ,  0.628,  0.   ,  0.   ],
   [-0.325,  0.   , -0.707,  0.   , -0.628, -0.   ,  0.   ,  0.   ],
   [ 0.   , -0.325,  0.   ,  0.707,  0.   ,  0.628,  0.   ,  0.   ],
   [-0.325,  0.   ,  0.707,  0.   , -0.628, -0.   ,  0.   ,  0.   ],
   [-0.888,  0.   ,  0.   ,  0.   ,  0.46 , -0.   ,  0.   ,  0.   ],
   [-0.   ,  0.   ,  0.   ,  0.   ,  0.   , -0.   ,  0.   ,  1.   ]]))

我真的很惊讶eig算法不能对这么简单的矩阵进行对角化!

我应该报告这种行为吗?

编辑

numpy版本1.6.2

我觉得一切都很好:

import numpy as np
a = np.array([[1., 0., 0., 0., 0., 0., 0., 0.],
              [0., -1., -0.5, 0., -0.5, 0., 0., 0.], 
              [0., -0.5, 0., 0., 0., 0., 0., 0.], 
              [0., 0., 0., 0., 0., 0., -0.5, 0.], 
              [0., -0.5, 0., 0., 0., 0., 0., 0.], 
              [0., 0., 0., 0., 0., 0., -0.5, 0.],  
              [0., 0., 0., -0.5, 0., -0.5, -1., 0.], 
              [0., 0., 0., 0., 0., 0., 0., 1.]])
fns = np.linalg.eig, np.linalg.eigh
for fn in fns:
    print fn
    ww, vv = fn(a)
    for i in range(len(ww)):
        w = ww[i]
        v = vv[:,i]
        print i, np.allclose(np.dot(a, v),w*v),
    print

产生

<function eig at 0xb5b570d4>
0 True 1 True 2 True 3 True 4 True 5 True 6 True 7 True
<function eigh at 0xb5b5710c>
0 True 1 True 2 True 3 True 4 True 5 True 6 True 7 True

此处显示的所有结果都是正确的。

因为你的矩阵有两个特征值分别为-1.366和0.366的二维子空间。对于2D子空间,可以选择线性独立特征向量的不同线性组合。

相关内容

  • 没有找到相关文章