2012-02-17 10 views
1

これは興味深い質問です。私は正方行列と出力同じサイズの正方行列を受け入れるバイナリ機能を有していると仮定(またはより一般的には、入力タイプとサイズは、その出力の種類とサイズと同じである'S):matlabの2入力関数を可変長入力関数に変える巧妙な方法

function C = myfunc(A,B) 

する例のようになりmtimes関数。

function C = myfunc_multi(varargin) 

myfunc(A{1},myfunc(A{2},myfunc(A{3},...myfunc(A{end-1},A{end})...))) == 
    myfunc_multi(A{:}) 

その可変長入力機能にこれを回すのいくつかの異なったと巧妙な方法は何ですか?

これが私に来た最初の一般的なソリューションです

function C = multioutput(functionhandle, varargin) 
    n = length(varargin); 
    funcstr = functiontostring(functionhandle); 
    str = regexprep(arrayfun(@num2str,1:n-1),'(.)',[funcstr '(varargin{$1},']); 
    C = eval(sprintf('%svarargin{%d}%s',str,n,repmat(')',1,n-1))); 
end 

は、あなたがそれをテストするために

A = {rand(3) rand(3) rand(3) rand(3) rand(3)}; 
multioutput(@mtimes,A{:})-A{1}*A{2}*A{3}*A{4}*A{5} 

のようなものでそれをテストすることができます(編集:再帰またはループ以外) 。あなたが考えることができる他の方法?

+3

申し訳ありませんが、arrayfun、regexprep、evalの複雑な使い方で単純なループを避けるのはちょっと愚かです。適切なときに簡単なコードを書くことを学ぶ。ここにループがあります。この混乱は評価に時間を節約しますが、それをデバッグする必要がある場合は、まさにそのことになります。 –

+0

さらに、私はあなたがそれを述べたので再帰の使用を勧めません。時間と記憶の無駄。 – yuk

+1

@ woodchips、@ yuk:私が言ったように、この質問は興味深かった。他のプログラミング言語と同じように、わかりやすいやりとりや思いがけないやり方を見て楽しんでいます。私は実践よりも[IOCCC](http://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest)のラインに沿ってもっと考えていました。実際にMatlabを計算に使用しているときは、「シンプルコード」と書いています。 –

答えて

5

明白な再帰的構造を避けるべき理由はおそらくありません。シンプルで読みやすく保守が容易で、パフォーマンスはかなり良いはずです。少ないメモリを必要とする(おそらく*)

function out = aggregate_inputs(fHandle, varargin) 
if nargin>3 
    out = fHandle(varargin{1},aggregate_inputs(fHandle,varargin{2:end})); 
elseif nargin <= 3 
    out = fHandle(varargin{:}); 
end 

ないほどエレガントな、しかし、ループはもちろん

function accumulate = aggregate_inputs(fHandle,varargin) 
if nargin<=3 
    accumulate = fHandle(varargin{:}); 
else 
    accumulate = fHandle(varargin{end-1},varargin{end}); 
    for ix = (length(varargin)-2):-1:1 
     acumulate = fHandle(varargin{ix}, accumulate); 
    end 
end 

構築物である、あなたの質問は検討から、これらの構成要素を削除...ので本当に良い存在しません私が見ることができる方法。分のための哲学的なワックス


、多くのMatlabの操作がベクトル化呼び出しを使用してはるかに速くすることができることは事実です。時には、これは「すべてのコストでループを回避する」と解釈されることがあります。ただし、cellfun、arrayfun、または(please no)evalの呼び出しでループを回避すると、通常はパフォーマンスが向上しません。時には、他の理由で行うのが正しいことです...しかし、 "コードをベクトル化して速くする"のには役立ちません。


*「おそらく」上記の私はMATLABの怠惰なコピー・オン・ライトおよびその他の最適化は、再帰的なソリューションと潜在的な危険のように思えるのメモリ使用量を妨げる方法もわからないので、単純です。

+0

私は簡単に考えることはできませんが、最初の関数の再帰的ステップとして、 'out = fhandle(varargin {1}、aggregate_inputs(fHandle、varargin {2:en​​d}))') – Nigel

+0

あなたは正しいと思います。更新しました。 – Pursuit

関連する問題