我刚刚发现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子空间,可以选择线性独立特征向量的不同线性组合。