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?
Valid function names follow the same rules as variable names. They must start with a letter, and can contain letters, digits, or underscores. To avoid confusion, use the same name for both the function file and the first function within the file. MATLAB associates your program with the file name, not the function name.
For MATLAB built-in data types, MATLAB always passes arguments 'by value' in the sense that any changes made to input arguments within a function are not visible to the respective variables in the caller workspace.
MATLAB® supports two syntaxes for passing name-value arguments. plot(x,y,LineWidth=2) name=value syntax. plot(x,y,"LineWidth",2) comma-separated syntax. Use the name=value syntax to help identify name-value arguments for functions and to clearly distinguish names from values in lists of name-value arguments.
Use function argument validation in MATLAB® to declare specific restrictions on function input arguments. You can constrain the class, size, and other aspects of function input values without writing code in the body of the function to perform these tests.
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
InputParser helps with this. See Parse Function Inputs for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With