1

Is there a way to supply arguments using varargin in MATLAB in the following manner?

Function

func myFunc(varargin)
  if a not given as argument
    a = 2;
  if b not given as argument
    b = 2;
  if c not given as argument
    c = a+b;
  d = 2*c;
end

I want to call the above function once with b = 3 and another time while the previous one is running in the same command window with a = 3 and c = 3 and letting b take the default value in the function this time. How can it be done using varargin?

1
  • Arguments go in order. If you give 2 arguments, then the function has arguments 1 and 2 defined. Options are to pass an empty array for unused args, check to see how many arguments are passed and do something different for 1 or 2 arguments, or using name-value pairs. Commented Mar 15, 2021 at 1:04

2 Answers 2

1

Here's the latest and greatest way to write the function (using arguments blocks from R2019b)

function out = someFcn(options)
arguments
    options.A = 3;
    options.B = 7;
    options.C = [];
end
if isempty(options.C)
    options.C = options.A + options.B;
end
out = options.A + options.B + options.C;
end

Note that this syntax does not allow you to say options.C = options.A + options.B directly in the arguments block.

In MATLAB < R2021a, you call this like so

someFcn('A', 3)

In MATLAB >= R2021a, you can use the new name=value syntax

someFcn(B = 7)
Sign up to request clarification or add additional context in comments.

2 Comments

Wow I didn't know about this approach - my gut reaction is that the = syntax is pretty horrible; an assignment inside a function call seems to jibe against existing MATLAB convention! Is the options input here a keyword now or just made important because it's used within the arguments block? Does the old style 'name', value pairing not work at all with options pre 21a or is the = syntax just preferred?
You can use either name = value or 'name', value interchangeably to your own taste ;) There's nothing magic about the name options - you can use whatever you like, so long as you use the struct syntax in the arguments block. (Of course, you can also augment this with type validations and so on).
1

Here are two ways to do this which have been available since 2007a (i.e. a long time!). For a much newer approach, see Edric's answer.

  1. Use nargin and ensure your inputs are always in order
  2. Use name-value pairs and an input parser

nargin: slightly simpler but relies on consistent input order

function myFunc( a, b, c )
    if nargin < 1 || isempty(a)
        a = 2;
    end
    if nargin < 2 || isempty(b)
        b = 2;
    end
    if nargin < 3 || isempty(c)
        c = a + b;
    end
end

Using the isempty check you can optionally provide just later arguments, for example myFunc( [], 4 ) would just set b=4 and use the defaults otherwise.


inputParser: more flexible but can't directly handle the c=a+b default

function myFunc( varargin )
    p = inputParser;
    p.addOptional( 'a', 2 );
    p.addOptional( 'b', 2 );
    p.addOptional( 'c', NaN ); % Can't default to a+b, default to NaN
    p.parse( varargin{:} );

    a = p.Results.a;
    b = p.Results.b;
    c = p.Results.c;
    if isnan(c) % Handle the defaulted case
        c = a + b;
    end
end

This would get used like myFunc( 'b', 4 );. This approach is also agnostic to the input order because of the name-value pairs, so you can also do something like myFunc( 'c', 3, 'a', 1 );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.