Last updated on 2023-12-04 | Edit this page

## Overview

### Questions

- How can I teach MATLAB to do new things?
- How can I make programs I write more reliable and re-usable?

### Objectives

- Learn how to write a function
- Define a function that takes arguments.
- Compare and contrast MATLAB function files with MATLAB scripts.
- Recognise why we should divide programs into small, single-purposefunctions.

## Writing functions from scratch

It has come to our attention that the data about inflammation thatwe’ve been analysing contains some systematic errors. The measurementswere made using the incorrect scale, with inflammation recorded inArbitrary Inflammation Units (AIU) rather than the scientific standardInternational Inflmmation Units (IIU). Luckily there is a handy formulawhich can be used for converting measurements in AIU to IIU, but itinvolves some hard to remember constants:

### MATLAB

`inflammation_IIU = (inflammation_AIU + B)*AB = 5.634A = 0.275`

There are twelve files worth of data to be converted from AIU to IIU:is there a way we can do this quickly and conveniently? If we have tore-enter the conversion formula multiple times, the chance of us gettingthe constants wrong is high. Thankfully there is a convenient way toteach MATLAB how to do new things, like converting units from AIU toIIU. We can do this by writing a function.

We have already used some predefined MATLAB functions which we canpass arguments to. How can we define our own?

A MATLAB function *must* be saved in a text file with a`.m`

extension. The name of the file must be the same as thename of the function defined in the file.

The first line of our function is called the *functiondefinition* and must include the special `function`

keyword to let MATLAB know that we are defining a function. Anythingfollowing the function definition line is called the *body* ofthe function. The keyword `end`

marks the end of the functionbody. The function only knows about code that comes between the functiondefinition line and the `end`

keyword. It will not haveaccess to variables from outside this block of code apart from thosethat are passed in as *arguments* or *input parameters*.The rest of our code won’t have access to any variables from inside thisblock, apart from those that are passed out as *outputparameters*.

A function can have multiple input and output parameters as required,but doesn’t have to have any. The general form of a function is shown inthe pseudo-code below:

### MATLAB

`function [out1, out2] = function_name(in1, in2) % FUNCTION_NAME Function description % Can add more text for the function help % An example is always useful! % This section below is called the body of the function out1 = calculation using in1 and in2; out2 = another calculation;end`

Just as we saw with scripts, functions must be *visible* toMATLAB, i.e., a file containing a function has to be placed in adirectory that MATLAB knows about. Following the same logic we used withscripts, we will put our source code files in the `src`

folder.

Let’s put this into practice to create a function that will teachMATLAB to use our AIU to IIU conversion formula. Create a file called`inflammation_AIU_to_IIU.m`

in the `src`

folder,enter the following function definition, and save the file:

### MATLAB

`function inflammation_in_IIU = inflammation_AIU_to_IIU(inflammation_in_AIU) % INFLAMMATION_AIU_TO_IIU Convert inflammation mesured in AIU to inflammation measued in IIU. A = 0.275; B = 5.634; inflammation_in_IIU = (inflammation_in_AIU + B)*A;end`

We can now call our function as we would any other function inMATLAB:

### MATLAB

`>> inflammation_AIU_to_IIU(0.5)`

### OUTPUT

`ans = 1.6869`

We got the number we expected, and at first glance it seems like itis almost the same as a script. However, if you look at the variables inthe workspace, you’ll probably notice one big difference. Although avariable called `inflammation_in_IIU`

was defined in thefunction, it does not exist in our workspace.

Lets have a look using the debugger to see what is happening.

When we pass a value, like `0.5`

, to the function, it isassigned to the variable `inflammation_in_AIU`

so that it canbe used in the body of the function. To return a value from thefunction, we must assign that value to the variable`inflammation_in_IIU`

from our function definition line. Whatever value `inflammation_in_IIU`

has when the`end`

keyword in the function definition is reached, thatwill be the value returned.

Outside the function, the variables `inflammation_in_AIU`

,`inflammation_in_IIU`

, `A`

, and `B`

aren’t accessible; they are only used by in function body.

This is one of the major differences between scripts and functions: ascript can be thought of as automating the command line, with fullaccess to all variables in the base workspace, whereas a function hasits own separate workspace.

To be able to access variables from your workspace inside a function,you have to pass them in as inputs. To be able to save variables to yourworkspace, it needs to return them as outputs.

