0

我刚刚发现 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

4

2 回答 2

1

这里显示的所有结果都是正确的。

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

于 2012-08-30T18:16:28.207 回答
1

在我看来一切都很好:

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
于 2012-08-30T18:19:18.140 回答