Code covered by the BSD License  

Highlights from
Optional function arguments

image thumbnail

Optional function arguments

by

 

02 Nov 2012 (Updated )

Optional function arguments with default values: optndfts

optndfts(args,varargin)
function [opts,opts2]=optndfts(args,varargin)
% optndfts  Create option struct with default values for those not given
%  2015-07-28  Matlab  Copyright (c) 2012, W J Whiten  BSD License
%
% opts=optndfts(args,dflts)
% opts=optndfts(args,initial,dflts)
%  args     Typically varargin from calling function
%            A cell array containing: initial arguments if present  
%            then name value pairs, or containing a struct,
%            or containing a cell array of name value pairs.
%            Alternatively a struct. Note initial arguments can not be of
%            type char, and a single struct or cell, in a cell array 
%            will be interpreted as giving option names and values.
%  initial  A cell array of the names of optional initial arguments given
%            without names in varargin of the calling function (ie args).
%            These names are the given order for the optional initial 
%            arguments and zero or more of the initial arguments can
%            can be given in args (the optional initial arguments 
%            in args can not be of type char (unless preceeded by -)
%            , or a single struct or cell array).
%            The names given here must have default values in dflts.
%            This argument is optional.
%  dflts    Argument list giving default name value pairs, or a struct, 
%            or a cell array of name value pairs.
%
%  opts     Struct giving names and values for all variables in dflts
%  opts2    Struct giving names & values of fields not in opts (optional)
%            If given fields not in dflts do not give an error
%            Can be used to pass options to nested functions (note
%            alternative is to put in a field containing a struct 
%            with options for nested functions)
%
% Use to process optional arguments given as name value pairs, a cell 
%  array of name value pairs, or as a struct. Default values from 
%  optndfts call are used for values not given in args.
% 
% Example:
% Using optndft within a function as follows: 
%    function strt=test1(a,varargin) % varargin values replace defaults
%    strt=optndfts(varargin,'aa',1,'bb',2,'cc',3); % give default values
%    end
% Then demo could be called as:
%    test1(123,'bb',22)
% And optndfts fills in default values for those not given::
%    ans = 
%        aa: 1
%        bb: 22
%        cc: 3
% 
% Also can allow for optional arguments that are not named:
%    function strt=test2(arg1,varargin)  % varargin replaces defaults
%    strt=optndfts(varargin,{'aa','bb'},'aa',1,'bb',2,'cc',3);
%    return  	% optndfts returns a struct
%    end
% 
%    test2(123,11,'cc',33)
%    ans = 
%        aa: 11
%        bb: 2
%        cc: 33
% 
% See also:  inputParser

% check for two or three arguments
if(length(varargin)>1 && iscellstr(varargin{1}))
    initial=varargin{1};
    varargin=varargin(2:end);
else
    initial={};
end

% convert varargin inputs to a struct
if(~isempty(varargin) && iscell(varargin{1}))
    opts=varargin{1};
    if(iscell(opts))
        opts=struct(opts{:});
    end
else
    opts=struct(varargin{:});   % varargin{1} a struct is ok
end

% initial value for second output
opts2=struct();

% if input args not a struct convert to struct
firstargs={};
if(iscell(args))
    
    % first check for initial arguments without name
    i=0;
    if(~(length(args)==1 && (isstruct(args{1}) || iscell(args{1}))))
        while(i<length(args))
            if(ischar(args{i+1}))
                if(args{i+1}(1)=='-')
                    args{i+1}=args{i+1}(2:end);
                else
                    break
                end
            end
            i=i+1;
        end
    end
    if(i>length(initial))
        error('optndfts: Too many unnamed input arguments')
    end
    firstargs=args(1:i);
    args=args(i+1:end);
    
    if(~isempty(args) && iscell(args{1}))
        args=args{1};
        if(iscell(args))
            args=struct(args{:});
        end
    else
        % for cell array of name value pairs
        args=struct(args{:});
    end
end

% initial arguments without names in args, copy over defaults
for i=1:length(firstargs)
    if(~isfield(opts,initial{i}))
        error(['optndfts: Initial name  ',initial{i},  ...
            '  does not have default value'])
    else
        opts.(initial{i})=firstargs{i};
    end
end

% copy new values over default values
names=fieldnames(args);
for i=1:length(names)
    if(~isfield(opts,names{i}))
        if(nargout>1)
            opts2.(names{i})=args.(names{i});
        else
            error(['optndfts: Invalid field name  ',names{i}])
        end
    end
    opts.(names{i})=args.(names{i});
end

return
end

Contact us