我有一个巨大的矩阵(584064x5369468),我必须在Matlab中使用稀疏矩阵,但在我的计算中,将值分配给稀疏矩阵非常慢。我迫不及待想要完成它,我该怎么做。
cgm=sparse(584064,5369468);
[Xcp, Ycp, Zcp] = ndgrid(-[1:336],-[1:45],-[1:336]);
% dp my data which is loaded
for sg=1:335
for tg=1:44
for rg=1:335
% ii is a vector i.e the size of ii = 309x1
fprintf('Constructing patch: %i %i %i',sg,tg,rg)
ii=find(abs((Xcp(sg,tg,rg))<=abs(dp(:,1)))&abs((dp(:,1))<abs(Xcp(sg+1,tg,rg)))&(abs(Ycp(sg,tg,rg))<=abs(dp(:,2)))& (abs(dp(:,2))<abs(Ycp(sg,tg+1,rg)))& (abs(Zcp(sg,tg,rg))<=abs(dp(:,3)))&(abs(dp(:,3))<abs(Zcp(sg,tg,rg+1))));
% jj is another vector i.e the size of jj = 64*1
%the ii size is changing every time but the size of jj is always 64. ii is non-zero values and can be between 1 and 584064 .
% c is my matrix after calculation i.e c = 309x64
cgm(ii,jj)=c;
end
end
end
对于第一个内部循环,它变得非常快,但它变得越来越慢,越来越慢。
我知道为稀疏矩阵赋值意味着重新打包所有内容并且速度很慢,但是如何在我的代码中重新打包它?
由于
答案 0 :(得分:4)
正如上面提到的@beaker,正如我在 Accelerating Matlab Performance 一书中解释的那样,使用sparse
或spdiags
函数比使用索引赋值要快得多。你的代码。
原因是任何这样的分配都会导致稀疏数据的内部表示的重建,这需要重新排列的数据元素越来越慢。
相反,您应该将数据索引(ii
和jj
)以及分配的数据(c
)累积到循环中的三个单独数组中,然后 外部 循环使用一次调用sparse(ii,jj,c)
来一次更新矩阵。这会快得多。
有关稀疏数据的其他详细信息和建议,请参阅本书中的第137-140页。