131

MATLAB で既定の引数を使用することは可能ですか?

たとえば、ここに:

function wave(a, b, n, k, T, f, flag, fTrue=inline('0'))

真の解を波動関数のオプションの引数にしたいと思います。可能であれば、これを行う適切な方法は何ですか?

現在、私は上に投稿したことを試していますが、次のようになります。

??? Error: File: wave.m Line: 1 Column: 37
The expression to the left of the equals sign is not a valid target for an assignment.
4

16 に答える 16

157

あなたが試みたようにこれを行う直接的な方法はありません。

通常のアプローチは、「varargs」を使用して引数の数をチェックすることです。何かのようなもの:

function f(arg1, arg2, arg3)

  if nargin < 3
    arg3 =   'some default'
  end

end

などを使用してできる、より手の込んだことがisemptyいくつかあります。これらの種類のものをバンドルするいくつかのパッケージについては、MATLAB central を参照してください。

varargin、などを見たことがあるかもしれませんnargchk。これらは、この種のことに役立つ関数です。varargsを使用すると、可変数の最終引数を残すことができますが、これでは一部/すべてのデフォルト値の問題を回避できません。

于 2009-04-28T00:55:17.977 に答える
58

inputParserこのオブジェクトを使用して、デフォルト オプションの設定を処理しました。MATLAB は、質問で指定した Python のような形式を受け入れませんが、次のように関数を呼び出すことができるはずです。

wave(a, b, n, k, T, f, flag, 'fTrue', inline('0'))

wave次のように関数を定義した後:

function wave(a, b, n, k, T, f, flag, varargin)

    i_p = inputParser;
    i_p.FunctionName = 'WAVE';

    i_p.addRequired('a', @isnumeric);
    i_p.addRequired('b', @isnumeric);
    i_p.addRequired('n', @isnumeric);
    i_p.addRequired('k', @isnumeric);
    i_p.addRequired('T', @isnumeric);
    i_p.addRequired('f', @isnumeric);
    i_p.addRequired('flag', @isnumeric);
    i_p.addOptional('ftrue', inline('0'), 1);

    i_p.parse(a, b, n, k, T, f, flag, varargin{:});

これで、関数に渡された値が から利用できるようになりましi_p.Resultsた。ftrueまた、渡されたパラメーターが実際に関数であることを検証する方法がわからなかったinlineため、バリデーターを空白のままにしました。

于 2009-05-02T12:37:40.127 に答える
19

もう1つの少しハッキリしない方法は次のとおりです。

function output = fun(input)
   if ~exist('input','var'), input='BlahBlahBlah'; end
   ...
end
于 2011-02-20T15:21:27.967 に答える
11

はい、あなたが書いたようにできることは本当に素晴らしいことかもしれません。しかし、MATLAB ではそれができません。引数のデフォルトを許可する私のユーティリティの多くは、次のように最初に明示的なチェックを使用して記述される傾向があります。

if (nargin<3) or isempty(myParameterName)
  MyParameterName = defaultValue;
elseif (.... tests for non-validity of the value actually provided ...)
  error('The sky is falling!')
end

わかりましたので、通常はより適切でわかりやすいエラー メッセージを適用します。空の変数のチェックにより、ユーザーは[]、デフォルト値を取る変数のプレースホルダーとして、空の括弧のペアを渡すことができることに注意してください。ただし、作成者は、その空の引数をデフォルト値に置き換えるコードを提供する必要があります。

より洗練された、多くのパラメーターを持ち、そのすべてに既定の引数がある私のユーティリティは、多くの場合、既定の引数にプロパティ/値のペア インターフェイスを使用します。この基本的なパラダイムは、MATLAB のハンドル グラフィックス ツールや、optimset、odeset などで見られます。

これらのプロパティ/値のペアを操作する手段として、完全に可変数の引数を関数に入力する方法として、vararginについて学習する必要があります。このようなプロパティ/値のペアを操作するためのユーティリティparse_pv_pairs.mを作成 (および投稿) しました。プロパティ/値のペアを MATLAB 構造体に変換するのに役立ちます。また、各パラメーターのデフォルト値を指定することもできます。扱いにくいパラメーターのリストを構造体に変換することは、MATLAB でそれらを渡すための非常に優れた方法です。

