我已经制作了一些辅助函数,它们使用其中的许多函数运行模拟。
为了使这些辅助函数更加用户友好,我想让用户选择用较少的参数调用函数(未传递给函数的参数被赋予预定义的值)。
例如,如果我有一个功能
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方法来处理这种情况,或者我是否必须使用较少的参数一次又一次地编写相同的代码?
答案 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);