C ++ Eigen线性系统解决了数值问题吗?

时间:2018-08-22 16:44:18

标签: c++ matlab eigen

我在Eigen中通过线性求解计算得到了意想不到且无效的结果。我有一个向量x和一个矩阵P

在MATLAB表示法中,我正在这样做:

x'/P*x

(类似于x'*inv(P)*x,但没有直接反演)

,它是二次形式,应产生肯定的结果。矩阵P是正定的,没有病态。在MATLAB中,结果虽然很大,但却是肯定的。

在C ++ Eigen中,我的斜杠运算符如下:

x/P的实现方式为:

(P.transpose()).ColPivHouseholderQr().solve(x.transpose).transpose()

通常,这给出了正确的答案,但看起来比MATLAB更脆弱。在我现在看的情况下,它为x'/P*x给出了非常大的负数,好像有溢出和环绕之类的东西。

有办法消除这种脆弱性吗?

编辑:做一些实验,我发现Eigen也无法反转该矩阵,而MATLAB没有问题。矩阵条件编号为3e7,还不错。 Eigen通过线性求解和简单的x.transpose() * P.inverse() * x给出了相同(错误)的答案。发生了什么事?

1 个答案:

答案 0 :(得分:2)

以下错误(除了您在问题中遗漏的()之外):

(P.transpose()).ColPivHouseholderQr().solve(x.transpose()).transpose();

因为

x'*inv(P) = ((x'    *inv(P))')'
          = (inv(P)'* (x')'  )'
          = (inv(P) *  x     )'  % Note: P=P'

在没有-DNDEBUG的情况下构建时,您的表达式实际上应该在Eigen中引发一个断言,因为x.transpose()仅一行,而P(通常)更多。

要计算对称正定x'*inv(P)*x的{​​{1}},我建议使用Cholesky分解P,它为您提供L*L'=P在Eigen中为:

x'*inv(P)*x = (L\x)'*(L\x)

对于矩阵本征无法求逆(Matlab进行了求逆),看到它会很有趣。