在Matlab中处理可变参数函数调用

4

我已经编写了一些辅助函数,这些函数内部使用了许多其他函数来运行模拟。

为了使这些辅助函数更易于使用,我希望用户可以选择使用较少的参数调用函数(未传递到函数中的参数将被分配预定义的值)。

例如,如果我有一个函数:

function [res, val, h, v, u] = compute(arg1, arg2, arg3, arg4)
    if nargin < 4 || isempty(arg4) arg4 = 150; end

并且这个函数 runsim 的定义如下:

function [res, val, h, v, u] = runsim(v, arg1, arg2, arg3, arg4)

愚蠢的做法是

if nargin < 5 || isempty(arg4)
    compute(arg1, arg2, arg3)
else
    compute(arg1, arg2, arg3, arg4)
end

另一种解决方法是将参数更改为向量,但我不被允许触及模拟背后的函数。是否有Matlab的方法来处理这种情况,或者我必须反复编写相同的代码,但参数较少?


你的意思是说你不能改变“compute”吗? - Andrey Rubshtein
@Andrey 是的,那就是我的意思。 - kechap
3个回答

13

您可以使用单元数组对函数参数进行打包和解包:

a={'foo','bar',42}
fun(a{:}) % is the same as:
fun('foo','bar',42)

输出参数同样适用:

a,b,c=fun(); % or easier:
c=cell(3,1);
[c{:}]=fun();

由于varargin也是一个单元格数组,您可以弹出包含要执行的函数的字段,然后将其余字段作为参数传递给该函数。


我很喜欢它,而且它也起作用。现在我只需添加或删除参数,然后进行一次调用即可。 - kechap

1
通常的做法是使用varagin。例如,要定义一个带有一个必需参数和四个可选参数的函数,我们可以这样做:
function [res, val, h, v, u] = runsim(v, varagin)

    % Check that at least 1 and at most 5 input arguments were passed
    error(nargchk(1, 5, nargin))

    % Check number of optional arguments passed
    noptargin = size(varargin, 2)

    % Check how many arguments passed, set default values if required.
    % Im sure the following could be cleaned up.
    if noptargin == 1
        arg1 = varagin{1}
        arg2 = ...
        arg3 = ...
        arg4 = ...
    elseif noptargin == 2
        arg1 = varagin{1}
        arg2 = varagin{2}
        arg3 = ...
        arg4 = ...
    elseif noptargin == 3
        arg1 = varagin{1}
        arg2 = varagin{2}
        arg3 = varagin{3}
        arg4 = ...
    end

    % Finally, call compute with all arguments set
    compute(arg1, arg2, arg3, arg4)

end

编辑:另一种方法是在 runsim 函数中使用 inputParser


1

我倾向于同意@Chris的观点,但我想引入一些微小的变化。
如果你的意思是你不能改变compute(),那么你可以使用vararginName/Value习语。

(为了运行此代码,您必须从Matlab central下载catstruct()函数)

function runsim( varargin) 
      partialParams= struct(varargin{:});
      % Check each variable 
      DefaultVal1 = 1;
      DefaultVal2 = 2;
      defaultParams = struct('Param1',DefaultVal1,'Param2',DefaultVal2');
      % Merge 2 structs
      params = catstruct(defaultParams,partialParams);
      % Call compute on the parameters.
      fnames = fieldnames(params);
      vals = {};
      for i=1:numel(fnames)
            vals{end+1} = params.(fnames{i});
      end
      compute( vals{:});
 end

调用函数:

 runsim('Param1',Value1,'Param2',Value2);
 runsim('Param2',Value2);
 runsim('Param1',Value1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接