2016-11-25 4 views
1

Iは行列セル配列の呼び出し関数をベクトル化する方法は?

x = rand(10,100,3); 

及び機能セルアレイを有する:擬似コードは

funcca = {... 
    @(v)(v(1)+v(2)), @(v)(v(1)-v(2)), ......, @(v)(v(1)+v(2)+v(3)^2); 
    ⋮ 
    ⋮ 
    @(v)(v(1)^6+sqrt(v(3))), @(v)(sin(v(1))-cos(v(2))),......,@(v)(v(1)) 
}; 

size(funcca) = [10, 100]あります。 funccaの各機能が異なることを意味します。

今私はyを計算するには、次のコードを使用します。

y = nan(10,100); 
for i = 1 :10 
    for j = 1:100 
     y(i,j) = funcca{i,j}(squeeze(x(i,j,:))); 
    end 
end 

は、私はこの2つのforループを避けるためか、このプロセスをベクトル化する可​​能性が方法はありますか?

+3

緩やかに話すベクトル化は、配列入力の各要素の関数の複数の呼び出しを、配列全体の関数の単一呼び出しに変換することです。ここでは、forループではなく1000個の異なる関数を呼び出すため、ベクトル化のための場所がありません。 – rahnema1

+1

関数を呼び出す方法ではなく、ベクトル化する必要があります。 –

+0

私はあなたの主なパフォーマンスの問題は、ループ内の 'squeeze 'だと思います。これはMATLABに組み込まれていないので、JITでコンパイルできず、ひどいパフォーマンスが得られます。ループの前に 'permute'を実行して、ループ内の抽出インデックスを調整すれば、かなり改善されるはずです。 –

答えて

0

matlab関数cellfunを使用すると、セル配列のすべての要素に対して操作を実行できます。この場合:cellfunへの呼び出しは次のようになります。実際に

y = cellfun(@(fh, data)fh(squeeze(data)), funcca, num2cell(x, 3)); 
+4

実際にcellfunは操作をベクトル化しませんが、これは単に「隠れたforループ」です – obchardon

+3

しかし、それはもはやあなたのせいではありません。今、それはcellfunをベクトル化しないためのMathWorksの不具合です –

+1

'squeeze'する必要はありません。 'funcca'は明示的に' 1'、 '2'、' 3'という要素を明示的に呼び出します.1×1×3の配列でも同様です。 –

0

、などの

y = cellfun(@(c)c(rand(1, 3)), funcca); 

またはx場合は、実際に明示的なデータであるべきで、ランダムにあなたの質問のように生成されない、そして何か:

z = cellfun(@(f,y) f(y), funcca, num2cell(x,3)); 

しかし、obchardonに示されているように、これは実際にあなたにスピードアップを与えないかもしれません。それはちょうどあなたにいくつかの入力を節約します。

実際、私はそれがデザイン上の問題だと思っています。どうしてそのような機能の配列に終わったのですか?文脈を提供することはできますか?

関連する問題