在numpy中计算矩阵求逆(求解线性系统)时,我一直在看到非常不可接受的高度不准确性。
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 )
答案 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的互惠条件号码)你不会去 在任何情况下都能获得非常准确的结果。