Numpy不准确的矩阵逆

时间:2014-02-17 21:40:03

标签: numpy scipy linear-algebra

在numpy中计算矩阵求逆(求解线性系统)时,我一直在看到非常不可接受的高度不准确性。

  • 这是不正常的准确程度吗?
  • 如何提高此计算的准确性?
  • 另外,有没有办法在numpy或scipy中更有效地解决这个系统(scipy.linalg.cho_solve看起来很有希望但是没有做我想要的事情?)

在下面的代码中,cholM是128 x 128矩阵。矩阵数据太大而不能包含在此处,但位于pastebin:cholM.txt

此外,原始向量ovec是随机选择的,因此对于不同的ovec,精度会有所不同,但是,对于大多数情况,错误似乎仍然高得令人无法接受。

编辑使用奇异值分解求解系统产生的误差明显低于其他方法。

import numpy.random as rnd
import numpy.linalg as lin
import numpy as np

cholM=np.loadtxt('cholM.txt')

dims=len(cholM)
print 'Dimensions',dims

ovec=rnd.normal(size=dims)
rvec=np.dot(cholM.T,ovec)
invCholM=lin.inv(cholM.T)

svec=np.dot(invCholM,rvec)
svec1=lin.solve(cholM.T,rvec)

def back_substitute(M,v):
    r=np.zeros(len(v))
    k=len(v)-1
    r[k]=v[k]/M[k,k]
    for k in xrange(len(v)-2,-1,-1):
        r[k]=(v[k]-np.dot(M[k,k+1:],r[k+1:]))/M[k,k]

    return r

svec2=back_substitute(cholM.T,rvec)

u,s,v=lin.svd(cholM)
svec3=np.dot(u,np.dot(np.diag(1./s),np.dot(v,rvec)))

for k in xrange(dims):
    print '%20.3f%20.3f%20.3f%20.3f'%(ovec[k]-svec[k],ovec[k]-svec1[k],ovec[k]-svec2[k],ovec[k]-svec3[k])

assert np.all( np.abs(ovec-svec)<1e-5 ) 
assert np.all( np.abs(ovec-svec1)<1e-5 )

2 个答案:

答案 0 :(得分:2)

正如@Craig J Copi和@pv所指出的那样,cholM矩阵的condition number很高,大约10 ^ 16,这表明为了获得更高的反向精度,更高的数值精度可能是必需的。

条件数可以通过最大奇异值与最小奇异值的比率来确定。在这种情况下,该比率与特征值的比率不同。

答案 1 :(得分:-1)

http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html

  

我们可以使用矩阵逆找到解向量:   ...   但是,最好使用linalg.solve命令,它可以更快,更稳定数值

编辑 - 来自Steve Lord的MATLAB http://www.mathworks.com/matlabcentral/newsreader/view_thread/63130

  

你为什么反转?如果您要反转解决系统,请不要 -   通常你会想要使用反斜杠。

     

但是,对于条件编号约为1e17的系统(条件编号   必须大于或等于1,所以我假设1e-17数字在   你的帖子是来自RCOND的互惠条件号码)你不会去   在任何情况下都能获得非常准确的结果。