0
votes

I have a function that has at least two required input arguments. Depending on the value of the second argument, there might be a third required input argument. I am wondering what is the best way to code a robust function that incorporates these requirements using MATLAB's input parser?

The function may look like this:

function vout = test(ReqInpArg1, ReqInpArg2, varargin)

ReqInpArg2 may hold the following string content:

  • 'cash'
  • 'absHurdleRate'
  • 'none'

If the user chooses cash, than another input argument numCashTicker needs to be defined as part of varargin, e.g. 'numCashTicker', 4. If absHurdleRatehas been choosen, a different input parameter has to be defined, e.g. 'hurdleRate', 0.2. If, on the other hand, none has been chosen, none of these input parameter must be defined. As a matter of fact, numCashTicker and hurdleRate are mutually exclusive, i.e. they must not be defined at the same time. In addition, if the user didn't chose none, he must define one of the other varargin input arguments.

What is best practice / the best strategy in order to implement these requirements?

1
Can you please post a code sample? Also don't ask for the "best strategy", because it's too general - make it more specific. - Rotem

1 Answers

0
votes

I came up with the following solution:

function vout = test(timeSeries, hurdleRate, varargin) 
    p = inputParser;
    expectedTypes = {'none', 'cash' 'absHurdleRate'}; 
    default_numCashTicker = [];
    default_absHurdleRate = [];
    p.addRequired('timeSeries');
    p.addRequired('hurdleRate',@(x) any(validatestring(x,expectedTypes)));
    p.addParameter('numCashTicker', default_numCashTicker);
    p.addParameter('absHurdleRate', default_absHurdleRate);
    
    parse(p, timeSeries, hurdleRate, varargin{:});

    numCashTicker = p.Results.numCashTicker;

    switch hurdleRate
        case 'none'
            if ~isequal(numCashTicker, default_numCashTicker)
                throw(MException('test:ParsingError', ...
                    '"none" does not require the "numCashTicker" parameter values"'));
            elseif ~isequal(absHurdleRate, default_absHurdleRate)
                throw(MException('test:ParsingError', ...
                    '"none" does not require the "absHurdleRate parameter values"'));
            end

        case 'cash'
            if ~isnumeric(numCashTicker)
                throw(MException('test:ParsingError', ...
                    '"cash" requires a numeric "numCashTicker" parameter value'));
            elseif ~isequal(absHurdleRate, default_absHurdleRate)
                throw(MException('CSmomRoC:ParsingError', ...
                    '"cash" does not require the "absHurdleRate parameter values"'));
            end

        case 'absHurdleRate'
            if ~isnumeric(absHurdleRate)
                throw(MException('CSmomRoC:ParsingError', ...
                    '"absHurdleRate" requires a numeric "absHurdleRate" parameter value'));
            elseif ~isequal(numCashTicker, default_numCashTicker)
                throw(MException('CSmomRoC:ParsingError', ...
                    '"absHurdleRate" does not require the "numCashTicker" parameter value.'));
            end
    end

    ...
    ...
    ...
end;