如何在Matlab中设置函数参数的默认值?

Sco*_*ott 120 matlab arguments default

是否可以在Matlab中使用默认参数?例如,这里:

function wave(a, b, n, k, T, f, flag, fTrue=inline('0'))
Run Code Online (Sandbox Code Playgroud)

我想让真正的解决方案成为wave函数的可选参数.如果有可能,任何人都可以证明这样做的正确方法吗?目前,我正在尝试上面发布的内容,我得到:

??? 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.
Run Code Online (Sandbox Code Playgroud)

sim*_*mon 145

没有像你尝试过的那样直接做到这一点的方法.

通常的方法是使用"varargs"并检查参数的数量.就像是:

function f(arg1, arg2, arg3)

  if nargin < 3
    arg3 =   'some default'
  end

end
Run Code Online (Sandbox Code Playgroud)

你可以用一些更好的东西来做isempty,等等,你可能想看看Matlab中心的一些捆绑这些东西的软件包.

你可能有一个看看varargin,nargchk等他们对这种事有用的功能.varargs允许您保留可变数量的最终参数,但这并不能解决部分/全部默认值的问题.


小智 58

我已经使用该inputParser对象来处理设置默认选项.Matlab不接受您在问题中指定的类似python的格式,但您应该能够像这样调用函数:

wave(a,b,n,k,T,f,flag,'fTrue',inline('0'))
Run Code Online (Sandbox Code Playgroud)

在定义了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{:});
Run Code Online (Sandbox Code Playgroud)

现在可以通过传递给函数的值i_p.Results.此外,我不知道如何验证传入的参数ftrue实际上是一个inline函数,因此验证器留空.

  • 我可以说,*this*,是首选的方法.它是干净的,自我记录的(更像是一堆`if nargin`hishismens),易于维护,紧凑和灵活. (7认同)

小智 19

另一种稍微不那么苛刻的方式是

function output = fun(input)
   if ~exist('input','var'), input='BlahBlahBlah'; end
   ...
end
Run Code Online (Sandbox Code Playgroud)


JMi*_*kes 14

“真正的”默认参数(即通过专门构建的语言功能而不是解析函数或手动代码进行默认设置)是在 2019b 中随块引入arguments

作为一个简化的示例,请考虑以下函数:

function myFun(a,b,c)
    arguments
        a
        b
        c = 0
    end
    disp([a b c])
end
Run Code Online (Sandbox Code Playgroud)

c是一个可选输入,默认值为 0。输入a没有b定义默认值,因此它们是必需的输入。

现在可以在传递或不传递 c 值的情况下调用 myFun,c=0如果未提供值,则使用默认值。

>> myFun(1,2)
     1     2     0

>> myFun(1,2,3)
     1     2     3
Run Code Online (Sandbox Code Playgroud)


小智 10

是的,拥有写作能力可能真的很棒.但是在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
Run Code Online (Sandbox Code Playgroud)

好的,所以我通常会应用更好,更具描述性的错误消息.请注意,检查空变量允许用户传入一对空括号[],作为将采用其默认值的变量的占位符.作者仍然必须提供代码,以使用其默认值替换该空参数.

我的实用程序更复杂,具有MANY参数,所有参数都具有默认参数,通常会使用属性/值对接口作为默认参数.这个基本范例可以在matlab的handle图形工具中看到,也可以在optimset,odeset等中看到.

作为使用这些属性/值对的一种方法,您需要了解varargin,作为向函数输入完全可变数量的参数的方法.我编写(并发布)了一个实用程序来处理这样的属性/值对,parse_pv_pairs.m.它可以帮助您将属性/值对转换为matlab结构.它还允许您为每个参数提供默认值.将笨重的参数列表转换为结构是一种非常好的方法,可以在MATLAB中传递它们.


ali*_*noi 5

我很困惑,没有人指出MATLAB 开发人员之一 Loren 的这篇博文。该方法基于varargin并避免所有那些无休止的痛苦if-then-elseswitch复杂情况的案例。当有几个默认值时,效果非常显着。这是链接博客中的一个示例:

function y = somefun2Alt(a, b, varargin)
% Some function that requires two inputs and has some optional inputs.

% Only want three optional inputs at most
numvarargs = length(varargin);
if numvarargs > 3
    error('myfuns:somefun2Alt:TooManyInputs', ...
        'requires at most three optional inputs');
end

% Set defaults for optional inputs
optargs = {eps 17 @magic};

% Now put these defaults into the valuesToUse cell array,
% and overwrite the ones specified in varargin.
optargs(1:numvarargs) = varargin;
% or ...
% [optargs{1:numvarargs}] = varargin{:};

% Place optional args in memorable variable names
[tol, mynum, func] = optargs{:};
Run Code Online (Sandbox Code Playgroud)

如果您仍然不明白,请尝试阅读 Loren 的整篇博文。我写了一篇后续博客文章,处理丢失的位置默认值。我的意思是你可以写这样的东西:

somefun2Alt(a, b, '', 42)
Run Code Online (Sandbox Code Playgroud)

并且仍然具有参数的默认epstol(当然还有@magic回调func)。Loren 的代码允许通过轻微但棘手的修改来实现这一点。

最后,这种方法的几个优点:

  1. 即使有很多默认值,样板代码也不会变得很大(与if-then-else方法系列相反,每个新的默认值都会变长)
  2. 所有默认值都在一处。如果其中任何一个需要更改,您只需查看一个地方。

说实话,也有缺点。当您在 MATLAB shell 中键入函数并忘记其参数时,您将看到一个无用varargin的提示。为了解决这个问题,建议您编写一个有意义的用法子句。


小智 5

这是我使用"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
Run Code Online (Sandbox Code Playgroud)

问候!