在MATLAB中乘以两个非常大的稀疏矩阵时出现内存不足错误

时间:2016-02-04 02:05:50

标签: matlab sparse-matrix matrix-multiplication

我有一个非常大的稀疏高matrixA大小(M x NM>>>>> N) 以及matrixB

的其他N x 1

我想做

MatrixA*MatrixB 

并获得M x 1输出。但是我得到了一个内存不足的错误。矩阵只有100个非零元素。这是怎么回事?

2 个答案:

答案 0 :(得分:2)

正如@patrik在现在删除的答案中所指出的那样,问题是MATLAB按列而不是元素存储稀疏矩阵。这意味着稀疏矩阵的空列占用了少量内存,并且巨大数量的空列占用了过多的内存,即使整个非零元素相当少。你的一条评论的相应引用:

  

whos其中一个变量是MatrixA 31679201751184x290953480 double sparse

我相信我的说法" 巨大的"有点轻描淡写。

由于您在评论中注意到您的矩阵,尤其是第二个矩阵,包含非常少数非零元素,因此它可能更快,但绝对可行且内存效率更高自己实现矩阵产品。

使用find选择矩阵的非零索引,然后循环遍历矩阵的这些非零值以构造矩阵乘积。你唯一需要的是(使用一些基于数学的伪代码)

[MatrixA * MatrixB](m,l) = sum_k MatrixA(m,k)*MatrixB(k,l)

你需要的指数都来自向量

[kvec, lvec] = find(MatrixB);
[mvec, ~] = find(MatrixA);

尤其在你的情况下,lvec方面会非常轻松。在一些预分配之后,应该直接循环mveclvec,在此过程中总结关于kvec元素的必要条款。

如果您的matrixB确实只是一个列向量,那么您的工作就更容易了:那么您需要

[MatrixA * MatrixB](m,1) = sum_k MatrixA(m,k)*MatrixB(k,1)

你基本上需要

k1vec = find(MatrixB);
[mvec, k2vec] = find(MatrixA);

%// choose those 'k' indices which are nonzero in both matrices
both_k = intersect(k1vec,k2vec);
inds_A = ismember(k2vec,both_k);
inds_B = ismember(k1vec,both_k);
mvec = mvec(inds_A);
k2vec = k2vec(inds_A);
k1vec = k1vec(inds_B);

然后在预分配后构建产品向量。

答案 1 :(得分:0)

仅供参考:如果你的N足够小,我发现这个实现工作得更快

function out = sparseMult(MatrixA, MatrixB)
out = sparse(size(a,1),1);
k1vec = find(b');
for i = k1vec
    out = out + a(:,i).*b(i);
end
end