使用Eigen :: CholmodSupernodalLLT时如何提取matrixL()和matrixU()?

时间:2019-04-18 11:09:30

标签: c++ eigen

我正在尝试使用Eigen::CholmodSupernodalLLT进行Cholesky分解,但是,似乎无法获得matrixL()matrixU()。如何从matrixL()中提取matrixU()Eigen::CholmodSupernodalLLT以便将来使用?

3 个答案:

答案 0 :(得分:1)

部分答案,以整合他人的言论。

考虑 Y〜MultivariateNormal(0,A)。人们可能想要(1)评估(对数)似然度(多元正常密度),(2)从这种密度中采样。

对于(1),有必要求解 Ax = b ,其中 A 是对称正定的,并计算其对数行列式。 (2)要求 L 使得 A = L * L.transpose(),因为 Y〜MultivariateNormal(0,A)可以找到 Y = L u 其中 u〜MultivariateNormal(0,I)

Cholesky LLT或LDLT分解很有用,因为chol(A)可以同时用于两种目的。给定分解即可轻松解决Ax=b,并且可以很容易地从D的(log-)分量的对和积或L的对角线得出(log)行列式。根据定义, L 可用于采样。

因此,在Eigen中,可以使用:

  • Eigen::SimplicialLDLT solver(A)(或Eigen::SimplicialLLT),当solver.solve(b)并使用solver.vectorD().diag()计算行列式时。很有用,因为如果A是协方差矩阵,则solver可用于似然评估,matrixL()可用于采样。

  • Eigen::CholmodDecomposition不能访问matrixL()vectorD(),但可以暴露.logDeterminant()来实现(1)目标,但不能实现(2)。

  • Eigen::PardisoLDLT不能访问matrixL()vectorD(),也没有提供获取行列式的方法。

在某些应用中,可以在以后的步骤中进行步骤(2)(即采样),因此Eigen::CholmodDecomposition就足够了。至少在我的配置中,Eigen::CholmodDecomposition的工作速度比Eigen::SimplicialLDLT高2至5倍(我想是因为在后台进行了排列以促进并行化)

示例:在贝叶斯空间高斯过程回归中,可以将空间随机效应积分出来,而无需进行采样。因此,MCMC可以迅速进行Eigen::CholmodDecomposition来实现未知参数的收敛。然后可以使用Eigen::SimplicialLDLT并行恢复空间随机效应。通常,这只是计算的一小部分,但直接来自matrixL()的{​​{1}}会稍微简化它们。

答案 1 :(得分:0)

您不能使用给定的类执行此操作。您要引用的类是引用求解器(确实使用cholesky分解)。要分解矩阵,您应该使用Eigen::LLT。他们网站上的代码示例:

MatrixXd A(3,3);
A << 4,-1,2, -1,6,0, 2,0,5;
LLT<MatrixXd> lltOfA(A);
MatrixXd L = lltOfA.matrixL(); 
MatrixXd U = lltOfA.matrixU(); 

答案 2 :(得分:0)

例如somewhere else,例如,这并不容易做到。 我正在复制一个可能的建议(由Gael Guennebaud亲自回答),即使有些老:

  

如果您确实需要自己做饭的因素,那么   最好使用内置的SimplicialL{D}LT<>类。提取   Cholmod / Pardiso超节点内部表示的一些因素   确实不是那么简单,而且很少需要。我们必须   检查,但Cholmod / Pardiso是否提供例程来操作   因素,例如将其应用于向量,那么我们可以让   matrix{L,U}()返回包装这些例程的伪表达式。

开发用于提取代码的代码可能超出SO的范围,并且可能是a feature request的主题。

当然,LLT的解决方案就在眼前(但不是OP的主题)。