While solutions with nargin are already given and more or less a standard usage within most MATLAB codebases, I think there is a nicer alternative that is more readable.
With nargin in big functions, you have to remember what argument 3 was exactly. Especially if you have more optional arguments, it becomes cumbersome to keep track or to allow that some optional arguments are passed, while others are not.
The first and easier solution is my personal alternative to nargin, and that is using the exist function:
function [output] = getValue(modelName,param,option, otherOption)
if ~exist('option', 'var') || isempty(option)
option = 'defaultValueForOption';
end
if ~exist('otherOption', 'var') || isempty(otherOption)
otherOption = 'defaultValueForOption';
end
% perform other actions
The advantage is that now all input-related code is at the beginning and it is more verbose as to what should be happening. You won't clutter your other code with that logic. And you can also supplement those if statements with validation of the input and fall back onto the default when an invalid option is given.
The other possibility is standard in later versions of MATLAB: the inputParser class. With this class, you can define even more complicated scenarios of optional parameters and even key-value pairs.
Below is a self-descriptive example I have kept to avoid needing the documentation every time.
%% Usage Example input Parser
%
function output = FuncName(rParam1, rParam2, oParam1, oParam2, varargin)
p = inputParser();
defaultValue = 0;
validatorFunc = @(x)(true); % validator function should return true when x is valid
%% Input Format definition
p.addRequired('rParam1', validatorFunc);
p.addRequired('rParam2', validatorFunc);
p.addOptional('oParam1', defaultValue, validatorFunc);
p.addOptional('oParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam1', defaultValue, validatorFunc);
p.addParamValue('kvParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam3', defaultValue, validatorFunc);
p.addParamValue('kvParam4', defaultValue, validatorFunc)
%% Optional Settings
% expand supplied struct to ParamValue pairs (or other arguments)
p.StructExpand = true; % default: false
%% Parse
p.parse(rParam1, rParam2, oParam1, oParam2, varargin{:})
%% Retrieve results
values = p.Results(); % structure with all values
defaultedArgs = p.UsingDefaults; % cell array of all parameter names using defaults
end
This approach is even more verbose and personally, I don't quite like the fact that one has to redefine for every input whether it is required or optional and that it requires quite a lot of boilerplate code. But at least, it is a solution that is a standard solution and without a doubt to be preferred for larger functions.
Both approaches do suffer from a drawback compared to the nargin way of checking: they are both slower. So if you use these in functions that get called a lot (or only perform a very quick calculaion), it might be more worthwhile to use nargin instead.
runModelto do if you don't pass theoptionparameter ?