在我用C工作的数值解算器的数值稳定逆,我需要反转一个2x2矩阵,它随后被另一矩阵相乘右侧:一个2x2矩阵
C = B . inv(A)
我有在使用倒置×2矩阵的定义如下:
a = A[0][0];
b = A[0][1];
c = A[1][0];
d = A[1][1];
invA[0][0] = d/(a*d-b*c);
invA[0][1] = -b/(a*d-b*c);
invA[1][0] = -c/(a*d-b*c);
invA[1][1] = a/(a*d-b*c);
在我的求解器的前几个迭代这似乎给正确的答案,但是,几步之后,事情开始增长,并最终爆炸。
现在,与使用SciPy的实现相比,我发现相同的数学不会爆炸。我能找到的唯一区别是SciPy代码使用scipy.linalg.inv()
,它在内部使用LAPACK来执行反演。
当我用上面的计算替换inv()
的调用时,Python版本确实爆炸了,所以我很确定这是问题所在。计算中的小差异正在蔓延,这导致我认为这是一个数值问题 - 对于反演操作来说并不是完全令人惊讶的。
我正在使用双精度浮点数(64位),希望数值问题不会成为问题,但显然情况并非如此。
但是:我想在我的C代码中解决这个问题,而不需要调用像LAPACK这样的库,因为将它移植到纯C的全部原因是为了让它在目标系统上运行。此外,我想了解这个问题,而不是只是喊出一个黑匣子。如果可能的话,最终我也希望它以单精度运行。
所以,我的问题是,对于这样一个小矩阵,是否有一个数值上更稳定的方法来计算A的逆?
谢谢。
编辑:目前试图找出我是否可以只avoid the inversion通过解决C
。
它在什么意义上爆炸?数字溢出?矩阵元素是什么类型,有哪些值? – fge
回答fge的问题会有所帮助。这里也有可能被零除,这可能会导致你的“爆炸”。 – greg
对不起,如果我不清楚,爆炸不是直接来自这个操作,而是从这个操作引入的错误到一个反馈函数,我没有在这里描述。 – Steve