特征LDLT Cholesky就地分解

时间:2016-03-29 13:01:17

标签: c++ eigen eigen3 in-place

我试图让Eigen3用就地Cholesky分解求解线性系统A * X = B。我无法承担任何大小为A的临时工具,但在此过程中我可以自由地销毁A

不幸的是,

A.llt().solveInPlace(B);

是不可能的,因为A.llt()隐式地在堆栈上推送大小为A的临时矩阵。对于LLT案例,我可以访问必要的功能,如下所示:

// solve A * X = B in-place for positive-definite A
template <typename AType, typename BType>
void AllInPlaceSolve(AType& A, BType& B)
{
    typedef Eigen::internal::LLT_Traits<AType, Eigen::Upper> TraitsType;
    TraitsType::inplace_decomposition(A);
    TraitsType::getL(A).solveInPlace(B);
    TraitsType::getU(A).solveInPlace(B);
}

这很好,但我很担心:

  • 我的矩阵A可能只是半正的,在这种情况下需要进行LDLT分解
  • LLT分解为系统解决方案不必要地计算sqrt()

我无法找到一种方法来与上面的代码类似地挂钩Eigen的LDLT功能,因为代码的结构非常不同。

所以我的问题是:有没有办法使用Eigen3来解决线性系统使用LDLT分解而不使用划痕空间而不是对角矩阵D

1 个答案:

答案 0 :(得分:0)

一种选择是仅分配一次LDLT求解器,并调用计算方法:

LDLT<MatType> ldlt(size);
// ...
ldlt.compute(A);
x = ldlt.solve(b);

如果这也不是一个选项,你可以构建由ldlt对象存储的矩阵:

LDLT<MatType> ldlt(MatType::Identity(size,size));
MatType& A = const_cast<MatType&>(ldlt.matrixLDLT());

播放A,然后播放:

ldlt.compute(A);
x = ldlt.solve(b);

这很难看,但只要MatType是专栏主,这就应该有效。