(伪) - 具有零行列式的N×N矩阵的逆

Too*_*oon 5 c++ matrix lapack eigen slam-algorithm

我想在我的GraphSlam中使用nxn矩阵的逆.

我遇到的问题:

  • .inverse() 特征库(3.1.2)不允许零值,返回 NaN
  • LAPACK(3.4.2)库不允许使用零行列式,但允许零值(使用C中使用lapack计算矩阵的逆矩阵的示例代码)
  • Seldon库(5.1.2)由于某种原因无法编译

有没有人成功实现了一个允许负值,零值和零行列式的n × n矩阵求逆代码?任何好的库(C++)推荐?

我尝试为GraphSlam计算以下的欧米茄: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 ]
Run Code Online (Sandbox Code Playgroud)

真实的例子是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]
Run Code Online (Sandbox Code Playgroud)

对于我的应用程序,我可以(暂时)删除维度为零.
所以我要删除第4列和第4行.
我也可以为我的170x170矩阵做到这一点,4x4只是一个例子.

A:

[ 1 -1  0 ]
[ -1 2 -1 ]
[ 0 -1  1 ]
Run Code Online (Sandbox Code Playgroud)

因此,删除第4列和第4行不会带来零行列式.但如果我的矩阵如上所述,我仍然可以有一个零行列式.当每行或每列的总和为零时.(我将一直在GraphSlam中拥有)

如果行列式不为零,则LAPACK解决方案(基于Moore-Penrose Inverse)工作(使用来自使用C中的lapack计算矩阵的逆的示例代码).
但作为一个决定性为零的"伪逆"失败了.


解决方案:(所有积分给Frank Reininghaus),使用SVD(奇异值分解)
http://sourceware.org/ml/gsl-discuss/2008-q2/msg00013.html

使用:

  • 零值(甚至完整0行和完整0列)
  • 负值
  • 决定性为零

a ^ -1:

[0.56   -0.12  -0.44]
[-0.12  0.22   -0.11]
[-0.44  -0.11   0.56]
Run Code Online (Sandbox Code Playgroud)

gga*_*ael 7

如果您只想解决Ax = B形式的问题(或等效计算形式A ^ -1*b的产品),那么我建议您不要计算A的逆或伪逆,而是直接求解Ax = b使用适当的等级显示解算器.例如,使用Eigen:

x = A.colPivHouseholderQr().solve(b);
x = A.jacobiSvd(ComputeThinU|ComputeThinV).solve(b);
Run Code Online (Sandbox Code Playgroud)


rit*_*ter 5

您的 Matlab 命令不会计算您的情况的逆矩阵,因为矩阵的行列式为零。该pinv命令计算Moore-Penrose 伪逆pinv(A)具有 的部分但不是全部属性inv(A)

所以你在 C++ 和 Matlab 中做的不是同样的事情!

以前的

正如我的评论中所说。现在作为答案。您必须确保对可逆矩阵进行反转。这意味着

det A != 0

您的示例矩阵的行列式为零。这不是可逆矩阵。我希望你不要尝试这个!

例如,如果给定矩阵的行列式为零,则该矩阵的行列式或整列为零。


je4*_*e4d 2

您确定这是因为零/负值,而不是因为您的矩阵是不可逆的?

如果矩阵的行列式非零(mathworld link),则矩阵仅具有逆矩阵,并且您在问题中发布的矩阵示例具有零行列式,因此它没有逆矩阵。

这应该可以解释为什么这些库不允许您取给定矩阵的逆,但我不能说同样的推理是否适用于您的全尺寸 170x170 矩阵。