Search code examples
functionmatlabargumentsfunction-parametername-value

How to deal with name/value pairs of function arguments in MATLAB


I have a function that takes optional arguments as name/value pairs.

function example(varargin)
% Lots of set up stuff
vargs = varargin;
nargs = length(vargs);
names = vargs(1:2:nargs);
values = vargs(2:2:nargs);

validnames = {'foo', 'bar', 'baz'};    
for name = names
   validatestring(name{:}, validnames);
end

% Do something ...
foo = strmatch('foo', names);
disp(values(foo))
end

example('foo', 1:10, 'bar', 'qwerty')

It seems that there is a lot of effort involved in extracting the appropriate values (and it still isn't particularly robust again badly specified inputs). Is there a better way of handling these name/value pairs? Are there any helper functions that come with MATLAB to assist?


Solution

  • I prefer using structures for my options. This gives you an easy way to store the options and an easy way to define them. Also, the whole thing becomes rather compact.

    function example(varargin)
    
    %# define defaults at the beginning of the code so that you do not need to
    %# scroll way down in case you want to change something or if the help is
    %# incomplete
    options = struct('firstparameter',1,'secondparameter',magic(3));
    
    %# read the acceptable names
    optionNames = fieldnames(options);
    
    %# count arguments
    nArgs = length(varargin);
    if round(nArgs/2)~=nArgs/2
       error('EXAMPLE needs propertyName/propertyValue pairs')
    end
    
    for pair = reshape(varargin,2,[]) %# pair is {propName;propValue}
       inpName = lower(pair{1}); %# make case insensitive
    
       if any(strcmp(inpName,optionNames))
          %# overwrite options. If you want you can test for the right class here
          %# Also, if you find out that there is an option you keep getting wrong,
          %# you can use "if strcmp(inpName,'problemOption'),testMore,end"-statements
          options.(inpName) = pair{2};
       else
          error('%s is not a recognized parameter name',inpName)
       end
    end