Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 行列式为零的N×N矩阵的(伪)逆_C++_Matrix_Lapack_Eigen_Slam Algorithm - Fatal编程技术网

C++ 行列式为零的N×N矩阵的(伪)逆

C++ 行列式为零的N×N矩阵的(伪)逆,c++,matrix,lapack,eigen,slam-algorithm,C++,Matrix,Lapack,Eigen,Slam Algorithm,我想取一个nxn矩阵的逆矩阵,用在我的GraphSlam中 我遇到的问题是: .inverse()Eigen库(3.1.2)不允许零值,返回NaN LAPACK(3.4.2)库不允许使用零行列式,但允许使用零值(使用的示例代码来自) 由于某种原因,Seldon库(5.1.2)无法编译 是否有人成功地实现了一个允许负值、零值和零行列式的nxn矩阵求逆代码?有什么好的库(C++)推荐吗 我试着用下面的公式来计算图表lam的ω: 简单的例子: [ 1 -1 0 0 ] [ -1 2 -1 0

我想取一个nxn矩阵的逆矩阵,用在我的GraphSlam中

我遇到的问题是:

  • .inverse()
    Eigen库(3.1.2)不允许零值,返回
    NaN
  • LAPACK(3.4.2)库不允许使用零行列式,但允许使用零值(使用的示例代码来自)
  • 由于某种原因,Seldon库(5.1.2)无法编译
是否有人成功地实现了一个允许负值、零值和零行列式的nxn矩阵求逆代码?有什么好的库(C++)推荐吗

我试着用下面的公式来计算图表lam的ω:


简单的例子:

[ 1 -1  0 0 ]
[ -1 2 -1 0 ]
[ 0 -1  1 0 ]
[ 0  0  0 0 ]
实际示例是170x170,包含0、负值和更大的正值。 给出的简单示例用于调试代码


我可以在Matlab中计算(Moore Penrose伪逆),但是由于某种原因,我不能在C++中编程。< /P>

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:

所以去掉第四列和第四行不会得到零行列式。 但如果我的矩阵如上所述,我仍然可以有一个零行列式。 当每一行或每一列的总和为零时,会发生这种情况。(我将一直在GraphSlam中使用它)

如果行列式不是零(使用示例代码),则LAPACK解决方案(基于Moore-Penrose逆)有效。
但作为行列式为零的“伪逆”失败。


解决方案:(全部归功于Frank Reininghaus),使用SVD(奇异值分解)


与以下机构合作:

  • 零值(即使是完整的0行和完整的0列)
  • 负值
  • 零行列式
A^-1:


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

如果矩阵的行列式为非零(),那么它只有一个逆矩阵,而你在问题中发布的矩阵示例,则它没有逆矩阵


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

您的Matlab命令在您的情况下不会计算逆,因为矩阵具有确定零。
pinv
COMMAND命令计算出的值
pinv(A)
具有
inv(A)
的部分但不是全部属性

<>你在C++和MATLAB中不做同样的事情! 以前的

正如我的评论。现在作为答案。你必须确保你是可逆矩阵。这意味着

det A!=0


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


例如,如果一个给定的矩阵有整行或整列的零项,则行列式为零。

如果您只想解决Ax=B形式的问题(或等效计算a^-1*B形式的乘积),那么我建议您不要计算a的逆或伪逆,但使用适当的秩显示解算器直接求解Ax=b。例如,使用Eigen:

x = A.colPivHouseholderQr().solve(b);
x = A.jacobiSvd(ComputeThinU|ComputeThinV).solve(b);

如果你的矩阵是协方差矩阵或权重矩阵,你可以用“广义cholesky反演”代替SVD。对于实际应用,结果会更容易接受

高斯消去法有什么错?你能举一个小矩阵的具体例子吗?这些都不能反转?(我假设矩阵是非奇异的。)使用高斯消去法,结果中仍然可能有负值和0值。否?您的示例矩阵的行列式等于零。这不是可逆矩阵。我希望你不要试这个!你能理解这个标题吗?行列式为零的矩阵没有逆矩阵。我的错。对于我的应用程序(GraphSlam),每行上所有值的总和将等于零。但是在他们的代码中,他们仍然能够反转欧米茄矩阵,如果每行的和为零,那就不能说明它的行列式。至少我没有很快看到;-)您正在尝试求解线性方程
X=AY
。你当然可以要求A的倒数作为问题的一般解决方案,这需要
det A=0
。然而,线性方程仍然可以用
a
的零行列式求解。那么解空间的维数大于0。从而将整个子向量空间作为可能的解。我建议先测试行列式,然后决定如何解线性方程:倒数,高斯消去等等。好了,问题就更清楚了,我将开始在C++中挖掘Moore Penrose pseudoinverse。我真的不确定是什么问题。现在我知道我不能使用正态反演,但必须进行伪反演。Matlab使用Moore Penrose伪逆,可以得到下降结果。确切地说,它不是你试图在C++程序中计算的伪逆。
[0.56   -0.12  -0.44]
[-0.12  0.22   -0.11]
[-0.44  -0.11   0.56]
x = A.colPivHouseholderQr().solve(b);
x = A.jacobiSvd(ComputeThinU|ComputeThinV).solve(b);