我想在我的GraphSlam中使用nxn矩阵的逆矩阵。
我遇到的问题:
.inverse()
特征库(3.1.2)不允许零值,返回NaN
是否有人成功实现了 n x n 矩阵反转代码,允许负值,零值和零行列式?任何好的库(C ++)建议?
我尝试为GraphSlam计算以下的omega: http://www.acastano.com/others/udacity/cs_373_autonomous_car.html
简单示例:
[ 1 -1 0 0 ]
[ -1 2 -1 0 ]
[ 0 -1 1 0 ]
[ 0 0 0 0 ]
真实的例子是170x170并包含0,负值,更大的正值。 给出简单的示例用于调试代码。
我可以在matlab(Moore-Penrose pseudoinverse)中计算出来,但由于某种原因,我无法用C ++编程。
A = [1 -1 0 0; -1 2 -1 0; 0 -1 1 0; 0 0 0 0]
B = pinv(A)
B=
[0.56 -0.12 -0.44 0]
[-0.12 0.22 -0.11 0]
[-0.44 -0.11 0.56 0]
[0 0 0 0]
对于我的应用程序,我可以(暂时)删除尺寸为零的尺寸
所以我要删除第4列和第4行。
我也可以为我的170x170矩阵做到这一点,4x4只是一个例子。
A:
[ 1 -1 0 ]
[ -1 2 -1 ]
[ 0 -1 1 ]
因此删除第4列和第4行不会带来零行列式。
但如果我的矩阵如上所述,我仍然可以有一个零行列式。
当每行或每列的总和为零时。 (我将一直在GraphSlam中使用)
如果行列式不为零,则LAPACK解决方案(基于Moore-Penrose Inverse)工作(使用来自Computing the inverse of a matrix using lapack in C的示例代码)。
但作为具有零行列式的“伪逆”失败。
解决方案:(所有积分给Frank Reininghaus),使用SVD(奇异值分解)
http://sourceware.org/ml/gsl-discuss/2008-q2/msg00013.html
适用于:
一个^ -1:
[0.56 -0.12 -0.44]
[-0.12 0.22 -0.11]
[-0.44 -0.11 0.56]
答案 0 :(得分:7)
如果您只想解决Ax = B形式的问题(或者等效地计算A ^ -1 * b形式的产品),那么我建议您不要计算A的逆或伪逆,但是使用适当的等级显示求解器直接求解Ax = b。例如,使用Eigen:
x = A.colPivHouseholderQr().solve(b);
x = A.jacobiSvd(ComputeThinU|ComputeThinV).solve(b);
答案 1 :(得分:4)
您的Matlab命令不会在您的情况下计算逆,因为矩阵的确定为零。 pinv
命令会计算Moore-Penrose pseudoinverse。 pinv(A)
具有inv(A)
的一些属性,但不是全部属性。
所以你在C ++和Matlab中没有做同样的事情!
的上一页强> 的
正如我的评论一样。现在回答。您必须确保反转可逆矩阵。这意味着
det A != 0
您的示例矩阵的行列式等于零。这不是可逆矩阵。我希望你不要尝试这个!
例如,如果存在零行的完整行或列,则给定矩阵的行列式为零。
答案 2 :(得分:2)
你确定这是因为零/负值,而不是因为你的矩阵是不可逆的吗?
如果矩阵的行列式非零(mathworld link),并且您在问题has a zero determinant中发布了矩阵示例,那么它只有一个逆矩阵,因此它没有逆。
这应该解释为什么那些库不允许你采用给定矩阵的逆矩阵,但我不能说你的全尺寸170x170矩阵是否有相同的推理。
答案 3 :(得分:0)
如果你的矩阵是一种协方差或权重矩阵,你可以使用“广义cholesky反演”而不是SVD。结果将更适合实际使用