1

コードのパフォーマンスを改善しようとしています。このコードは基本的に (1x2640) の値を計算し、L_total(1320x6) と呼ばれる別の変数からデータをフェッチすることによって計算しますL_CNcolindexesで見る行の値を格納するマトリックス (2640x3)もありますL_CN

これがどうなるかというと、コードは を調べcolindexesて行データを取得します。Saycolindexesは次の形式です。

55    65    75
68    75    85
...

プログラムは をL_total(1)使用して計算しL_CN(55,1) + L_CN(65,1) + L_CN(75,1)ます。ここで、最初のインデックスは、colindexes行列から取得された行番号を参照します。2 番目のインデックスは、これまでにこれらの行番号が出現した回数を表します。したがって、 を計算するL_total(2)と となりますL_CN(68,1) + L_CN(75,2) + L_CN(85,1)。以前使っていL_CN(75,2)たのでこちらにしました。L_CN(75,1)

L_total行列全体を計算するには、次のコードが適切に機能します。list対応するインデックスを(2640x1)という変数にインクリメントすることで、各インデックスの出現回数を格納し、を計算しL_totalます。これは 0.023715 秒で行われます。n(以下は 2640であることに注意してください)

for i=1:n
     list(colindexes(i,:)) = list(colindexes(i,:)) + 1;
     L_total(i) = sum(diag(L_CN(colindexes(i,:),list(colindexes(i,:)))));
end

問題は、コードのこの部分を何度も、おそらく 100 万回も実行することです。それは大きなシミュレーションの一部です。したがって、パフォーマンスの向上のほんのわずかな部分でも、私が求めているものです。まず、for ループを取り除くことがこの目的に役立つと考え、コードを次のように切り替えました - このトピックから少し助けを得て:出現番号のベクトル:

list_col = reshape(colindexes',1,[]);
occurrence = sum(triu(bsxfun(@eq,list_col,list_col.')));
list = reshape(occurrence,3,[])';
straight_index = colindexes + (list - 1)*k;
L_total = sum(L_CN(straight_index),2)';

このコードは、list_col(1x7920)、occurrence(1x7920)、list(2640x3)、およびstraight_index(2640x3) のジョブも実行します。しかし、私の予想に反して、0.062168 秒かかり、for ループの実装よりも約 3 倍遅くなりました。この操作の 0.05217 秒は、オカレンス マトリックスが形成される 2 行目の予定です。私のような配列サイズでは、このように出現を見つけるのは本当に非効率的です。

問題は、for ループの有無にかかわらず、このコードのパフォーマンスを向上させるにはどうすればよいかということです。発生行列をより速く計算する方法を見つけられれば、ベクトル化方法はいいようです。前述したように、コードのこの部分は何度も実行されるため、パフォーマンスの向上は何パーセントでも歓迎されます。

ありがとうございました!

詳細情報: colindexesサイズ 1320x2640 の大きな行列を表します。この行列全体を格納する代わりに、この行列の '1' の行の位置のみを に格納しcolindexesます。残りはゼロです。したがって、colindexes質問で指定したのは、1 列目の 55 行目と 2 列目の 85 行目に「1」があることを意味します... したがって、最小、最大範囲は 1,1320 です。各列には '1' が 3 つしかないため、そのサイズは 2640x3 です。もちろん、これはそれがどのように形成されるかについての背景情報です。それが役立つ場合、各値の出現回数colindexesも同じで、6 です。

したがって、行列のA = [1 0 0 1; 0 1 1 0]場合、colindexesは です[1; 2; 2; 1]

4

1 に答える 1