As with any operation, if we want to save the result, we need toassign the result to a variable, for example:

### MATLAB

`>> val_in_IIU = inflammation_AIU_to_IIU(0.5)`

### OUTPUT

`val_in_IIU = 1.6869`

And we can see `val_in_IIU`

saved in our workspace.

### Writing your own conversion function

We’d like a function that reverses the conversion of AIU to IIU.Re-arrange the conversion formula and write a function called`inflammation_IIU_to_AIU`

that converts inflammation measuedin IIU to inflammation measured in AIU.

Remember to save your function definition in a file with the requiredname, start the file with the function definition line, followed by thefunction body, ending with the `end`

keyword.

### MATLAB

`function inflammation_in_AIU = inflammation_IIU_to_AIU(inflammation_in_IIU) % INFLAMMTION_IIU_TO_AIU Convert inflammation measured in IIU to inflammation measured in AIU. A = 0.275; B = 5.634; inflammation_in_AIU = inflammation_in_IIU/A - B;end`

### Functions that work on arrays

One of the benefits of writing functions in MATLAB is that often theywill also be able to operate on an array of numerical variables *forfree*.

This will work when each operation in the function can be applied toan array too. In our example, we are adding a number and multiplying byanother, both of which work on arrays.

This will make converting the inflammation data in our files usingthe function we’ve just written very quick. Give it a go!

## Transforming scripts into functions

In the `patient_analysis`

script we created, we can choosewhich patient to analyse by modifying the variable`patient_number`

. If we want information about patient 13, weneed to open `patient_analysis.m`

, go to line 9, modify thevariable, save and then run `patient_analysis`

. This is a lotof steps for such a simple request.

Can we use what we’ve learned about writing functions to transform(or *refactor*) our script into a function, increasing itsusefulness in the process?

We already have a `.m`

file called`patient_analysis`

, so lets begin by defining a function withthat name.

Open the `patient_analysis.m`

file, if you don’t alreadyhave it open. Instead of line 9, where `patient_number`

isset, we want to provide that variable as an input. So lets remove thatline, and right at the top of our script we’ll add the functiondefinition telling MATLAB what our function is called and what inputs itneeds. The function will take the variable `patient_number`

as input and since we removed the line that assigned a value to thatvariable, the input will decide which patient is analysed.

### MATLAB

`function patient_analysis(patient_number) % PATIENT_ANALYSIS Computes mean, max and min of a patient and compares to global statistics. % Takes the patient number as an input, and prints the relevant information to console. % Sample usage: % patient_analysis(5) % Load patient data patient_data = readmatrix('data/base/inflammation-01.csv'); % Compute global statistics g_mean = mean(patient_data(:)); g_max = max(patient_data(:)); g_min = min(patient_data(:)); % Compute patient statistics p_mean = mean(patient_data(patient_number,:)); p_max = max(patient_data(patient_number,:)); p_min = min(patient_data(patient_number,:)); % Compare patient vs global disp('Patient:') disp(patient_number) disp('High mean?') disp(p_mean > g_mean) disp('Highest max?') disp(p_max == g_max) disp('Lowest min?') disp(p_min == g_min)end`

Congratulations! You’ve now created a MATLAB function from a MATLABscript!

You may have noticed that the code inside the function is indented.MATLAB does not need this, but it makes it much more readable!

Lets clear our workspace and run our function in the commandline:

### MATLAB

`>> clear>> clc>> patient_analysis(13)`

### OUTPUT

`Patient 13:High mean? 0Highest max? 0Lowest min? 1`

So now we can get the patient analysis of whichever patient we want,and we do not need to modify `patient_analysis.m`

anymore.However, you may have noticed that we have no variables in ourworkspace. Remember, inside the function, the variables`patient_data`

, `g_mean`

, `g_max`

,`g_min`

, `p_mean`

, `p_max`

, and`p_min`

are created, but then they are deleted when thefunction ends. If we want to save them, we need to pass them asoutputs.

Lets say, for example, that we want to save the mean of each patient.In our `patient_analysis.m`

we already compute the value andsave it in `p_mean`

, but we need to tell MATLAB that we wantthe function to return it.

To do that we modify the function definition like this:

### MATLAB

`function p_mean = patient_analysis(patient_number)`

