5

我的目标是将许多稀疏矩阵组合在一起形成一个大的稀疏矩阵。我能想到的仅有的两个想法是(1)创建一个大型稀疏矩阵并覆盖某些块,(2)创建单独用于vertcat形成我的最终稀疏矩阵的块。但是,我读到覆盖稀疏矩阵的效率很低,而且我还读到 vertcat 的计算效率并不高。(我都没有考虑使用 for 循环,因为它们效率低下)。

那我还有什么其他选择?

编辑:通过组合我的意思是(垂直)将矩阵“粘合”在一起,元素不会相互作用。

4

2 回答 2

5

根据 matlab 帮助,您可以使用“反汇编”稀疏矩阵

[i,j,s] = find(S);

这意味着如果你有两个矩阵ST,并且你想(有效地)vertcat它们,你可以做

[is, js, ss] = find(S);
[it, jt, st] = find(T);
ST = sparse([is; it + size(S,1)], [js; jt], [ss; st]);

不确定这是否非常有效......但我猜这还不错。

编辑:使用密度为 1% 的 2000x1000 稀疏矩阵,并将其与另一个密度为 2% 的矩阵结合起来,上面的代码在我的机器上运行了 0.016 秒。只是做[S;T]的速度快了 10 倍。是什么让您认为垂直连接很慢?

EDIT2:假设您需要使用“许多”稀疏矩阵执行此操作,则以下工作(假设您希望它们都“在同一个地方”):

m = 1000; n = 2000; density = 0.01;
N = 100;
Q = cell(1, N);
is = Q;
js = Q;
ss = Q;
numrows = 0; % keep track of dimensions so far

for ii = 1:N
    Q{ii} = sprandn(m+ii, n-jj, density); % so each matrix has different size
    [a b c] = find(Q{ii});
    sz = size(Q{ii}); 
    is{ii} = a' + numrows; js{ii}=b'; ss{ii}=c'; % append "on the corner"
    numrows = numrows + sz(1); % keep track of the size
end

tic
ST = sparse([is{:}], [js{:}], [ss{:}]);
fprintf(1, 'using find takes %.2f sec\n', toc);

输出:

using find takes 0.63 sec

这种方法的最大优点是您不需要在各个稀疏数组中具有相同数量的列......它将全部由命令排序,该sparse命令将简单地将丢失的列视为全零。

于 2013-03-14T20:48:50.910 回答
0

考虑到已经给出的答案。

我已经稍微改变了实验,以便能够垂直连接矩阵(它应该具有相同的宽度),所以我们不需要n通过提取来调整ii(由 输入错误jj)。

这种方法

tic
ST = sparse([is{:}], [js{:}], [ss{:}]);
fprintf(1, 'using find takes %.2f sec\n', toc);

0.45 sec比这个慢得多

tic
ST = vertcat(Q{:});
fprintf(1, 'using vertcat takes %.2f sec\n', toc);

平均0.18 sec

我还用分析器检查了它,第一个示例预计会慢一些,因为至少内存分配要高 100 倍。很可能是因为[ss{:}]数组结构明确地将数据复制到新数组中。

然而,即使使用预先计算的向量,速度也是0,3 secvs 0,18 secfor vertcat

因此,我建议这vertcat是原始问题的更好选择。至少在 2021 年 :)

于 2021-05-07T19:46:00.367 回答