我们说我有一个稀疏矩阵A.我想对它做大量计算。计算不修改A,只访问其元素,例如取一排A然后乘以某物。我想知道在进行任何计算之前是否应该将A转换为完整矩阵,或者只是直接进行? 换句话说,访问稀疏矩阵中的元素比完整矩阵慢吗?
答案 0 :(得分:5)
跨列切片稀疏矩阵比在MATLAB中切片行快得多。因此,您应该更喜欢通过M(:,i)
访问M(i,:)
。
内部MATLAB使用Compressed Sparse Column(CSC)存储:
nzmax
的1-D双数组中,排列在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);
这就像存储在内存中一样(我在ir
和jc
使用基于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 Matrices,Manipulating Sparse Matrices
值得查看 John R. Gilbert,Cleve Moler和Robert Schreiber的original paper:" Matlab中的稀疏矩阵:设计与实现",( SIAM Journal on Matrix Analysis and Applications,13:1,333-356(1992))。
以上是上述文章的一些引用,以回答有关稀疏存储开销的问题:
简单数组操作的计算复杂性应该是 与
nnz
成比例,也可能在m
或n
上线性相关, 但要独立于产品m*n
。复杂性更多 复杂的操作涉及订购和填写等因素, 但是一个好的稀疏矩阵算法的目标应该是:稀疏矩阵运算所需的时间应该是成比例的 对非零数量的算术运算次数。
我们称之为"时间与翻牌成正比#34;规则;它是一个 我们设计的基本原则。
和
这个(面向列的稀疏矩阵)方案效率不高 用于一次操作元素上的矩阵:访问单个 元素花费的时间至少与对数成正比 柱长;插入或删除非零可能需要 广泛的数据运动。但是,逐个元素操作是 在MATLAB中很少见(即使在完整的MATLAB中也很昂贵)。最常见的 应用程序将创建一个稀疏矩阵,但这更多 通过在其中构建列表
[i,j,s]
矩阵元素来有效地完成 任意顺序,然后使用sparse(i,j,s)
创建矩阵。允许稀疏数据结构在之后具有未使用的元素 矩阵的最后一列的结尾。因此构建的算法 一次一个矩阵可以有效地实现 在开始时为所有预期的非零值分配足够的空间。
第3.1.4节"渐近复杂度分析"应该是有意义的(这里引用的时间太长了。)