Matlab 是否存在访问稀疏矩阵中元素的开销
假设我有一个稀疏矩阵a,我想对它做大量的计算。计算不修改A,只访问其元素,例如,取A的一行,然后与某物相乘。我想知道在进行任何计算之前,是应该将A转换为完整矩阵,还是直接进行?Matlab 是否存在访问稀疏矩阵中元素的开销,matlab,matrix,sparse-matrix,overhead,Matlab,Matrix,Sparse Matrix,Overhead,假设我有一个稀疏矩阵a,我想对它做大量的计算。计算不修改A,只访问其元素,例如,取A的一行,然后与某物相乘。我想知道在进行任何计算之前,是应该将A转换为完整矩阵,还是直接进行? 换句话说,访问稀疏矩阵中的元素是否比访问完整矩阵慢?在MATLAB中跨列切片稀疏矩阵比跨行切片快得多。因此,您应该更喜欢访问M(:,i)而不是M(i,:) MATLAB内部使用(CSC)存储: 非零元素存储在一维双数组中,长度nzmax,按(pr表示实部,pi表示虚部,如果矩阵为复数) ir具有相应行索引的整数数组 j
换句话说,访问稀疏矩阵中的元素是否比访问完整矩阵慢?在MATLAB中跨列切片稀疏矩阵比跨行切片快得多。因此,您应该更喜欢访问
M(:,i)
而不是M(i,:)
MATLAB内部使用(CSC)存储:
- 非零元素存储在一维双数组中,长度
,按(nzmax
表示实部,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的索引):
要检索稀疏矩阵的第i列M(:,i)
,只需执行以下操作即可:pr(jc(i):jc(i+1)-1)
(为了保持简单,我不关注基于0和1的索引)。另一方面,访问矩阵行涉及更多的计算和数组遍历(不再友好)
以下是MATLAB文档的一些链接,以获取更多信息:
值得一看的是John R.Gilbert、Cleve Moler和Robert Schreiber的《Matlab中的稀疏矩阵:设计与实现》(SIAM Journal on Matrix Analysis and Applications,13:1333–356(1992)) 以下是上述论文中的一些引文,以回答您关于稀疏存储开销的问题: 简单数组操作的计算复杂性应该是 与
nnz
成比例,也可能与m
或n
成线性关系,
但必须独立于产品m*n
。更多信息的复杂性
复杂的操作涉及订购、填写等因素,
但好的稀疏矩阵算法的目标应该是:
稀疏矩阵运算所需的时间应成比例
对非零量进行算术运算的次数
我们称之为“时间与失败成正比”规则;这是一个
我们设计的基本原则
及
这种(面向列的稀疏矩阵)方案效率不高
用于一次操作元素上的矩阵:访问单个
元素所花费的时间至少与元素的对数成正比
柱的长度;插入或删除非零可能需要
广泛的数据移动。但是,元素对元素的操作是不正确的
在MATLAB中很少见(即使在完整的MATLAB中也很昂贵)。这是最常见的
应用程序将是创建一个稀疏矩阵,但这更重要
通过在列表中建立矩阵元素的列表来高效地完成
任意顺序,然后使用稀疏(i,j,s)
创建矩阵
稀疏数据结构允许在
矩阵最后一列的末尾。因此,建立
一次一列的矩阵可以通过
在开始时为所有预期的非零分配足够的空间
此外,第3.1.4节“渐进复杂性分析”也应该引起关注(此处引述太长)。如果您有足够的内存将
A
转换为full
,为什么您需要sparse
?跨列切片稀疏矩阵比按行切片快得多,考虑到数据是如何存储的,这是可以理解的internally@Luis:我正在使用的服务器有足够的内存,但其他用户也在使用它,因此我认为使用尽可能少的资源会更好。此外,我还将该矩阵(在稀疏模式下)保存到mat文件中(它确实为我节省了一些空间)。现在我把它装回去,想知道是否应该把它转换成一个完整的矩阵。@Amro+1:这很有趣。我刚刚在这个链接中发现了类似的信息:您可能会发现和,包括链接的引用很有趣。虽然它没有回答我的问题(我的问题是比较稀疏矩阵和完整矩阵的检索元素),我对这一点很满意。根据Amro的回答——如果它真的是稀疏矩阵中的行——将其转置,并从转置形式中提取列。或者更好——使用探查器查看实际发生的情况!
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