5

私の目標は、多くの疎行列を組み合わせて 1 つの大きな疎行列を形成することです。私が考えることができた唯一の2つのアイデアは、(1)大きな疎行列を作成し、特定のブロックを上書きする、(2)vertcat最終的な疎行列を形成するために個別に使用するブロックを作成することです。ただし、スパース行列の上書きは非常に非効率的であると読んだことがあります。また、vertcat は正確に計算効率的ではないことも読みました。(for ループは効率が悪いので、どちらも for ループの使用を検討しませんでした)。

その場合、他にどのような選択肢がありますか?

編集:結合とは、マトリックスを(垂直に)「接着」することを意味し、要素は相互作用しません。

4

2 に答える 2

5

matlabのヘルプによると、スパース行列を「逆アセンブル」できます

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

これは、2 つの行列SとがありT、それらを (効果的に) したい場合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 に答える