12

D が大きいため、単純に対角 D 行 D 列の行列を作成するのに十分なメモリがありません。「メモリ不足」エラーが発生し続けます。

最初の乗算で M x D x D 演算を実行する代わりに、M x D 演算を実行しますが、それでもコードの実行には時間がかかります。

誰でも乗算を実行するためのより効果的な方法を見つけることができますA'*B*Aか? これが私がこれまでに試みたことです:

D=20000
M=25

A = floor(rand(D,M)*10);
B = floor(rand(1,D)*10);

for i=1:D
    for j=1:M
        result(i,j) = A(i,j) * B(1,j);
    end
end    

manual = result * A';
auto = A*diag(B)*A';
isequal(manual,auto)

代替テキスト

4

3 に答える 3

12

問題を解決する 1 つのオプションは、疎行列を使用することです。次に例を示します。

D = 20000;
M = 25;
A = floor(rand(D,M).*10);    %# A D-by-M matrix
diagB = rand(1,D).*10;       %# Main diagonal of B
B = sparse(1:D,1:D,diagB);   %# A sparse D-by-D diagonal matrix
result = (A.'*B)*A;         %'# An M-by-M result

もう 1 つのオプションは、 の主対角に沿って D 要素を複製Bし、関数REPMATを使用して M 行 D 列の行列を作成し、要素ごとの乗算を で使用することA.'です。

B = repmat(diagB,M,1);   %# Replicate diagB to create an M-by-D matrix
result = (A.'.*B)*A;    %'# An M-by-M result

さらに別のオプションは、関数BSXFUNを使用することです。

result = bsxfun(@times,A.',diagB)*A;  %'# An M-by-M result
于 2010-12-12T05:15:42.183 に答える
3
  1. MATLAB が行列全体を収容するのに十分な大きさのメモリのチャンクを見つけることができないため、「メモリ不足」になっています。MATLAB ドキュメンテーションで説明されているこのエラーを回避するためのさまざまな手法があります。

  2. MATLAB では、 operator を使用できるため、ほとんどの場合、明らかに明示的なループをプログラミングする必要はありません*。明示的なループを使用して行列の乗算を高速化する方法が存在します。これは C# の例です。(潜在的に大きな) 行列を小さな行列に分割する方法がよくわかります。これらの小さな行列を MATLAB に含めるには、セル行列を使用できます。システムが 2 つの小さなサブマトリックスを収容するのに十分な RAM を見つけ、結果として得られる大きなマトリックスを見つける可能性がはるかに高くなります。

于 2010-12-12T08:11:58.977 に答える
3

多分私はここでちょっと頭がおかしいのですが、DxD マトリックスを DxM マトリックス (与えられたベクトルの M コピー) に変換してから、.* 最後の 2 つのマトリックスを乗算するのではなく (そしてもちろん、通常は最初の値に見つかった製品の数量を掛けます)?

于 2010-12-12T04:30:07.483 に答える