Functions


Functions

matlab



What is a function?

In mathematics we think of functions like this:

In programming, functions are a little different. In Matlab, a function can:

  • Receive Information - Input Arguments(s)
  • Process Information - Carry out Operations on input arguments
  • Return Information - Return Output Argument(s)

However all are optional, i.e. it is ok for a function to have no inputs.

Matlab functions

Matlab has many ‘built in’ functions, sin, mean, sort etc. We can also write our own functions to perform specific tasks:

function out = add_two(in)
% Usage:
%  out = add_two(in)
%  in  : Argument passed in
%  out : Output, the result of adding two to the input.

out = in + 2;
end

In this case code is saved in a file named add_two.m and it is very important that the name of the m-file matches the name of the function. The name must start with a letter. This first letter can only be followed by letters, numbers and underscores. No dashes!

To call our function at the command line. We pass a as an input argument to the function add_two. The return value is then assigned to b:

>> a = 5

a =
5

>> b = add_two(a)

b =
7
Built in functions

Matlab has many built in functions, a few more examples include:

  • fprintf – Displays a message written by the user and can include variables.
  • rand – Displays random number(s).
  • numel – Displays the number of elements in an array.

Scope

The scope of a variable describes where it can be accessed and used, i.e. where it is ‘visible’. This is useful at the command line or within a function (e.g. when debugging)

However be careful as the same name can be used for different variables if they have different scope. In the following example both places (the command line and in the file) have a variable x nut they are not in the same scope:

  • At the command line

    >> x = 11;
    
  • In the file my_cube.m

    function y = my_cube(x)
    y = x * x * x;
    end
    

You can check which variables are in current scope as they appear in the workspace window. Or you could use the whos command.

Scripts

When you save any sequence of commands in a ‘.m’ file, the file is known as a script. There are many differences between scripts & functions:

Script Function
No function/end keywords Wrapped in function/end
No arguments in and out Can have arguments in and out
To change behaviour: need to edit file To change behaviour: call with a different argument
Variables in the workspace are affected Variables in the workspace are not affected
Script’s variables are in the same global scope as workspace Function variables are in the its local scope

More than one function in a file

It is possible to have more than one function in a file. The first function must match the name of the file. It is then possible for this function to call another function which is defined later on in the file. e.g.

scratch.m
function scratch()
disp('Call to scratch')
foo()
end

function foo()
disp('Call to foo!!')
end

However in this case, the function foo can only be called from within scratch.m or from the command line. It is not in scope to be called from inside another script.

It is illegal to start off an m-file as a script and then attempt to finish it by defining a function. Matlab is not a ‘pick-n-mix’ language.

fprintf in more depth

There are many different ways in which fprintf can be used. Here are a few common examples:

In the following case, %f interprets the result of x + y as a floating point number:

fprintf('The sum is %f\n', x + y)

\n is used to denote a new line after printing:

fprintf( 'low\n' )

%u is interpreted as an unsigned integer, i.e. in the below case, it denotes the value of total:

fprintf('Sum = %u\n' , total)

fprintf is a very flexible function and can be used in more complex situations. Here it interprets the first argument as a string, due to %s and the second as an unsigned integer due to %u:

name = 'Jack';
age = 21;
fprintf('%s is %u years old\n' , name, age)

Error checking

If code is written so that it explicitly checks for errors. Later on it helps debugging and tracking down causes of errors. And this in turn makes the code more robust.

Matlab has built-in functions to help checking:

  • warning: when function can proceed but may not work as expected
  • error: when function really cannot proceed

Below is a detailed example of how the error function can be used. The following function expects an array of numbers. If the user gives an empty, we should not return a result:

function [l,m] = compare_to_mean(x)
% usage:
%    [l,m] = compare_to_mean(x)
% Input:
%     x - A list of numbers
% Outputs:
%     l - Number of values in x less than mean
%     m - Number of values in x greater than mean

% Check:
if isempty(x)
  error('compare_to_mean: %s' , 'Input array empty.');
end

% ... rest of function below

The built in isempty function checks if the input is valid. If the check fails, the error function is called. This will cause the function to halt and return. Note, the arguments to error are treated in the same way as fprintf.

We can also include a warning function is the example:

% from previous ...

% A warning check:
if ~ isreal(x)
  warning('compare_to_mean: %s' , 'Input has complex values');
end

% ... rest of function below

The isreal function checks that all the input elements are real (i.e. not complex numbers). If the check fails the warning function will display a message to the operator. However the overall function will continue but may not result to be what the operator expects.

The Matlab Path

Just below the toolbar, the user interface tells us the Present Working Directory (PWD). We can also tell where we are using the pwd command. Functions saved in the files in the PWD can be called directly. But if a function file is located elsewhere, we need to include its location in the Path.

The Matlab Path is actually a list of directories, where Matlab searches for files containing functions. We can add our own directories to the list using the addpath command:

  • If PWD is ’/path/to/current/directory’
  • And the function we want is in ’/some/other/directory’
  • We need to run the following at the command line: >> addpath(’/some/other/directory’)
  • Then we will be able to call our function (otherwise we will get an error)

In Windows, we should include the drive letter, e.g. ’C:’ or ’N:’. For example, if we have files saved in a folder called myMatlabFiles, in ‘My Documents’ on shared drive ’N;’, we should write >> addpath('N:/My Documents/myMatlabFiles’) in the command line.

Recursive functions

Here is an example of a recursive function, it prints a message and then calls itself:

dontDoThis.m
function dontDoThis()

fprintf('No really, ');
fprintf('Don''t do this\n');

dontDoThis()

end

Command Line (0) —> dontDoThis.m (1) —>dontDoThis.m (2) —> dontDoThis.m (2) —> … (Depth of recursion)

However you will get an error:

>> dontDoThis
Maximum recursion limit of 500 reached ... Be aware that exceeding your available stack space can crash MATLAB and/or your computer.

Error in dontDoThis

Such functions need a way to avoid infinite recursion. They need either:

  • Stopping condition
  • Base case
  • Ground case

A recursive function with a stopping condition

For example if we define a sequence as follows:

  • Start with any number (a)
  • The next number in the sequence is… (a \div 2) if (a) is even(3a + 1) if (a) is odd.
  • Stop when we reach 1.

Starting at 6 we get the following sequence:

  • 6, 3, 10, 5, 16, 8, 4, 2, 1

    It takes 8 steps to reach 1. We want a function to give the number of steps for any stating number. Here is an example of the code which could be used:

function nSteps = recFunc(a)

% base case
if a == 1
  nSteps = 0;
  return
end

if mod(a,2) == 0
  % a is even
  nSteps = 1 + recFunc (a / 2);
else
  % a is odd
  nSteps = 1 + recFunc (3 * a + 1);
end

end

The % base case is the vital stopping condition. We make a recursive call if we haven’t reached the stopping condition. We add 1 to the steps returned from the recursive call, in order to include the step for the current call.


return  link
Written by Tobias Whetton