于 2009-04-28T11:56:57.280 に答える
7

これは、「try」を使用して、関数にデフォルト値を設定する簡単な方法です。

function z = myfun (a, varargin)

%% Default values
b = 1;
c = 1;
d = 1;
e = 1;

try 
    b = varargin{1};
    c = varargin{2};
    d = varargin{3};
    e = varargin{4};
end

%% Calculation
z = a * b * c * d * e;
end
于 2015-06-09T14:01:02.400 に答える
3

parseArgs関数が非常に役立つことがわかりました。

そのドキュメントは次のとおりです。

解析用のヘルパー関数varargin。次のような引数を取る関数を簡単に記述できます。subaxis(4,2,1,'spacing',0,'marginleft',.1,'H','pt',.1)

ArgStruct=parseArgs(varargin,ArgStruct[,FlagtypeParams[,Aliases]])

  • ArgStructデフォルト値を持つ名前付き引数でいっぱいの構造体です。
  • Flagtype パラメータは、値を必要としないパラメータです。(存在する場合、値は 1 に設定されます)
  • エイリアスを使用して、1 つの引数名を複数の argstruct フィールドにマップできます

使用例:

function parseargtest(varargin)

%define the acceptable named arguments and assign default values
Args=struct('Holdaxis',0, ...
'SpacingVertical',0.05,'SpacingHorizontal',0.05, ...
'PaddingLeft',0,'PaddingRight',0,'PaddingTop',0,'PaddingBottom',0, ...
'MarginLeft',.1,'MarginRight',.1,'MarginTop',.1,'MarginBottom',.1, ...
'rows',[],'cols',[]);

%The capital letters define abrreviations.
% Eg. parseargtest('spacingvertical',0) is equivalent to parseargtest('sv',0)

Args=parseArgs(varargin,Args, ... 
% fill the arg-struct with values entered by the user, e.g.
% {'Holdaxis'}, ... %this argument has no value (flag-type)
% {'Spacing' {'sh','sv'}; 'Padding' {'pl','pr','pt','pb'}; 'Margin' {'ml','mr','mt','mb'}});

disp(Args)
于 2009-04-28T21:00:52.633 に答える
3

この問題に対処するための気の利いた方法を次に示します。使用するコードは 3 行のみです (行の折り返しを除く)。以下は、私が書いている関数から直接持ち上げられたもので、期待どおりに動作するようです:

defaults = {50/6,3,true,false,[375,20,50,0]}; % Set all defaults
defaults(1:nargin-numberForcedParameters) = varargin; % Overload with function input
[sigma,shifts,applyDifference,loop,weights] = ...
     defaults{:}; % Unfold the cell struct
于 2014-01-16T14:18:21.187 に答える
3

ある時点で MATLAB から削除される可能性がありますが、使用できる「ハック」もあります。

関数evalは実際には 2 つの引数を受け入れ、最初の引数でエラーが発生した場合に 2 番目の引数が実行されます。

したがって、使用できます

function output = fun(input)
   eval('input;', 'input = 1;');
   ...
end

値 1 を引数のデフォルトとして使用します。

于 2010-12-07T09:30:38.933 に答える
2

ASSIGNIN ( b3によるこの回答のおかげ) とEVALINを認識した後、非常に単純な呼び出し構造を最終的に取得するために 2 つの関数を作成しました。

setParameterDefault('fTrue', inline('0'));

リストは次のとおりです。

