我在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
给出了相同(错误)的答案。发生了什么事?
答案 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进行了求逆),看到它会很有趣。