It is important that the variable name is the same that is usedinside the function.

If we now run our function in the command line, we get:

### MATLAB

`p13 = patient_analysis(13)`

### OUTPUT

`Patient 5:High mean? 0Highest max? 0Lowest min? 1p13 = 0.1049`

We could return more outputs if we want. For example, lets return themin and max as well. To do that, we need to specify all the outputs insquare brackets, as an array. So we need to replace the functiondefinition for:

### MATLAB

`function [p_mean,p_max,p_min] = patient_analysis(patient_number)`

To call our function now we need to provide space for all 3 outputs,so in the command line, we run it as:

### MATLAB

`[p13_mean,p13_max,p13_min] = patient_analysis(13)`

### OUTPUT

`Patient 5:High mean? 0Highest max? 0Lowest min? 1p13_mean = 0.1049p13_max = 0.3450p13_min = 0`

### Callout

**Note** If you had not provided space for all theoutputs, Matlab assumes you are only interested in the first one, so`ans`

would save the mean.

### Plotting daily average of different data files

Look back at the `plot_daily_average`

script. The data andresulting image file names are hard-coded in the script. We actuallyhave 12 datafiles. Turn the script into a function that lets yougenerate the plots for any of the files.

The function should operate on a single data file, and should havetwo parameters: `data_file`

and `plot_file`

. Whencalled, the function should create the three graphs, and save the plotas `plot_file`

.

You should mostly be reusing code from the `plot_all`

script.

### MATLAB

`function plot_daily_average(data_file,plot_name) %PLOT_DAILY_AVERAGE Plots daily average, max and min inflammation accross patients. % The function takes the data in data_file and saves it as plot_name % Example usage: % plot_daily_average('data/base/inflammation-03.csv','results/plot3.png') % Load patient data patient_data = readmatrix(data_file); figure(visible='off') % Define tiled layout and labels tlo = tiledlayout(1,3); xlabel(tlo,'Day of trial') ylabel(tlo,'Inflammation') % Plot average inflammation per day nexttile plot(mean(patient_data, 1)) title('Average') % Plot max inflammation per day nexttile plot(max(patient_data, [], 1)) title('Max') % Plot min inflammation per day nexttile plot(min(patient_data, [], 1)) title('Min') % Save plot in 'results' folder as png image: saveas(gcf,plot_name) close()end`

### Plotting patient vs mean

Create a function called `patient_vs_mean`

that generatesa plot like this one:

The function should have the following inputs:

`per_day_mean`

- A 1D array with the averageinflammation per day already loaded (you’ll have to load the data andcompute per_day_mean before calling the function).`patient_data`

- A 1D array with the data for thepatient of interest only.`patient_reference`

- A string that will be used toidentify the patient on the plot, and also as a file name (you shouldadd the extension`png`

in your function).

When called, the function should create and save the plot as`patient_reference`

.png in the results folder.

Look back at the previous lessons if you need to!

### MATLAB

`function patient_vs_mean(per_day_mean,patient_data,patient_reference) % PATIENT_VS_MEAN Plots the global mean and patient inflammation on top of each other. % per_day_mean should be a vector with the global mean. % patient_data should be a vector with only the patient data. % patient_reference will be used to identify the patient on the plot. % % Sample usage: % patient_data = readmatrix('data/base/inflammation-01.csv'); % per_day_mean = mean(patient_data); % patient_vs_mean(per_day_mean,patient_data(5,:),"Patient 5") figure(visible='off') %Plot per_day_mean plot(per_day_mean,DisplayName="Mean") legend title('Daily average inflammation') xlabel('Day of trial') ylabel('Inflammation') %Overlap patient data hold on plot(patient_data,DisplayName=patient_reference) hold off % Save plot saveas(gcf,"results/"+patient_reference+".png") close()end`

### Key Points

- A MATLAB function
*must*be saved in a text file with a`.m`

extension. The name of the file must be the same as thename of the function defined in the file. - Define functions using the
`function`

keyword to startthe definition, and close the definition with the keyword`end`

. - Functions have an independent workspace. Access variables from yourworkspace inside a function by passing them as inputs. Access variablesfrom the function returning them as outputs.
- The header of a function with inputs an outputs has the form:

`function [output_1,output_2,...] = function_name(input_1,input_2,...)`

- Break programs up into short, single-purpose functions withmeaningful names.