MATLAB: using inputParser with varargin

I have a function for which I would like to pass arguments through varargin and use inputParser to ensure that the inputs are normal. Some arguments are required, and some are not. Here is an example:

 function myFunc(varargin) p = inputParser; p.addRequired(... 'numStates', ... @(x) validateattributes(x, {'numeric'}, ... {'scalar', 'integer', 'positive'})); p.addRequired(... 'numInps', ... @(x) validateattributes(x, {'numeric'}, ... {'scalar', 'integer', 'positive'})); p.addRequired(... 'numOuts', ... @(x) validateattributes(x, {'numeric'}, ... {'scalar', 'integer', 'positive'})); p.addRequired(... 'X0', ... @(x) validateattributes(x, {'numeric'}, ... {'vector'})); p.addOptional(... 'freq', 10, ... @(x) validateattributes(x, {'numeric'}, ... {'scalar', 'integer', 'positive'})); p.addOptional(... 'SimulinkVariables', struct(), ... @(x) isa(x, 'struct')); p.parse(varargin{:}); %# do stuff with variables end 

I would like to be able to pass arguments as follows: it does not matter which pair passes, when, while there are necessary ones. Thus, an example could be as follows:

 myFunc('numStates', 4, 'numInps', 2, 'numOUts', 3, 'X0', [4;0]); 

This syntax seems to be illegal; parse() expects the first arguments in it to be the required values, but they should not be explicitly named, that is, as in:

 function myFunc(numStates, numInps, numOuts, X0, varargin) ... p.parse(numStates, numInps, numOuts, X0, varargin{:}); end 

Is there an easy way to get this to do what I want, i.e. first function? I think the easiest way is to do something to reorder the varargin elements and throw out the argument names, but this is not very elegant.

+4
source share
2 answers

The most elegant solution I can think of is a subclass of inputParser . This way you can do something like this (with the exception of myInputParser.m):

 classdef myInputParser < inputParser properties required = {}; end methods function obj = myInputParser obj = obj@inputParser ; end function addRequired(obj, argname, validator) obj.required = {obj.required{:}, argname}; obj.addOptional(argname, [], validator); end function parse(obj, varargin) params_input = varargin(1:2:end); for i=1:length(obj.required) if isempty(strmatch(obj.required{i}, params_input)) error(sprintf('Required named parameter %s was not passed to function', obj.required{i})); end end parse@inputParser (obj, varargin{:}); end end end 

Then change

  p = inputParser; 

to

  p = myInputParser; 

and then your code will work the way you want.

Note that this may not handle all cross cases correctly, and I have not tested it extensively, but it works with your use case.

+7
source

In InputParser you can add pairs ParameterName - ParameterValue only with addParamValue . These arguments must be optional.

As a workaround, you can add all your parameters with addParamValue and use [] as the default value for the required arguments.

Then you can do one of the following:

  • add "not empty" to the attributes in the validateattributes function for the required arguments (however, in this case the error message will not indicate that these are the required arguments, but that this should not be empty)
  • or add a separate check (with if or assert ) for which the required arguments should not be empty with your own error message.

You cannot use [] . By default, there can be any value that does not correspond to a specific parameter and is easily verified.

+5
source

Source: https://habr.com/ru/post/1395705/


All Articles