1

多数の 2 行 2 列の行列 S1、S2、...、SN があり、これらの各行列で、R*S*R^T のように左右の行列乗算を実行したいと考えています。ここで、R はも 2 行 2 列の行列です。明らかに、これを for ループで書くこともできますが、MATLAB の大きな N では非常に遅くなると予想されます。for ループを使用せずにこれを達成する簡単で効率的な方法はありますか? 前もって感謝します!

4

2 に答える 2

4

あなたの最大の問題はループではありません。行列が非常に小さい場合、MATLAB を呼び出すとA*B多くのオーバーヘッドが発生します。できる最善の方法は、すべての行列を大きな行列に格納4 x n_matricesし、行列の乗算を手動で綴ることです。

A = rand(4, 1000);
B = rand(4, 1000);

tic;
C = zeros(size(A));
C(1,:) = A(1,:).*B(1,:) + A(3,:).*B(2,:);
C(2,:) = A(2,:).*B(1,:) + A(4,:).*B(2,:);
C(3,:) = A(1,:).*B(3,:) + A(3,:).*B(4,:);
C(4,:) = A(2,:).*B(3,:) + A(4,:).*B(4,:);
toc

Elapsed time is 0.020950 seconds.

ご覧のとおり、これにはほとんど時間がかかりません (これは 6 年前のデスクトップ PC です)。このような小さな行列の場合、これは実用的であり、MATLAB で記述されたもので、パフォーマンスの点でこれに勝るものは他にありません。非常に多数の2x2行列の場合、キャッシュの再利用を強化するためにブロッキングを導入できます (つまり、一度に多数の行列のみを処理します)。

于 2012-11-22T16:29:26.457 に答える
0

ここでのサイクルはそれほど悪くなく、遅くもありません。これを考慮してください

N = 1000000
S = cell(1,N);
Out = S;
A = rand(2);
B = rand(2);

for i = 1 : N     
    S{i} = rand(2);
end

tic
for i = 1 : N
    Out{i} = A * S{i} * B;    
end
toc

tic
  f = @(i) A*i*B;
  Out = cellfun(f,S,'UniformOutput' , false);  
toc


  N =

 1000000

   Elapsed time is 2.609569 seconds.
   Elapsed time is 9.871200 seconds.

2x2 行列を実行してから、2 つの乗算だけを実行することを考えるかもしれませんcat(途中で正しく転置します)。しかし、あなたはcatティンで時間を失うでしょう。

于 2012-11-22T16:28:37.130 に答える