我有一个非常大的稀疏高matrixA
大小(M x N
,M
>>>>> N
)
以及matrixB
N x 1
我想做
MatrixA*MatrixB
并获得M x 1
输出。但是我得到了一个内存不足的错误。矩阵只有100个非零元素。这是怎么回事?
答案 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
方面会非常轻松。在一些预分配之后,应该直接循环mvec
和lvec
,在此过程中总结关于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