コードのパフォーマンスを改善しようとしています。このコードは基本的に (1x2640) の値を計算し、L_total
(1320x6) と呼ばれる別の変数からデータをフェッチすることによって計算しますL_CN
。colindexes
で見る行の値を格納するマトリックス (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]
。