要素を行列の部分行列に割り当てる for ループをベクトル化する賢い方法はありますか?
最初は、2 つの for ループがありました。
U=zeros(6*(M-2),M-2);
for k=2:M-3
i=(k-1)*6+1;
for j=2:M-3
U(i:i+5,j)=A*temp(i:i+5,j)+B*temp(i:i+5,j-1)+C*temp(i:i+5,j+1)+D*temp(i-6:i-1,j)+E*temp(i+6:i+11,j);
end
end
次に、内側のループをベクトル化して、コードが読み取れるようにしました。
U=zeros(6*(M-2),M-2);
j=2:M-2;
for k=2:M-3
i=(k-1)*6+1;
U(i:i+5,j)=A*temp(i:i+5,j)+B*temp(i:i+5,j-1)+C*temp(i:i+5,j+1)+D*temp(i-6:i-1,j)+E*temp(i+6:i+11,j);
end
これにより CPU 時間が 90% 以上短縮されたので、外側のループでも同じことができるかどうか疑問に思いましたが、U マトリックス内の (6x1) マトリックスに割り当てるため、少し難しいようです。私は試した
U=zeros(6*(M-2),M-2);
k=2:M-3;
i=(k-1)*6+1;
j=2:M-2;
U(i:i+5,j)=A*temp(i:i+5,j)+B*temp(i:i+5,j-1)+C*temp(i:i+5,j+1)+D*temp(i-6:i-1,j)+E*temp(i+6:i+11,j);
i:i+5 は必要な最初の 6 つのインデックスしか取得しないためです。
また、 reshape() 関数を使用して行列をベクトルに変換しようとしましたが、要素の複数のブロックを一度に割り当てるのはまだ難しいようです。コードにはそのような for ループが全部で 3 つあるので、代替の最適化は何らかの形でそれらを並列化することだと思います。ただし、並列ツールボックスにアクセスできない場合は、可能であればベクトル化が適切なソリューションのように思えます。
このコードは、グリッド上の 6 つの連立方程式を解くための数値有限差分法のサブルーチンの一部であるため、この質問は、連立方程式、特に偏微分方程式で行列計算を行うすべての人に関連する可能性があります。コードを最適化するための提案をいただければ幸いです。