2012-01-12 157 views
3

我已經做了一些幫助函數,使用它們中的很多函數來運行模擬。在Matlab中處理可變參數函數調用

爲了使這些幫助函數更加用戶友好我想給用戶選擇使用較少的參數調用函數(沒有傳遞給函數的參數被賦予一個預定義的值)。

例如,如果我有一個函數

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

並且被這樣

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

傻方式做到這一點所限定的函數runsim是

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

另一種解決方案會改變向量的參數,但我不允許觸摸模擬背後的功能。有沒有一種Matlab方式來處理這種情況,還是我必須一次又一次地用相同的代碼編寫更少的參數?

+0

你的意思,你可以」 t改變「*計算*」? – 2012-01-12 14:13:05

+0

@Andrey是的,這就是我的意思。 – kechapito 2012-01-12 14:35:43

回答

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也是一個單元陣列,你可以彈出場您要執行的函數位於,然後將其餘的字段作爲參數傳遞給該函數。

+0

我喜歡它,它工作。現在我只是添加或刪除參數,並且只進行一次調用。 – kechapito 2012-01-12 14:37:43

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,儘管我想介紹一些細微的變化。
如果你的意思是,你不能改變計算(),那麼你可以使用varargin名稱/值成語。

(爲了運行此代碼,您必須下載從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);