Search code examples
matlabfunctionargumentsoptional-parametersoptional-arguments

Input parser interdependent optional argument


In the following function, I tried to let Pt be on optional input parameter. In case Pt is not specified, it needs other optional parameters to be computed (that part works). But when I specify it:

Alg(b,'circle','Pt',ones(150,1))

I get the following error:

'Pt' is not a recognized parameter. For a list of valid name-value pair arguments, see the documentation for this function.

Code of the function:

function [ v ] = Alg( b,shape,varargin )

%%Parse inputs
p = inputParser;

addRequired(p,'b',@isnumeric);
expectedShapes = {'square','circle'};
addRequired(p,'shape',@(x) any(validatestring(x,expectedShapes)));

defaultIt = 42;
addParameter(p,'It',defaultIter,@isnumeric);

addParameter(p,'t',@isnumeric);
addParameter(p,'v',@isnumeric);

parse(p,b,shape,varargin{:})
b = p.Results.b;
shape = p.Results.shape;
It = p.Results.It;
t = p.Results.t;
v  = p.Results.v;

parse(p,b,shape,varargin{:})
defaultPoint = Alg_sq(b,Pt,It);
defaultPoint = Sub_Alg(defaultPoint,shape,t,v);
addParameter(p,'Pt',defaultPoint,@isnumeric);
Pt = p.Results.Pt;

%%Shape
switch shape
    case 'circle'
        v = Alg_crcl( b,Pt,It );

    case 'square'
        v = Alg_sq( b,Pt,It );
end
end

Thanks a lot for your help!


Solution

  • It errors because Pt was not specified as a valid parameter name when you initially parsed the arguments. You need to slightly restructure the code, here is how I would do it:

    function v = Alg(b, shape, varargin)
    
        % define arguments
        p = inputParser;
        addRequired(p, 'b', @isnumeric);
        addRequired(p, 'shape', @(x) any(validatestring(x,{'square','circle'})));
        addParameter(p, 'It', 42, @isnumeric);
        addParameter(p, 't', @isnumeric);
        addParameter(p, 'v', @isnumeric);
        addParameter(p, 'Pt', [], @isnumeric);   % default for now is empty matrix
    
        % parse arguments
        parse(p, b, shape, varargin{:})
        b = p.Results.b;
        shape = p.Results.shape;
        It = p.Results.It;
        t = p.Results.t;
        v  = p.Results.v;
        Pt = p.Results.Pt;
        if isempty(Pt)
            % insert your logic to compute actual default point
            % you can use the other parsed parameters
            Pt = computeDefaultValue();
        end
    
        % rest of the code ...
    
    end