2

Matlab では、「ndgrid」を使用して 6D マトリックスを作成しています。コードは次のとおりです。

for i=1:3
    dd{i}=[0 0 0 0 0 0 0 1 1 1 1 1];
    ss{i}=[0 0 0 0 0 0 1 1 1 1 1 1];
end 
[D1 D2 D3 S1 S2 S3] = ndgrid(dd{1},dd{2},dd{3},ss{1},ss{2},ss{3});
out = D1.*S1.*D2.*S2.*D3.*S3;   

私が抱えている問題は、1 つまたは 2 つの 6-D 行列を格納するための十分なメモリがありますが、6 つの行列すべてを格納するのに十分なメモリがないことです。

[D1 D2 D3 S1 S2 S3] 

ご覧のとおり、行列 D1、D2... および "out" は本質的にスパースですが、Matlab の "スパース" 機能は多次元配列では機能しません。Matlab で他の「グリッド」機能を検索しましたが、D1、D2 などを計算する中間ステップを回避するのに役立つ「グリッド」機能が見つかりません。

一般に、dd{1} が dd{2} と異なることを許可したいと考えています。また、私が投稿したこの 6-D のケースはメモリをあまり消費しませんが、8-D のケースはメモリを消費し、問題が発生しています。

この状況でメモリをより効率的に使用するためのヘルプは大歓迎です。

4

2 に答える 2

1

これは、ループがほぼ確実に高速になる (そして収まる!) 場合です。これは、メモリに制約があるためです。ネストされた 6 (または 8) の for ループを使用し、 の各要素をout一度に 1 つずつドロップします。ネストされたループ インデックスを使用して、ソース ベクトルを直接参照します。正しいインデックスと正しいベクトルが一致していることを確認してください。これにより、出力配列の最大サイズのみに制限されます。

新しいアイデアで編集:

bsxfun2 つの引数しか受け付けないことを除けば、これはまさに正しいことをするだろうと思いました。基本的に、必要に応じてシングルトン ディメンション間でレプリケートします。bsxfun中間結果がフルサイズに戻るため、ペアワイズネスト呼び出しは無意味です。しかし、これは次元を半分に減らす優れた方法であり、ベキ項にとっては大きな問題です。

[D1 D2 D3] = ndgrid(dd{1},dd{2},dd{3});
[S1 S2 S3] = ndgrid(ss{1},ss{2},ss{3});
out = bsxfun(@times, D1.*D2.*D3, reshape(S1.*S2.*S3, [1 1 1 12 12 12]));

明らかに、12 は動的サイズに置き換える必要があります。これで、D*N^D 要素の代わりに、D*N^(D/2) だけが必要になります。14 次元または 16 次元に戻るまで、メモリの問題は発生しません。

于 2012-11-16T15:45:01.137 に答える
0

編集:線形インデックスを使用して、すばやくすばやく行う方法を見つけました。

out=D1(:) %Initialize out to give it the right dimensions, bit ugly perhaps

out(:) = D1(:).*S1(:).*D2(:).*S2(:).*D3(:).*S3(:);  
于 2012-11-16T15:47:45.810 に答える