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

发布于 2024-12-26 06:57:23 字数 617 浏览 1 评论 0 原文

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

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

例如,如果我有一个函数

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

I have made some helper functions that run a simulation using a lot of functions inside them.

In order to make these helper functions more user friendly I want to give the user the choice of calling the functions with fewer arguments (the arguments that are not passed into the function are assigned a predefined value).

For example if I have a function

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

and the function runsim which is defined like this

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

the silly way to do it is

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

Another solution would be to change the arguments to vectors but I am not allowed to touch the functions behind the simulation. Is there a Matlab way to handle this situation or do I have to write the same code again and again with fewer arguments?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奶茶白久 2025-01-02 06:57:23

您可以使用元胞数组打包和解包函数参数:

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 也是元胞数组,因此您只需弹出要执行的函数所在的字段,然后将其余字段传递为函数的参数。

You can pack and unpack function arguments using cell arrays:

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

The same goes for output arguments:

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

Since varargin is also a cell array, you can just pop the field the function you want to execute is in, and then pass the rest of the fields as arguments to the function.

暮年慕年 2025-01-02 06:57:23

我倾向于同意@Chris 的观点,尽管我想引入一些细微的变化。
如果您的意思是无法更改 compute(),那么您可以使用 vararginName/Value 习惯用法。

(为了运行此代码,您必须从 Matlabcentral< 下载 catstruct() 函数/a>)

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);

I tend to agree with @Chris, though I want to introduce a slight variation.
If what you meant is that you can't change compute(), then you can use varargin, and the Name/Value idiom.

(In order to run this code, you must download the catstruct() function from Matlab central)

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

And the calling function:

 runsim('Param1',Value1,'Param2',Value2);
 runsim('Param2',Value2);
 runsim('Param1',Value1);
情魔剑神 2025-01-02 06:57:23

通常的方法是使用 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

编辑的操作:另一种方法是使用inputParser 在您的 runsim 函数中。

The usual way to do this is to use varagin. For example, to define a function which takes one required argument and four optional arguments we could do something like

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

Edit: An alternative way would be to use inputParser in your runsim function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文