【问题标题】:Is there overhead of accessing elements in a sparse matrix访问稀疏矩阵中的元素是否存在开销
【发布时间】:2014-12-09 01:32:50
【问题描述】:

假设我有一个稀疏矩阵 A。我想对其进行大量计算。计算不会修改 A,仅访问其元素,例如取一行 A 然后乘以某物。我想知道是否应该在进行任何计算之前将 A 转换为完整矩阵,还是直接进行?
换句话说,访问稀疏矩阵中的元素是否比完整矩阵慢?

【问题讨论】:

  • 如果你有足够的内存将A转换为full,那你为什么还需要sparse呢?
  • 跨列对稀疏矩阵进行切片比按行切片要快得多,考虑到数据在内部的存储方式,这是可以理解的
  • @Luis:我正在使用的服务器有足够的内存,但其他用户也在使用它,所以我认为使用尽可能少的资源会更好。此外,我确实将该矩阵(在稀疏模式下)保存到一个 mat 文件中(它确实为我节省了一些空间)。现在我把它加载回来,想知道我应该把它转换成一个完整的矩阵。
  • @Amro +1:这很有趣。我刚刚在这个链接中找到了类似的信息:mathengineering.com/understanding-sparse-matrix-storage
  • 您可能会发现 this questionthis answer,包括有趣的链接参考。

标签: matlab matrix sparse-matrix overhead


【解决方案1】:

在 MATLAB 中跨列切片稀疏矩阵比跨行切片要快得多。所以你应该更喜欢访问M(:,i) 而不是M(i,:)

MATLAB 内部使用Compressed Sparse Column (CSC) 存储:

  • 非零元素存储在长度为nzmax 的一维双精度数组中,排列在column-major order 中(pr 用于实部,pi 用于虚部,如果矩阵很复杂)
  • ir 具有相应行索引的整数数组
  • jc 一个长度为n+1(其中n 是列数)的整数数组,其中包含列索引信息。根据定义,jc 的最后一个值包含 nnz(存储的非零数)。

以下面的稀疏矩阵为例:

>> M = sparse([1 3 5 3 4 1 5], [1 1 1 2 2 4 4], [1 7 5 3 4 2 6], 5, 4);

这就是它存储在内存中的样子(我对 irjc 使用基于 0 的索引):

1 . . 2
. . . .
7 3 . .
. 4 . .
5 . . 6

pr = 1 7 5 3 4 2 6
ir = 0 2 4 2 3 0 4
jc = 0 3 5 5 7

nzmax = at least 7
nnz = 7
m = 5
n = 4

要检索稀疏矩阵M(:,i) 的第 i 列,只需执行以下操作:pr(jc(i):jc(i+1)-1)(为简单起见,我不关注基于 0 和 1 的索引)。另一方面,访问矩阵行涉及更多的计算和数组遍历(它不再对spatial-locality 友好)。

这里有一些指向 MATLAB 文档的链接以获取更多信息:Sparse MatricesManipulating Sparse Matrices


值得查看 John R. Gilbert、Cleve Moler 和 Robert Schreiber 撰写的 original paper:“Matlab 中的稀疏矩阵:设计和实现”,(SIAM 矩阵分析和应用杂志,13:1 , 333–356 (1992)).

以下是上述论文中的一些引用,用于回答您关于稀疏存储开销的问题:

简单数组运算的计算复杂度应该是 与nnz 成正比,也许还线性依赖于mn, 但要独立于产品m*n。更多的复杂性 复杂的操作涉及到订购和填写等因素, 但是一个好的稀疏矩阵算法的目标应该是:

稀疏矩阵运算所需的时间应该成正比 对非零量的算术运算次数。

我们称之为“时间与失败成正比”规则;它是一个 我们设计的基本原则。

这个(面向列的稀疏矩阵)方案效率不高 一次操作元素上的矩阵:访问单个 元素花费的时间至少与 其列的长度;插入或删除非零可能需要 广泛的数据移动。但是,逐个元素的操作是 在 MATLAB 中很少见(即使在完整的 MATLAB 中也很昂贵)。它最常见 应用程序将创建一个稀疏矩阵,但这更多 通过构建矩阵元素列表[i,j,s] 来有效地完成 任意顺序,然后使用sparse(i,j,s) 创建矩阵。

稀疏数据结构允许在 矩阵最后一列的结尾。因此,建立了一个算法 一次一列的矩阵可以通过以下方式有效地实现 一开始就为所有预期的非零值分配足够的空间。

第 3.1.4 节“渐近复杂性分析”也应该很有趣(这里引用太长了)。

【讨论】:

  • 虽然它没有回答我的问题(我的问题是在检索元素方面比较稀疏矩阵和完整矩阵),但我对这个很满意。
  • 继续 Amro 的回答 - 如果它真的是你想要的稀疏矩阵中的行 - 转置它并从转置形式中提取列。或者更好的是 - 使用分析器查看实际情况!
猜你喜欢
  • 1970-01-01
  • 2021-12-30
  • 2013-02-13
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多