我发现 scipy.linalg.eig 有时会给出不一致的结果。但不是每次。
>>> import numpy as np
>>> import scipy.linalg as lin
>>> modmat=np.random.random((150,150))
>>> modmat=modmat+modmat.T # the data i am interested in is described by real symmetric matrices
>>> d,v=lin.eig(modmat)
>>> dx=d.copy()
>>> vx=v.copy()
>>> d,v=lin.eig(modmat)
>>> np.all(d==dx)
False
>>> np.all(v==vx)
False
>>> e,w=lin.eigh(modmat)
>>> ex=e.copy()
>>> wx=w.copy()
>>> e,w=lin.eigh(modmat)
>>> np.all(e==ex)
True
>>> e,w=lin.eigh(modmat)
>>> np.all(e==ex)
False
虽然我不是最伟大的线性代数向导,但我确实理解特征分解本质上会受到奇怪的舍入误差的影响,但我不明白为什么重复计算会导致不同的值。但我的结果和可重复性各不相同。
问题的本质是什么——嗯,有时结果是可以接受的不同,有时不是。这里有些例子:
>>> d[1]
(9.8986888573772465+0j)
>>> dx[1]
(9.8986888573772092+0j)
~3e-13 的上述差异似乎并不是什么大问题。相反,真正的问题(至少对于我目前的项目而言)是一些特征值似乎无法就正确的符号达成一致。
>>> np.all(np.sign(d)==np.sign(dx))
False
>>> np.nonzero(np.sign(d)!=np.sign(dx))
(array([ 38, 39, 40, 41, 42, 45, 46, 47, 79, 80, 81, 82, 83,
84, 109, 112]),)
>>> d[38]
(-6.4011617320002525+0j)
>>> dx[38]
(6.1888785138080209+0j)
MATLAB中的类似代码似乎没有这个问题。