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

时间:2012-01-12 13:53:59

标签: matlab variadic-functions

我已经制作了一些辅助函数,它们使用其中的许多函数运行模拟。

为了使这些辅助函数更加用户友好,我想让用户选择用较少的参数调用函数(未传递给函数的参数被赋予预定义的值)。

例如,如果我有一个功能

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方法来处理这种情况,或者我是否必须使用较少的参数一次又一次地编写相同的代码?

3 个答案:

答案 0 :(得分:12)

您可以使用单元格数组打包和解压缩函数参数:

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也是一个单元格数组,你只需弹出你想要执行的函数所在的字段,然后将其余的字段作为参数传递给函数。

答案 1 :(得分: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

答案 2 :(得分:1)

我倾向于同意@Chris,虽然我想引入一些轻微的变化 如果你的意思是你不能改变 compute(),那么你可以使用 varargin 名称/值成语。< / p>

(为了运行此代码,您必须从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);