いくつかの方法が考えられます。まず、いくつかの偽のデータを生成します
A = cellfun(@(~)rand(2,1), cell(1000), 'uni', false);
B = rand(2);
セルファン
おっしゃるとおり、これは避けたいところです。いずれにせよ、比較のためにここに含めます。
C = cellfun(@(x)B*x, A, 'UniformOutput',false);
匿名関数が関係しているため、低速です。組み込みの文字列関数 (「参考文献」を参照) を備えた Cellfunhelp cellfun
は猛威を振るっていますが、無名関数は反復ごとに強制的に実行を Matlab インタープリターに渡します。これは JIT によっていくらか効率化できますが、最適とは言えません。
セル拡張、num2cell、形状変更
アイデア: セルを 2x1000 行列に展開し、乗算を実行し、結果を正しいサイズのセル配列にキャストします。原則としてはエレガントですが、実際に使用すると少し混乱します。
C = reshape( num2cell(B*[A{:}],1), size(A) );
中間の 2x1000 テンポラリは、メモリ フットプリントの観点からは少し無駄であることに注意してください...また、パス スルーnum2cell
(これは組み込みではない) と「役に立たない」reshape
ため、実行がかなり遅くなります。
ループ用
ループは、最も読みやすく、実装も簡単です。メモリ使用量が少なく、JIT による高速化などに適しています。
C = cell(size(A));
for ii = 1:numel(A)
C{ii} = B*A{ii};
end
唯一の欠点は、評判が悪いことです:)
比較
そして今、キッカーのために: どれが最速ですか?
tic
C = cellfun(@(x)B*x, A, 'uni',false);
toc
tic
C = reshape( num2cell(B*[A{:}],1), size(A) );
toc
tic
C = cell(size(A));
for ii = 1:numel(A)
C{ii} = B*A{ii};
end
toc
結果:
Elapsed time is 4.738791 seconds. % cellfun
Elapsed time is 4.161515 seconds. % cell expansion, num2cell, reshape
Elapsed time is 3.808822 seconds. % loop
結論: R2008 で JIT コンパイルが導入されて以来、ループはもはや悪ではありません。デフォルトでそれらを回避しようとしないでください。