我想计算一个非常大的矩阵(5e6 x 5e6)的对数行列式。然而,它非常稀疏 - 每行只有6个非零项(7个对角线计数)。它也是对称和肯定的。
在Eigen中我试图使用Cholesky分解:SimplicialLDLT<SparseMatrix<double>>
然后对对角线的对数值求和(可以通过SimplicialLDLT::vectorD()
访问)但是分解运行了很长时间而没有完成。有更好的方法吗?我实际上并不需要任何类型的分解,只需要log-determinant本身(或一个好的估计)。
答案 0 :(得分:0)
您期望多快?您可以尝试版本3.3-beta1中的所有稀疏求解器,并找到哪一个更快的问题。
https://eigen.tuxfamily.org/dox-devel/group__TopicSparseSystems.html
答案 1 :(得分:0)
我不妨把它作为答案,这样我就可以展示一个数字。
首先, Eigen的documentation on sparse solvers说SimplicialLDLT
是“推荐用于非常稀疏且不太大的问题”。你的问题非常稀少但也非常大。
其次, SimplicialLDLT
需要的输入不仅仅是对称的(“自我联接”),而且还需要肯定的,你的几乎肯定不是(除非你有理由不这样做?)
SimplicialLDLT
有可能花费大量时间来计算Cholesky分解 - 由于矩阵不是正定的,因此无法成功找到它。
这让我有了一个第三点。我生成了in Matlab ,你的问题的一个小版本:1e4乘1e4稀疏矩阵,对称,在1和5之间的对角线上有小整数,每行有六个其他-1的条目。 Matlab相当于LDLT是ldl
,奇怪的是它不需要正定矩阵,所以它在几秒钟内通过我的1e4 1E4示例咀嚼(生成稀疏矩阵需要更长时间而不是分解它)进入LDL')。
这是下三角因子的稀疏模式(在Matlab中通过spy(L)
):
它有1e7个非零元素,占用162 MB RAM。回想一下这是针对1e4乘1e4的问题。如果内存使用量与矩阵的长度成线性关系(1e4→5e6),那么您将看到近80 GB的RAM使用率。相反,它会随着元素的数量(1e4 ^ 2→5e6 ^ 2)而缩放,你需要38 TB RAM ......这个分析都没有结论 - 很可能是5e6缩小到5e6会大大增加LDL的稀疏性因素,但这可以解释为什么Eigen挂起。如评论中所述,请检查您的交换文件是否正在颠倒。
第四个问题是,对于我的1e4乘1e4的测试示例,我在下三角形L
矩阵的对角线上有很多完全为零的条目,所以行列式整个稀疏矩阵的值为零到双精度,记录或没有记录。