web-dev-qa-db-ja.com

MATLAB関数の一部の戻り値をエレガントに無視する方法は?

すべての_n-1_戻り値に対してダミー変数を作成することなく、関数から「n番目」の戻り値を取得することは可能ですか?

たとえば、MATLABに次の関数があるとします。

_function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
_

今、私はthird戻り値のみに興味があると仮定します。これは、ダミー変数を1つ作成することで実現できます。

_[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
_

しかし、これは一種のgいであると思います。次のいずれかのようなことができると思いますが、できません:

_[_, _, variableThatIWillUse, _] = func;_

_[, , variableThatIWillUse, ] = func;_

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

エレガント動作するこれを行う方法はありますか?


これまでのところ、最良の解決策は、単にvariableThatIWillUseをダミー変数として使用することです。これにより、ワークスペースを汚染する(またはクリアする必要がある)実際のダミー変数を作成する必要がなくなります。要するに、解決策は、興味深い値までのすべての戻り値にvariableThatIWillUseを使用することです。後の戻り値は単に無視できます。

_[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
_

私はまだこれは非常にいコードだと思いますが、より良い方法がなければ、答えを受け入れると思います。

115
Jordi

これはややハックですが、動作します:

最初の簡単な関数例:

_Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
_

ここで重要なのは、複数式の割り当ての左側で変数twiceを使用すると、前の割り当てが後の割り当てによって上書きされることです。割り当て:

_[b,b,c]=Func3();
% yields b=2, c=3

[c,c,c]=Func3();
% yields c=3
_

(編集:確認するために、polyfitから気にするのが3番目の引数である場合、この手法が[mu,mu,mu]=polyfit(x,y,n)で機能することも確認しました)


編集:より良いアプローチがあります。代わりに ManWithSleeveの答え を参照してください。

38
Jason S

MATLABバージョン7.9(R2009b)では、〜を使用できます。たとえば、

[~, ~, variableThatIWillUse] = myFunction();

,はオプションではないことに注意してください。 [~ ~ var]と入力するだけでは機能せず、エラーがスローされます。

詳細については、 リリースノート をご覧ください。

224
ManWithSleeve

変数をビットバケットに入れるスタイルを使用したい場合、合理的な代替策は

[ans,ans,variableThatIWillUse] = myfun(inputs);

ansはもちろんmatlabのデフォルトのジャンク変数であり、セッション中に頻繁に上書きされます。

〜を使用して無視される戻り変数を指定することで、MATLABで許可されている新しいトリックが気に入っていますが、これは下位互換性の問題です。古いリリースのユーザーはコードを使用できません。通常、少なくとも数個のMATLABリリースが発行されるまで、そのような新しいものを使用することは避けます。たとえば、今でも人々は、匿名関数を使用できないほど古いMATLABリリースを使用していることに気付きます。

37
user85109

使用できる別のオプションを次に示します。最初にセル配列を作成して、すべての出力をキャプチャします( [〜#〜] nargout [〜#〜] 関数を使用して、特定の関数が返す出力の数を決定できます)。

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

次に、次のように関数を呼び出します。

[a{:}] = func();

次に、必要なaから要素を削除し、aを上書きします:

a = a{3};  % Get the third output
13
gnovice

私はkth out関数を書きました:


function kth = kthout(k,ffnc,varargin)
%% kthout: take the kth varargout from a func call %FOLDUP
% 
% kth = kthout(k,ffnc,varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

[outargs{1:k}]  = feval(ffnc,varargin{:});
kth                         = outargs{k};

end %function

その後、電話することができます

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc

次のような関数をまとめることもできます

func_i_want = @(varargin)(kthout(3,@myfunc,varargin{:}));  %assuming you want the 3rd output.

その後使用する

val_i_want = func_i_want(func_input_1,func_input_2);

このような匿名関数の使用に関連するオーバーヘッドがあることに注意してください。これは、何千回も呼び出されるコードで行うことではありません。

9
shabbychef

Matlab 2010aで、あなたが求めていることをきちんと行う方法を見つけました。それは単に、ダミー変数として(複数のパラメーターを返すときに必要なだけ)キャラクター "〜"(もちろん引用符なし)を使用することです。これは、関数が欠損データを処理するように設計されている場合、関数への入力パラメーターに対しても機能します。これが以前のバージョンに存在したかどうかはわかりませんが、最近発見しました。

4
Sam

選択した出力のみを返す関数(または匿名関数)を作成できます。

select = @(a,b) a(b);

その後、次のように関数を呼び出すことができます。

select(func,2);
select(func,1:3);

または、出力を変数に割り当てることができます。

output(1,2:4) = select(func,1:3);
1
Dave

次のように、ans(n)を使用しない理由はありますか?

a=Rand([5 10 20 40]);

size(a);

b=ans(2);

B = 10となり、この方法はすべてのMatlabバージョンと互換性がないでしょうか?

さらに、これは、引数の数がわからない場合に2番目の出力引数を取得するために機能します!一方、これを行う場合:

[~, b] = size(a);

それからb = 8000! (引数をさらにキャッチするには、〜で終わる必要があります!)

0
user1596274