1. ホーム
  2. arrays

[解決済み] MATLABで、bsxfunを使うのはいつが最適ですか?

2022-06-12 15:30:46

質問

Stack OverflowのMATLABの質問に対する多くの良い回答が、頻繁に関数 bsxfun . なぜでしょうか?

動機です。 MATLABのドキュメントにある bsxfun のMATABドキュメントでは、次のような例が示されています。

A = magic(5);
A = bsxfun(@minus, A, mean(A))

を使って同じ操作をすることももちろん可能です。

A = A - (ones(size(A, 1), 1) * mean(A));

そして実際、簡単なスピードテストでは、2番目の方法の方が約20%速いことが実証されています。では、なぜ最初の方法を使うのでしょうか?というのも、おそらくは bsxfun を使用した方が、手動で行うよりもはるかに速い場合があるのでしょう。そのような状況の例と、なぜそれがより速いのかについての説明をぜひ見てみたいです。

また、この質問に対する最後の要素として、再びMATLABのドキュメントから bsxfun : "C = bsxfun(fun,A,B) は、関数ハンドル fun で指定された要素ごとの二項演算を、シングルトン展開を有効にして配列 A と B に適用します(")。with singleton expansion enabled"とは、どういう意味ですか?

どのように解決するのですか?

私が bsxfun ( ドキュメント , ブログリンク )

  1. bsxfun よりも高速です。 repmat (よりも高速です(下記参照)。
  2. bsxfun はより少ないタイピングを必要とします
  3. 使用方法 bsxfun を使うのと同じように accumarray を使うように、MATLABを理解していることを実感できます。

bsxfun は入力配列をその "シングルトン次元"、つまり配列のサイズが1である次元に沿って複製し、他の配列の対応する次元のサイズと一致するようにします。これがいわゆる" シングルトン展開 と呼ばれるものです。余談ですが、シングルトンディメンションは、もしあなたが squeeze .

非常に小さな問題では repmat のアプローチの方が高速である可能性がありますが、その配列サイズでは、両方の操作が非常に高速であるため、全体的なパフォーマンスの点では違いがない可能性があります。2 つの重要な理由があります。 bsxfun の方が高速である理由は 2 つあります。(1) 計算はコンパイルされたコードで行われるため、実際の配列の複製は発生しないこと、および (2) bsxfun はマルチスレッド化されたMATLAB関数の1つです。

との速度比較をしてみました。 repmatbsxfun を、私のそこそこ速いラップトップ上の MATLAB R2012b で実行しました。

私の場合 bsxfun よりも約3倍速いです。 repmat . 配列が大きくなれば、その差はより顕著になります。

の実行時間のジャンプは repmat は配列のサイズが 1 MB のあたりで発生しますが、これはプロセッサのキャッシュのサイズと関係があるのかもしれません。 bsxfun は出力配列を割り当てるだけなので、それほどひどいジャンプは起こりません。

以下に、タイミングをとるために使用したコードを示します。

n = 300;
k=1; %# k=100 for the second graph
a = ones(10,1);
rr = zeros(n,1);
bb = zeros(n,1);
ntt = 100;
tt = zeros(ntt,1);
for i=1:n;
   r = rand(1,i*k);
   for it=1:ntt;
      tic,
      x = bsxfun(@plus,a,r);
      tt(it) = toc;
   end;
   bb(i) = median(tt);
   for it=1:ntt;
      tic,
      y = repmat(a,1,i*k) + repmat(r,10,1);
      tt(it) = toc;
   end;
   rr(i) = median(tt);
end