将稀疏矩阵乘积计算为密集结果

计算科学 矩阵 稀疏矩阵 密集矩阵
2021-12-20 06:53:14

我需要组装一个矩阵(密集形式,中等大小,例如维度 1000),它最容易表示为几个 (4) 稀疏矩阵的乘积。这些矩阵最容易通过它们的动作来表达(矩阵向量乘法例程),尽管我认为明确地写出它们并不难。

我的问题是计算乘积的最佳方法是什么,请记住,无论如何,结果最终都会存储为密集矩阵。显然,将所有内容表示为密集矩阵并计算乘积似乎效率低得离谱,因为中间体仍然非常稀疏。

更多细节:矩阵的实际形式类似于 其中是网格邻接矩阵(每行只有两个非零),是带宽低于 10 的带状矩阵。

A=DBDHC
DBC

2个回答

如果你真的想要密集矩阵乘积的所有条目,你可以通过计算单位矩阵列上的动作来逐列计算它。

由于这个问题是很久以前提出的,我将给出详细的概述答案。

第一个问题是组装后的矩阵将如何使用,因为矩阵本身的构造很少是目标。在问题中,明确定义了最终需要有一个密集矩阵。但是,出于某些目的,使用密集矩阵而不是将其分解为多个矩阵可能是有害的,应该避免。最简单的例子是使用迭代求解器求解线性方程组。A

现在,如果密集矩阵的构造是不可避免的和\或其他算法需要的,那么您有几个选择。

  • 正如限幅器指出的那样,密集矩阵的条目可以通过将矩阵向量积应用于单位矩阵的列来逐列手动计算:,其中单位矩阵通过这种方式,您将能够避免形成密集的中间结果并利用的稀疏性。AD(B(DH(CIn)))InnDBC
  • 根据您使用的工具,矩阵库已经可以支持稀疏矩阵矩阵产品。比如一个常用的基于模板的库 Eigen 自然会支持这样的产品。
  • 明确使用一些 SparseBLAS 实现。例如,英特尔 MKL 现在支持子程序mkl_?csrmultcsrmkl_?csrmultd计算两个稀疏矩阵的乘积,并将结果分别存储为稀疏 CSR 或密集格式。

使用一些 SparseBLAS 实现的优点是为矩阵运算提供了经过良好优化和调试的代码,已经内置了并行化的潜力。但是,对于您感兴趣的稀疏模式和问题大小,需要将其与基于 MVP 的解决方案进行基准测试。使用类似 Eigen 的库是最简单的选择,尽管您将缺乏很多控制并且可能会损失一些性能,尤其是如果对于那些特定的功能,Eigen 不使用外部 BLAS/LAPACK 引擎并且仅依赖于它自己的实现。