Customizing MATLAB Functions#

Here we will look into customizing functions to perform more specific computations by continuing to build upon mySum().

Why should we customize mySum()?#

Previously, we created a function that calculated the sum of two inputs.

function ans = mySum(a, b)

ans = a + b
sprintf('%g + %g = %g', a, b, ans)

end

But, this function is limited in multiple ways. Currently, it can only take two inputs. What if we want more than two? What if we want to visually demonstrate the addition of negative numbers? We cannot do this with the current function. Therefore, we need to add additional elements to further customize the function.

Let’s take a look at what I mean.

Summing more than two numbers with mySum()#

There are a few additional components to building functions that are not required in the initial function creation, but will most likely be needed when implementing more complex functions. They are listed below.

  1. varargin This allows for multiple optional input arguments.

  2. nargin This returns the numbers of optional input arguments given by the user.

  3. switch case Allows you to execute one of several statements given a conditional.

Let’s try some of these out.

function ans = mySum(a, varargin)

if nargin == 1
    ans = a + a;
    sprintf('%g + %g = %g', a, a, ans)
elseif nargin > 1
    ans = a;
    for i = 1:length(varargin)
        ans = ans + varargin{i}
    end
    sprintf('Your sum is %g', ans)
end
end
            Error: MATLAB Kernel for Jupyter was unable to find the notebook server from which it was spawned!

            Resolution: Please relaunch kernel from JupyterLab or Classic Jupyter Notebook.
            

Here, we have made use of varargin and nargin to allow us to add more than just two numbers. Let’s break this code down.

First we begin by creating our function using the required syntax, but it’s changed from the previous iteration. It now looks like this : function ans = mySum(a, varargin). By including varargin, we can now allow for more than two arguments. I have also changed the input parameters by only including one required argument, a. I will explain that below.

Next, we have an if/elseif statement. The first if looks at the total number of inputs and checks if there is onnly 1 input given. If there is, then sum that input to itself. This is much neater than mySum(2, 2) which we would have done in the previous iteration of mySum(). The elseif checks if there is more than one input given. It then adds all of the remaining inputs to a.

This new version of mySum() will allow you to execute the function with many parameters and allows for more complex applications.

But how can we take this further? Let’s check out the switch case method to find the sum of the absolute values of inputs.

function ans = mySum(a, varargin)
if nargin == 1
    ans = a + a;
    sprintf('%g + %g = %g', a, a, ans)
elseif nargin == 1 && strcmp(varargin{end}, 'abs')
    switch sign(a)
        case -1
            a = a*(-1);
        otherwise
            a = a;
    end
    ans = a + a;
    sprintf('%g + %g = %g', a, a, ans)
elseif nargin > 1 && ~strcmp(varargin{end}, 'abs')
    ans = a;
    for i = 1:length(varargin)
        ans = ans + varargin{i};
    end
    sprintf('Your sum is %g', ans)
elseif nargin >= 1 && strcmp(varargin{end}, 'abs')
    switch sign(a)
        case -1
            a = a*(-1);
        otherwise 
            a = a;
    end
    nvar = length(varargin) - 1;
    for i = 1:nvar
        switch sign(varargin{i})
            case -1
               varargin{i} = varargin{i}*(-1);
            otherwise
               varargin{i} = varargin{i};
        end
    end
    ans = a;
    for i = 1:nvar
        ans = a + varargin{i};
    end
    sprintf('Your sum is %g', ans)
end
end
            Error: MATLAB Kernel for Jupyter was unable to find the notebook server from which it was spawned!

            Resolution: Please relaunch kernel from JupyterLab or Classic Jupyter Notebook.
            

This may seem like a lot. And to be fair, it is. But let’s break it down.

Just like the previous two iterations, we create our function with function ans = mySum(a, varargin).

Next we have a giant if/elseif block. Let’s break this down into smaller components. First we have

if nargin == 1
    ans = a + a;
    sprintf('%g + %g = %g', a, a, ans)

This checks if there was only one input given. If so, it will sum it to itself.

Second we have

elseif nargin == 1 && strcmp(varargin{end}, 'abs')
    switch sign(a)
        case -1
            a = a*(-1);
        otherwise
            a = a;
    end
    ans = a + a;
    sprintf('%g + %g = %g', a, a, ans)

This checks if there is only one input given and whether or not you want to find the absolute value of that input. When calling the function we want to add the string/char 'abs' to the end of the function inputs if we wish to find the sum of the absolute values of our input , which would look like this: mySum(-6, 'abs'). Then we begin switch. Here we say that the sign (either positive or negative) of a is our “switch expression”. We take this expression and test it agains each case. If it satisifes the case, it executes the code belonging to that case. I have included otherwise to tell the function, “if a is not negative, then keep it that way.” This is essentially how switch case logic works. This is repeated if there is more than one input, like mySum(1, 2, -12, 'abs').

switch case is probably not the most effective method in this particular case, but it has it’s uses. If you are working a lot with string/char input arguments, then switch case is the method you are going to use, as you do not need to ensure that user input arguments into a function in a specific order.

Note: MATLAB already has an absolute value function abs() but for the purposes of understanding, I have neglected to use this function. However, if you are feeling adventurous, try changing mySum() to make use of MATLAB’s abs() function.

Here, I’ve added some additional comments to the code which might help you better understand each step.

function ans = mySum(a, varargin)
% MYSUM calculates the sum of a number or multiple numbers
% a -- (double) number(s) to be summed
% Optional arguments
    % abs -- (string) to calculate absolute value of a.

% if the number of inputs is 1...
if nargin == 1
    ans = a + a; % add a to itself
    sprintf('%g + %g = %g', a, a, ans) % display answer

% if the number of inputs is 1 *and* the string 'abs' is passed as an input
elseif nargin == 1 && strcmp(varargin{end}, 'abs')
    switch sign(a) % check if a is positive or negative
        case -1
            a = a*(-1); % if a is negative, change it to positive
        otherwise
            a = a; % if a is positive, leave it
    end
    ans = a + a; % add a to itself
    sprintf('%g + %g = %g', a, a, ans) % display answer
elseif nargin > 1 && ~strcmp(varargin{end}, 'abs') % if there is more than 1 input but *no* string 'abs'
    ans = a;
    for i = 1:length(varargin)
        ans = ans + varargin{i}; % add a plus all other numbers
    end
    sprintf('Your sum is %g', ans) % display answer
elseif nargin >= 1 && strcmp(varargin{end}, 'abs') % if there is more than 1 inputs *and* the string 'abs' is passed as an input
    switch sign(a) % check is a is positive or negative 
        case -1
            a = a*(-1); % if a is negative, change it to positive
        otherwise 
            a = a; % if a is positive, leave it
    end
    nvar = length(varargin) - 1;
    for i = 1:nvar % loop throguh the rest of the numbers
        switch sign(varargin{i}) % check if the number is positive or negative
            case -1
               varargin{i} = varargin{i}*(-1); % is the number is negative, change to positive
            otherwise
               varargin{i} = varargin{i}; % if the number is positive, leave it
        end
    end
    ans = a;
    for i = 1:nvar % loop through the absolute values
        ans = a + varargin{i}; % add a plus absolute values
    end
    sprintf('Your sum is %g', ans) % display answer
end
end
            Error: MATLAB Kernel for Jupyter was unable to find the notebook server from which it was spawned!

            Resolution: Please relaunch kernel from JupyterLab or Classic Jupyter Notebook.