function setParameterDefault(pname, defval)
% setParameterDefault(pname, defval)
% Author: Tobias Kienzler (https://stackoverflow.com/users/321973)
% sets the parameter NAMED pname to the value defval if it is undefined or
% empty

if ~isParameterDefined('pname')
    error('paramDef:noPname', 'No parameter name defined!');
elseif ~isvarname(pname)
    error('paramDef:pnameNotChar', 'pname is not a valid varname!');
elseif ~isParameterDefined('defval')
    error('paramDef:noDefval', ['No default value for ' pname ' defined!']);
end;

% isParameterNotDefined copy&pasted since evalin can't handle caller's
% caller...
if ~evalin('caller',  ['exist(''' pname ''', ''var'') && ~isempty(' pname ')'])
    callername = evalin('caller', 'mfilename');
    warnMsg = ['Setting ' pname ' to default value'];
    if isscalar(defval) || ischar(defval) || isvector(defval)
        warnMsg = [warnMsg ' (' num2str(defval) ')'];
    end;
    warnMsg = [warnMsg '!'];
    warning([callername ':paramDef:assigning'], warnMsg);
    assignin('caller', pname, defval);
end

function b = isParameterDefined(pname)
% b = isParameterDefined(pname)
% Author: Tobias Kienzler (https://stackoverflow.com/users/321973)
% returns true if a parameter NAMED pname exists in the caller's workspace
% and if it is not empty

b = evalin('caller',  ['exist(''' pname ''', ''var'') && ~isempty(' pname ')']) ;
于 2011-03-22T09:55:50.437 に答える
1

Matlab はこのメカニズムを提供していませんが、inputParser または "if nargin < 1..." シーケンスよりも簡潔なユーザーランド コードで構築できます。

function varargout = getargs(args, defaults)
%GETARGS Parse function arguments, with defaults
%
% args is varargin from the caller. By convention, a [] means "use default".
% defaults (optional) is a cell vector of corresponding default values

if nargin < 2;  defaults = {}; end

varargout = cell(1, nargout);
for i = 1:nargout
    if numel(args) >= i && ~isequal(args{i}, [])
        varargout{i} = args{i};
    elseif numel(defaults) >= i
        varargout{i} = defaults{i};
    end
end

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

function y = foo(varargin)
%FOO 
%
% y = foo(a, b, c, d, e, f, g)

[a, b,  c,       d, e, f, g] = getargs(varargin,...
{1, 14, 'dfltc'});

フォーマットは、パラメータ名からデフォルト値までを読み取るための規則です。オプションのパラメーターの型指定 (エラー検出または暗黙の変換用) と引数カウント範囲を使用して getargs() を拡張できます。

このアプローチには 2 つの欠点があります。まず、遅いので、ループで呼び出される関数には使用したくないでしょう。次に、Matlab の関数ヘルプ (コマンド ラインのオートコンプリート ヒント) は、varargin 関数では機能しません。でもかなり便利です。

于 2009-05-13T04:18:36.217 に答える
1

これは多かれ少なかれMATLAB マニュアルから引用したものです。合格経験しかない…

function my_output = wave ( a, b, n, k, T, f, flag, varargin )
  optargin = numel(varargin);
  fTrue = inline('0');
  if optargin > 0
    fTrue = varargin{1};
  end
  % code ...
end
于 2009-04-28T00:59:25.207 に答える
0

parseparamsMATLABでコマンドを使用することをお勧めします。使用法は次のようになります。

function output = wave(varargin);
% comments, etc
[reg, props] = parseparams(varargin);
ctrls = cell2struct(props(2:2:end),props(1:2:end),2);  %yes this is ugly!
a = reg{1};
b = reg{2};
%etc
fTrue = ctrl.fTrue;
于 2010-10-08T19:04:52.863 に答える
0
function f(arg1, arg2, varargin)

arg3 = default3;
arg4 = default4;
% etc.

for ii = 1:length(varargin)/2
  if ~exist(varargin{2*ii-1})
    error(['unknown parameter: ' varargin{2*ii-1}]);
  end;
  eval([varargin{2*ii-1} '=' varargin{2*ii}]);
end;

たとえば、f(2,4,'c',3)パラメータcを 3 にします。

于 2010-10-11T13:56:52.427 に答える
0

Octaveを使用する場合は、次のようにすることができますが、残念ながら MATLAB はこの可能性をサポートしていません。

function hello (who = "World")
  printf ("Hello, %s!\n", who);
endfunction

(ドキュメンテーションから引用。)

于 2014-06-10T14:09:18.040 に答える