main

60
UNIVERSITY OF SOUTHAMPTON FACULTY OF ENGINEERING AND THE ENVIRONMENT Institute of Sound and Vibration Research A Refresher Course in MATLAB Course Manual Rachel M. van Besouw, Timos Papadopoulos, Katrine S. Rogers, Emery M. Ku and Chris J. Powles This work is licenced under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this licence, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA. January 2011

Upload: timosp1973

Post on 01-Dec-2014

95 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Main

UNIVERSITY OF SOUTHAMPTON

FACULTY OF ENGINEERING AND THE ENVIRONMENT

Institute of Sound and Vibration Research

A Refresher Course in MATLAB

Course Manual

Rachel M. van Besouw, Timos Papadopoulos, Katrine S. Rogers,

Emery M. Ku and Chris J. Powles

This work is licenced under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 UnportedLicense. To view a copy of this licence, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a

letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.

January 2011

Page 2: Main

Contents

1 Introduction 1

1.1 Aims, Objectives & Learning Outcomes . . . . . . . . . . . . . . . .. . . . . . . 1

1.2 Supporting Code Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . 2

1.3 Course Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 3

1.4 New Features & Demos in MATLAB . . . . . . . . . . . . . . . . . . . . . . .. 3

1.5 Using Commands in MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . .4

1.6 Arranging the MATLAB Window . . . . . . . . . . . . . . . . . . . . . . . .. . 7

1.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2 Programming for Correctness 8

2.1 Handling Warnings & Errors . . . . . . . . . . . . . . . . . . . . . . . . .. . . . 8

2.1.1 Try-Catch Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.1.2 MException Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10

2.1.3 Validation Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11

2.2 Debugging Tools in MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . .. . 12

2.2.1 M-Lint Code Analyzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2.2 Function Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14

2.2.3 Breakpoints & Stepping Through Code . . . . . . . . . . . . . . . . .. . 15

i

Page 3: Main

2.2.4 TODO & FIXME Comments . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.3 Assessing Code Performance . . . . . . . . . . . . . . . . . . . . . . . . .. . . . 18

2.3.1 TicToc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.3.2 Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.5 Test Yourself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 20

3 Structuring Code 21

3.1 Private Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 21

3.2 Function Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . 22

3.3 Anonymous Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . 23

3.4 Subfunctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 24

3.5 Nested Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . 25

3.6 Precedence Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 27

3.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.8 Test Yourself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 28

4 Structuring Data 29

4.1 Cell Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.1.1 Importing Data From a Text File . . . . . . . . . . . . . . . . . . . .. . . 30

4.1.2 Indexing Cell Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32

4.2 Structure Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 36

4.2.1 Creation and Indexing of Structure Arrays . . . . . . . . . . .. . . . . . . 36

4.2.2 Dynamic Fieldnames . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38

ii

Page 4: Main

4.3 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . 40

4.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.5 Test Yourself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 42

5 Visualising Data & GUI Development 43

5.1 Object Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 44

5.2 Modifying Object Properties . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 45

5.3 Adding Uicontrol Objects . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . 46

5.4 Plot Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48

5.5 Animations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50

5.5.1 Creating a Movie using Getframe . . . . . . . . . . . . . . . . . . . .. . 50

5.5.2 Modifying Graphics Object Properties using Drawnow .. . . . . . . . . . 51

5.6 Graphical User Interface (GUI) development in GUIDE . . .. . . . . . . . . . . . 52

5.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

5.8 Test Yourself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 55

iii

Page 5: Main

Chapter 1

Introduction

1.1 Aims, Objectives & Learning Outcomes

The overall aims of this course are to widen your knowledge ofthe tools available in MATLAB,and enable you to program more efficiently and effectively using relevant and hopefully motivatingexamples.

The teaching objectives of the course are to reintroduce youto the MATLAB environment, draw-ing attention to the features of recent releases and helpfulkeyboard shortcuts; introduce efficientmethods for debugging, assessing the performance of and speeding up code; provide examples ofthe different function and data types and explain the implications of each; and provide an overviewof the visualisation techniques and graphical user interface (GUI) development tools available inMATLAB.

By the end of the course it is anticipated that you will be able to:

• More efficiently utilise the MATLAB environment, includingrecent features

• Select and use appropriate tools for debugging and improving the efficacy of code

• Select and use appropriate function and data types for optimal performance

• Select and use appropriate methods for visualising data

• Implement or amend basic GUIs for research or demonstrationpurposes

1

Page 6: Main

1.2 Supporting Code Files

The MATLAB code files for this course are organised in the directory structure shown in Figure1.1. The parent directory of each unit (e.g. ‘2Programmingfor Correctness’) contains a corre-sponding code file (e.g. ‘Part2Programmingfor Correctness.m’) with exercises for delegates tocomplete, together with supporting code files and data. The parent directory for each unit alsocontains a sub directory called ‘InstructorVersion’, which contains the model solutions.

2_Programming_for_Correctness(contains Part2_Programming_for_Correctness.m)

Instructor_Version

3_Structuring_Code(contains Part3_Structuring_Code.m)

private

4_Structuring_Data(contains Part4_Structuring_Data.m)

Instructor_Version

5_Visualising_Data(contains Part5_Visualising_Data.m)

Instructor_Version

Instructor_Version

CIPIC_hrtf_database

Figure 1.1: Structure of supporting code files

The supporting code files were created and tested in MATLAB version 7.11 (R2010b) and theWindows XP operating system. The shortcuts, menu commands and filepaths used here may needto be adapted for other operating systems.

2

Page 7: Main

1.3 Course Structure

1. Introduction (9:00 - 9:30)

2. Programming for Correctness (09:30 - 11:00)

Coffee (11:00 - 11:15)

3. Structuring Code (11:15 - 12:15)

Lunch (12:15 - 13:15)

4. Structuring Data (13:15 - 14:15)

5. Visualising Data & GUI Development (14:15 - 15:45)

Coffee (15:45 - 16:00)

GUI Developement Time and Q&A Session

1.4 New Features & Demos in MATLAB

To find out that is new in the most recent version of MATLAB, navigate to:

Help → Product Help → MATLAB → Release Notes

and click on the ‘Details’ link in the ‘New Features and Changes’ column for the latest version(see Figure 1.2).

Figure 1.2: Details of the new features & changes in MATLAB

3

Page 8: Main

For example, in version 7.10 (R2010a) underNew Features and Changes to the DesktopTools and Development Environment → Editing and Debugging MATLAB Code you willsee that the MATLAB editor now supports tab completion for local variable and subfunction nameswithin MATLAB program files.

For code and video demonstrations on the topics of: Getting Started, Mathematics, Graphics, 3-DVisualization, Programming, Desktop Tools and Development Environment, Creating GraphicalUser Interfaces, External Interfaces, and New Features, navigate to:

Help → Product Help → MATLAB → Demos

Figure 1.3: Code and video demonstrations

1.5 Using Commands in MATLAB

Most commands in MATLAB can be done in one of three ways; clicking in the correct menu,using a shortcut or typing a command at the command prompt. Sometimes there is also a buttonwhich can be clicked. A few common examples are given in Table1.1.

Operation Shortcut Command MenuOpen new m-file Ctrl+N edit File → New → ScriptSave file Ctrl+S save filename File → SaveOpen saved file Ctrl+O open filename File → OpenClear command window clc Edit → Clear Command WindowClear workspace clear Edit → Clear WorkspaceClose all open windows close all

Table 1.1: Example shortcuts, commands and menu options in MATLAB.

4

Page 9: Main

The first three of the examples in Table 1.1 can also be done by clicking the correct button asshown in Figure 1.4. Figure 1.4 shows the buttons (in ellipses) for opening a new m-file, openingan existing m-file and saving an m-file. The first two actions can be done from the main MATLABwindow or from the editor, but saving an m-file in this way can only be done from the editor.

Figure 1.4: Buttons for opening a new or existing m-file and saving

It is also possible to create customised buttons for your ownfrequently used commands (see Figure1.5); select the commands in the Command History window, right click and selectCreate Short-cut. Figure 1.6 shows the shortcut editor used to create a shortcut button called ‘Clean Up’, whichexecutes the commandsclear , close all andclc .

Figure 1.5: How to add shortcut button

5

Page 10: Main

Example Shortcut

Figure 1.6: Creating a shortcut

Figure 1.7: Undocking & redocking windows

6

Page 11: Main

1.6 Arranging the MATLAB Window

When opening MATLAB, the window may be arranged in different ways. The previous figuresshow that the Command Window is to the right, and to the left arethe Current Directory, CommandHistory and Workspace. Figure 1.7 shows an example where theCommand History has beenundocked. Ellipses show the buttons for re-docking the Command History and undocking theWorkspace.

These windows can also be moved within the MATLAB window by clicking on the titlebar andmoving it to a preferred location before releasing the mousebutton. An example of a differentarrangement is shown in Figure 1.8

Figure 1.8: Arranging the MATLAB window by moving titlebars

1.7 Summary

In this introduction we have learned:

• Where to access the new features and changes of the latest MATLAB release

• Shortcuts, commands and menu options for opening/saving files, clearing the command win-dow, clearing the workspace and closing windows

• How to create custom shortcuts

• How to arrange the MATLAB window

7

Page 12: Main

Chapter 2

Programming for Correctness

The aim of this unit is to provide an overview of the tools available in MATLAB R2010a fordebugging code and assessing code performance.

In this unit we describe methods for diagnosing warnings anderrors, explain how to use variousdebugging tools to verify code execution and to efficiently identify and correct problems in code,and introduce methods for assessing the execution time of code. All of the code examples relate tothe problem of solving the equation for a mass on a spring.

By the end of this unit you will have developed skills that willenable you to:

• Diagnose warnings and error messages

• Select and use appropriate tools for addressing problems incode

• Select and use appropriate tools for verifying code execution

• Assess the performance of code

Open2 Programming for Correctness.m for the exercises in this unit.

2.1 Handling Warnings & Errors

The code examples for this section involve reading in the parameters and initial conditions for amass-spring system. In2 Programming for Correctness.m the following lines of codethrow an error in the command window:

parameters file = fopen(‘mass spring parameters.txt’);

parameters = fscanf(parameters file,‘%g’);

8

Page 13: Main

fclose(parameters file);

disp(‘Parameters read ok’);

Errors terminate the execution of the code and commands following the error are not executed(hence ‘Parameters read ok’ does not appear in the command window).

A simple method of determining which line of code produced the error is to comment the codeone line at a time by placing the cursor at the start of the lineand using the Ctrl+R and Ctrl+Tcomment and uncomment shortcut keys.

2.1.1 Try-Catch Construct

As a form of damage limitation, we can place the lines of code above in a ‘try-catch construct’. Ifan error is likely to occur in the program (perhaps due to a filename change as in this example),then alternative lines of code can be executed instead.

try

parameters file = fopen(‘mass spring parameters.txt’);

parameters = fscanf(parameters file,‘%g’);

fclose(parameters file);

catch ME parameter file (This part is called an ‘MException Object’)

warning(‘PforC:parameters file’, ...

‘Unable to access file. Using default parameters.’);

disp([‘Original error message was: ’ ...

MEparameter file.message]);

parameters = [10; 0; 15];

end

The code above now thows a warning in the command window, but the code still executes in full.

The ‘warning’ function enables us to display a custom warning. Warning messages comprise amessage identifier and the actual message. Message identifiers usually provide information aboutthe source of the warning (e.g. project, program or company name) followed by a colon and thena short description or mnemonic of the warning itself, e.g.PforC:parameters file - ourcustom example andMATLAB:divideByZero - a message identifier that you may have comeacross in the past. The MathWorks have now removed this particular warning from current versionsof MATLAB.

The message part is displayed in the command window. To retrieve the last warning message and

9

Page 14: Main

message identifier, use

[warnmsg msgid] = lastwarn;

We can also suppress the display of warning messages with a given message identifer using

warning(‘off’, ‘PforC:parameters file’);

If you now execute the try-catch statement above, you will not see the custom warning in thecommand window. To turn the display of this warning message back on use

warning(‘on’, ‘PforC:parameters file’);

To query the state of a warning message use:

warning(‘query’, ‘PforC:parameters file’);

To turn all warnings off/on use

warning off all;

warning on all;

2.1.2 MException Object

The MException Object that we have named ‘MEparameterfile’ also contains information aboutthe error generated in the try part of the construct. If you double click this object in the workspaceyou will see that it contains identifier and message components. The message component wasdisplayed in the command window. Messages produced by the MException Object can often bedifficult to interpret, so it is useful to use custom warning messages where you can.

The throw method can be used with the MException object to issue the exception and terminateexecution of the program, as in the example below:

try

initial conditions file = fopen(‘initial conditions.txt’);

initial conditions = fscanf(initial conditions file,‘%g’);

fclose(initial conditions file);

catch ME initial conditions file

warning(‘PforC:initial conditions file’, ...

‘Unable to access initial conditions file.’);

throw(ME initial conditions file)

end

10

Page 15: Main

Other methods that can be used with the MException object includerethrow andthrowAsCaller . See ‘MException’ in the MATLAB Help documentation for further details.

Alternative ways of generating an error message include using theerror and assert com-mands, e.g.

filename = ‘mass spring initial conditions.txt’;

initial conditions file = fopen(filename);

assert(initial conditions file > 0, ...

‘Cannot open file %s’, filename);

Remember that, unlike warnings, errors terminate the execution of the code. To ensure no filesare left open accidentally, usefopen(‘all’) to return a vector of all the file identifiers of openfiles. Then usefclose(‘all’) to close them:

if fopen(‘all’)

fclose(‘all’);

end

2.1.3 Validation Tools

To check that the files contained appropriate numeric values, we can use the following validationmethod:

if ∼isa(parameters,‘double’) || isempty(parameters)

error(‘PforC:parameters file’, ...

‘The file does not contain the right data type.’);

end

if ∼isa(initial conditions,‘double’) || isempty(initial conditions)

ME = MException(‘PforC:initial conditions file’, ...

‘The file does not contain the right data type.’);

throw(ME);

end

isa is a useful method for checking whether the input variable isof a given type or ‘class’.Classes include:logical , char , numeric , integer , float , single , double , cell andstruct . Functions for checking the class of variables include:iscell , ischar , isfloat ,isinteger , isnumeric etc. Search for ‘is*’ in the Help Documentation for a complete list.

To confirm the class of a variable, use the ‘class’ command:

class(parameters)

11

Page 16: Main

class(initial conditions)

We can investigate the data further by checking that at least3 parameters were read in. In theexample below a warning is thrown if there were more than 3 parameters and zeros are inserted ifthere were less than 3.

if numel(parameters) > 3

parameters = parameters(1:3);

warning(’PforC:parameters long’, ...

’There are more than 3 parameter values in parameters file.

Only the first 3 will be used.’);

elseif numel(parameters) < 3

parameters(numel(parameters)+1:3) =

zeros(3-numel(parameters),1);

warning(’PforC:parameters short’, ...

’There are fewer than 3 parameter values in parameters file.

Zeros will be used for the rest.’);

end

In the example above we usenumel to validate the number of elements in the arrayparameters .Another validation tool that we can use to check the validityof arrays isvalidateattributes .This function requires an input array, a class specificationand an attributes specification.

In the example below we check that there are exactly 2 initialconditions, that they are of classdouble , and that they are a column vector (the numbers should be readin as a column vectorregardless of the format of the text file).

validateattributes(initial conditions,‘double’,‘size’,[2,1]);

See ‘validateattributes’ in the MATLAB Help Documentationfor a list of class and attribute argu-ments.

2.2 Debugging Tools in MATLAB

In this section we use analytical and numerical solutions for the equation of motion for a masson a spring as a code example. Note that the code in this file is indented to help readability. Toautomatically indent your code, select the lines of code that you want to indent and use the Ctrl+Ikeyboard shortcut.

12

Page 17: Main

2.2.1 M-Lint Code Analyzer

m = parameters(1); mass (kg)c = parameters(2); damping coefficientk = parameters(3) spring stiffness (N/m)

u 0 = initial conditions(1); initial displacementu d 0 = initial conditions(2); initial velocity

In the code above a semicolon is missing. Go toFile → Preferences → Code Analyzer and ver-ify that the option for ‘Enable integrated warning and errormessages’ is checked (see Figure 2.1).In earlier versions of MATLAB ‘Code Analyzer Preferences’ was named ‘M-Lint Preferences’.M-Lint is a code checking tool. It uses a green/orange/red square indicator in the top-right cornerof the editor to indicate errors, warnings and opportunities to improve code (see Figure 2.2):

green: no errors, warnings or opportunites to improve codeorange: warnings or opportunites to improve codered: errors

Figure 2.1: Setting M-Lint preferences

If you click on the square indicator, it will take you to the next M-Lint message. Each M-Lintmessage is also represented by a coloured horizontal bar on the right side of the editor and if youhover over this with you mouse it will display the M-Lint message (see Figure 2.2). As soon asyou address the issue, the M-Lint indicator automatically updates itself.

13

Page 18: Main

Figure 2.2: M-Lint indicators and messages

You can also use the M-Lint function in the command window to display M-Lint information abouta file e.g.

mlint(‘Part2 Programming for Correctness’)

Or, in the editor, you can selectTools → M-Lint → Show M-Lint Report.

2.2.2 Function Handles

A quick detour into function handles is neccesary when usingthe MATLAB ordinary differentialequation solverode45 . In this code example we useode45 as follows:

fh = @(t,y) odefn(t,y,m,c,k);

[T,Y] = ode45(fh,[0 end time],initial conditions);

whereodefn is an m-file with the differential equations to be solved. Theode45 solver requiresthe following as input parameters:

1. a ‘function handle’ that calls a function which defines thedifferential equations to be solved

2. a vector specifying the interval of integration (e.g. 0 to50 seconds)

3. a vector specifying the initial conditions (displacement and velocity)

We are already familiar with the idea that a variable name canbe used as a substitute for a variable,e.g.var name = 5; A function handle can be used similarly as a substitute for a function. Forexample:

14

Page 19: Main

fh sin = @sin; the function handle is created using the@symboly = fh sin(pi/2);

Function handles enable a function to be passed to another function. For example:

pi approx = fzero(fh sin, 3);

where functionfzero finds the zero(s) of thesin function nearsin(3) . The following alsoproduces the same result:

pi approx = fzero(@sin, 3);

You can create handles to functions that are defined in m-filessimply by using the@symbol andthe function name as above. It is also possible to specify thefunction at the same time as creatingthe function handle. This type of function handle is called an ‘anonymous function handle’ as thereis no m-file for the function. For example:

fh cube = @(x) x.ˆ3; fplot(fh cube, [-2 2]);

Here the function,x.ˆ3 , is defined at the same time as the handle using the dummy inputvariable(x) . The fplot command accepts function handles as an input and we can use this to evaluate thefunction if the formy = f(x) over a range of limits (in this case from -2 to +2).

We will explore function types in more detail in Unit 3: Structuring Code and we will be usingfunction handles in all the other sections of the course.

2.2.3 Breakpoints & Stepping Through Code

The functionread file opens a file containing other values formand assigns them, as well asthe original value ofm, to ms. This timeOnCleanup is used to ensure that the file is not left openif an error occurs. When the following lines of code are executed, an error occurs:

ms = read file(m);

number of ms = length(ms);

There are several ways of using the same debugging tools in MATLAB to find errors in code. Onemethod is to use the breakpoint and step buttons shown in Figure 2.3 to set a breakpoint, executethe lines of code up to the breakpoint and then from the breakpoint, step through the code line byline, observing the values of variables and checking the program flow.

Breakpoints can also be set/cleared by clicking on the dash next to the line number of the codewhere you want the breakpoint. When stepping through code, the values of variables can beobserved by hovering the mouse pointer over the variable name. Note that breakpoints are red

15

Page 20: Main

Figure 2.3: Set/clear breakpoint, Step, Step in, Step out, Continue and Exit debug mode buttons

Figure 2.4: Setting conditional breakpoints

when the script has been saved and grey when the script has been edited and is unsaved.

It is also possible to stop the execution of code and locate the error by navigating toDebug →

Stop if Errors/Warnings... and clicking onAlways stop if error (dbstop if error).

Breakpoints can also be conditional. To insert a conditionalbreakpoint, create a breakpoint usingthe set breakpoint button or by clicking on the dash next to the line of code, and then right click onthe breakpoint. SelectSet/Modify Condition... from the menu and enter the condition in the box(see Figure 2.4). The breakpoint will then turn yellow to indicate that it is a conditional breakpoint.

The debug commands that we have learned can also be executed using the commandline. Simplytypedbstep to step through the code line by line,dbstep in to step into a function,dbstep

out to step out of a function anddbquit to quit debug mode.dbclear all can be used toclear all breakpoints. For a few handy shortcuts, see Table 2.1.

Another useful short cut to remember is Ctrl+C for stopping code execution. For example, if youwere to typepause(inf) then Ctrl+C will abort the process and bring you back to the commandprompt!

16

Page 21: Main

Operation Shortcut MenuComment code Ctrl+R Text → CommentUncomment code Ctrl+T Text → UncommentIndent code Ctrl+I Text → Smart IndentEvaluate selected codeF9 Text → Evalaute SelectionStep through code F10 Debug → StepStep in F11 Debug → Step InStep out Shift+F11 Debug → Step OutSave file and run F5 Debug → Save File and Run

Table 2.1: Useful debugging shortcuts in the editor.

2.2.4 TODO & FIXME Comments

It is common for programmers to leave ‘TODO’, ‘FIXME’ and ‘NOTE’ comments in their code.MATLAB provides a TODO/FIXME report tool that enables you toquickly locate all of the m-files in a folder with these comments in them. Navigate toDesktop → Current Folder (if thisis not already open) and click on the cog-like ‘Actions’ icon(see Figure 2.6). SelectReports →

TODO/FIXME Report. This report lists all of the m-files in the current directoryand the linenumbers in each file where these comments occur (see Figure 2.5). Click on the line number for acomment to go to that line of code.

Figure 2.5: TODO/FIXME report

Other reports that can be accessed in this way include:

Code Analyzer Report - Display M-Lint Code Analyzer reportTODO/FIXME Report - List all TODO and FIXME commentsFile Dependency Report - Show file dependency in the current directory

17

Page 22: Main

Figure 2.6: MATLAB report tools

2.3 Assessing Code Performance

2.3.1 TicToc

The commandstic andtoc can be used to measure the time that lines of code take to execute.The time measured bytic andtoc is known as ‘clock time’ and is the same as if you measuredthe time elapsed using a stop watch.

The output oftic can optionally be assigned to a variable, enabling more thanone timer to beused at the same time. For example,

timer1 = tic;

...

timer2 = tic;

...

...

time2 = toc(timer2);

...

time1 = toc(timer1) ;

18

Page 23: Main

2.3.2 Profiler

The MATLAB Profiler is also a really useful tool for comparinghow long different parts of a scripttake to run and identifying lines of code that could be made toexecute more efficiently.

Open the profiler by navigating toTools → Open profiler or by using the Profiler icon in the toolbar. To profile an m-file, type the name of the m-file where it says ‘Run this code’ (see Figure 2.7).Double click on the m-file name in the ‘Function Name’ column to see the lines of code wheremost time was spent.

In order to only view the speed of a specific section of code youcan also insert the commandsprofile on , profile off andprofile viewer in your code.

Figure 2.7: MATLAB Profiler

19

Page 24: Main

2.4 Summary

In this unit we have learned about:

• Handling warnings and errors using the try-catch construct, the MException object and var-ious validation tools.

• Debugging tools including the M-Lint Code Analyzer, Breakpoints, stepping through codeand locating TODO/FIXME comments.

• Assessing code performance using tic toc and Profiler.

For more information on any of the topics covered, try MATLAB’s ‘Product Help’ or visithttp://www.mathworks.com/products/matlab/

2.5 Test Yourself

1. True or False: Warnings terminate the execution of code?

2. Which of the following is not used as a validation tool?(A) class

(B) numel

(C) tic /toc

(D) validateattributes

3. Which of the following M-Lint indicator descriptions is correct(A) green = opportunites to improve code(B) green = no errors, warnings or opportunites to improve code(C) orange = no warnings(D) red = warnings

4. Which of the following breakpoint descriptions is correct?(A) red = breakpoint in unsaved file(B) yellow = conditional breakpoint(C) yellow = unconditional breakpoint(D) grey = breakpoint in saved file

5. True or False: Profiler displays the lines of code that takelongest to execute?

20

Page 25: Main

Chapter 3

Structuring Code

The aim of this unit is to provide an overview of the methods tomodularize code into readableand maintainable functions. As with most advanced programming languages, MATLAB allowsfor several implementation options when writing functions. There is often a tradeoff betweenreadability and code performance that should be carefully weighed.

By the end of this unit you will have developed skills that willenable you to:

• Describe the main features of anonymous, nested, private, and sub functions

• Select and use appropriate function types

• Apply knowledge of precedence rules for functions and variables that have the same name

Open3 Structuring Code.m for the exercises in this unit.

3.1 Private Functions

In the code files for this unit there are two functions calledmyPolyFun - one directly in the3 Structuring Code directory and one in a folder calledprivate within the3 Structuring Code directory (see Figure 3.1). The local function returnsx.ˆ2 , whereasthe private function returnsx.ˆ3 .

If the current directory is the parent directory (3 Structuring Code) and myPolyFun iscalled from the command line, the local function executes.

If the current directory is theprivate directory within the3 Structuring Code directoryandmyPolyFun is called from the command line, the private function executes.

21

Page 26: Main

3_Structuring_Code (myPolyFun.m)

private (myPolyFun.m)

Figure 3.1: Directory Structure for Private Functions

If the current directory is the parent directory (3 Structuring Code) and myPolyFun iscalled from a function in the parent or private directory, the private function executes.

If myPolyFun is called from a function in the parent or private directory,with a local variable (inthis case,x ) that already exists in the Workspace, the local function executes.

Thus the ‘visibility’ of private functions is limited. Private functions can only be called by func-tions in the same directory or parent folder and cannot be accessed from the command line, unlessyou are currently in the private directory. Any function canbe made a private function by placingit within a subfolder calledprivate . This private directory cannot be added to the MATLABsearch path.

Local variables take precedence over private functions, and private functions take precedence overfunctions in the current directory. We will learn more aboutprecedence rules in section 3.6.

To check for multiple instances of a function, use thewhich function, e.g.

which myPolyFun -all

If you omit the-all qualifier, MATLAB returns the pathname of the first function that it finds.

3.2 Function Handles

We have already come across function handles in Chapter 2, where we used a function handle asan input to theode45 differential equation solver. Function handles can be useful for:

• increasing the visibility of functions

• changing the interface of a function

• minimizing the number of function files in a given directory

• improving performance in repeated operations

A quick recap: the function handle is created using the@symbol and, in this example, is stored inthe variablefh sin :

22

Page 27: Main

fh sin = @sin;

y = fh sin(pi/2);

The function handle contains the name of the function, the function type, the location of the func-tion and any additional data required to execute the function.

To access the information stored in a function handle, use the functions command, e.g.

functions(fh sin)

which, in this case, returns:

function: ‘sin’

type: ‘simple’

file: ‘’

3.3 Anonymous Functions

We also came across anonymous functions in Chapter 2. If the function is defined at the same timethat the function handle is created, it is known as an ‘anonymous function’ (there is no m-file forthe function). Anonymous functions are defined in a single line of code.

The following line defines a new function handleUnwrapAngleDeg to unwrap and convert aphase varying in radians into degrees.

UnwrapAngleDeg = @(x) unwrap(angle(x)) * 180/pi;

Again, the function handle is created using the@symbol. This is followed by a dummy inputvariable,x , and then the function definition.

If you check the attributes of an anonymous function handle using thefunctions command, thefunction type will confirm that the function handle is a handle to an anonymous function. E.g.

attributes UAD = functions(UnwrapAngleDeg)

returns

function: ‘@(x)unwrap(angle(x)) * 180/pi’

type: ‘anonymous’

file: ‘’

workspace: [1x1 struct]

23

Page 28: Main

Note: If any workspace variables have been defined previously, they will persist in an anonymousfunction until the function is redefined. For example,

var = 0;

AddOne = @(x) x+var+1;

AddOne(5)

returns the answer 6. However the following lines of code also return the answer 6 as the originaldefinition of the variablevar persists in the anonymous function:

var = 2;

AddOne(5)

3.4 Subfunctions

Subfunctions can also reduce the clutter and ambiguity of function files in a given directory, espe-cially for long programs, or programs with graphical user interfaces (GUIs).

A simple example to show how subfunctions are implemented isgiven below:

x = -10:.1:10;

y = subfunctions(x,2);

plot(x,y)

In subfunctions.m :

function out = subfunctions(in,type) % PRIMARY FUNCTION

if type == 1

out = subfun1(in);

elseif type == 2

out = subfun2(in);

elseif type == 3

out = subfun3(in);

end

end

function y = subfun1(x) % SUBFUNCTION 1

y = x.ˆ1;

end

function y = subfun2(x) % SUBFUNCTION 2

24

Page 29: Main

y = x.ˆ2;

end

function y = subfun3(x) % SUBFUNCTION 3

y = x.ˆ3;

end

Only the first (or ‘primary’) function in an m-file containingsubfunctions can be called fromoutside the m-file. The remaining functions are called ‘subfunctions’.

Note: In the example above, each of the subfunctions is terminated with anend command. Thisis optional when the m-file only contains subfunctions and should either be used for all of thesubfunctions or none of them. If the m-file contains nested functions, theend command shouldbe used to terminate all function types in the file.

3.5 Nested Functions

Nested functions can be applied in a manner similar to subfunctions, but additionally allow theworkspace variables to be shared between functions in the m-file. Similarly, large blocks of datacan be shared within a workspace, thus saving on memory usage. This type of function is alsoparticularly useful for coding GUIs.

A simple example to show how nested functions are implemented is given below.

Nested functions can be called by functions from the level above (e.g. in the example below, nestedfunction 1.2 can be called by nested function 1), by other functions at the same level (e.g. nestedfunction 1.1 could call nested function 1.2) and by nested functions at lower levels (e.g. nestedfunction 1 could be called by nested function 1.2).

Unlike subfunctions it is important to terminate each nested function with theend command.

25

Page 30: Main

random data = rand(1000);

output = nestedfunctions(random data);

In nestedfunctions.m:

[a,b] = size(input);

if numel(input) <1e6

out1 = nFun1(input);

output = nFun2(out1);

else

output = nFun2(input);

end

output = nFun3(input, out2);

% NESTED FUNCTION 1

function out = nFun1(in)

if a==b

out = nnFun1 1(in);

else

out = nnFun1 2(in);

end

% NESTED FUNCTION 1.1

function out = nnFun1 1(in)

out = repmat(in,ceil(1000/a),ceil(1000/a));

end

% NESTED FUNCTION 1.2

function out = nnFun1 2(in)

out = repmat(in,ceil(1000/a),ceil(1000/b));

end

end

% NESTED FUNCTION 2

function out = nFun2(in)

out = (in <0.2);

end

end

26

Page 31: Main

3.6 Precedence Rules

If variables, m-files and functions share the same name, MATLAB operates a set of ‘local to global’precedence rules in order to determine how to proceed. The following list indicates the order ofprecedence:

• Local variable or nested function*

• Subfunction

• Private function

• Class constructor (not covered on this course)

• Overloaded method (not covered on this course)

• Function in current directory

• Function on MATLAB path

*If a local variable and a nested function have the same name,an error occurs.

3.7 Summary

In this unit we have learned about:

• Differences between private, sub-, nested and anonymous functions.

• Using a function handle as a substitute for a function.

• Precedence rules for functions and variables with the same name.

For more information on any of the topics covered, try MATLAB’s ‘Product Help’ or visithttp://www.mathworks.com/products/matlab/

27

Page 32: Main

3.8 Test Yourself

1. True or False: Private functions can be added to the MATLABsearch path?

2. True or False: Subfunctions can be accessed from the command line?

3. Which of the following function types is not defined in an m-file?(A) private(B) sub(C) nested(D) anonymous

4. Which of the following takes most precedence?(A) Subfunction(B) Nested function(C) Private function(D) Function in current directory

28

Page 33: Main

Chapter 4

Structuring Data

The aim of this unit is to introduce the cell array and structure array data types as well as the useof the multidimensional numerical array as the preferred means of manipulating and processingheterogeneous and/or multidimensional data.

In this unit we use an existing publicly available database of Head Related Impulse Response(HRIR) measurements provided by the Center for Image Processing and Integrated Computing,University of California, Davis (available online from http://interface.cipic.ucdavis.eduCIL html/CIL HRTF database.htm). We will organise the data in this database into a single data containerand we will show how the data can be accessed from such a container for further processing.

The CIPIC database contains the Head-Related Impulse Responses (HRIRs) of 45 subjects, in-cluding two data sets obtained with the KEMAR mannequin (Algazi et al. 2001). It also containsinformation about the age, sex and anthropometric data for each of the subjects (including weightand 27 dimensions describing the head, torso and pinna size and position). The data contained inthe CIPIC database are also multidimensional as the HRIR is a function of time, of the individualsubject, of the azimuth and elevation of the sound source andthe left or right ear.

The teaching objective of this unit is to describe how the cell, structure and multidimensional arraydata types can be used for organising the CIPIC data into a suitable data container that allowsaccessing them for further processing and analysis in an efficient way. By the end of this unit youwill have developed skills that will enable you to:

• Write efficient code for importing data into appropriate datacontainers.

• Use appropriate techniques for indexing data containers.

• Explain the advantages and disadvantages of data containertypes in terms of memory re-quirements, efficiency and accessibility.

Open4 Structuring Data.m for the exercises in this unit.

29

Page 34: Main

4.1 Cell Arrays

Cell arrays are similar to standard matrices in that they havedimensions in the same way, but theyare more versatile containers as they can contain anything as elements: numbers, matrices, strings,others cells, cells of other cells, structures, etc.

To create a cell array, use thecell command:

simple cell=cell(2,2);

To assign values to each of the four elements we need to index the cell contents using curly brackets{}. For example:

simple cell {1,1 }=5;

simple cell {1,2 }=‘Matlab’;

simple cell {2,1 }=[1 2 4];

simple cell {2,2 }={7;8;9 };

To view the contents of the cell array in the command window, simply type the name of the cellarray,

simple cell

which returns

simple cell =

[ 5] ‘Matlab’

[1x3 double] {3x1 cell }.

4.1.1 Importing Data From a Text File

The fileanthro1.txt lists the information about the age and weight of the 45 subjects and theirunique subjectID number (see Figure 4.1). It has three headers and three columns of numericaldata. In this section we read information from the file into a cell array. Check that you have a copyof anthro1.txt in your current folder.

To open a text file in MATLAB we use thefopen command, which takes the form

fid = fopen(filename, permission) ;

Wherefid contains the file identifier. The permission options include‘r’ for ‘read’, ‘w’ for‘write’, ‘a’ for ‘append’. For this example, we openanthro1.txt with read access only:

30

Page 35: Main

Figure 4.1: Format of the data in anthro1.txt

fid = fopen(‘anthro1.txt’,‘r’);

We can then read the numerical data in the three columns and store this data in a cell array usingthetextscan command:

anthro basic = textscan(fid, ‘%n %n %n’, ‘HeaderLines’,1);

The textscan command requires the file identifier (fid ) and information about the formatof the data (in this case, three columns of floating point numbers specified by%n). Here theparameter‘HeaderLines’ is also used with a value of 1 to ensure that the ‘SubjectID’, ‘Age’and ‘Weight[Kg]’ headers are skipped.

Other commands that we can use in MATLAB for reading files include textread , fscanf ,fread and fileread . For more information on these and other low-level file input/outputfunctions, go to:

Help → Product Help → MATLAB → Functions → Data Import and Export →Low-Level File I/O

We can then read the headers into a cell array. The functiontextscan starts reading from thepoint in the file where it was left from its last call. So we haveto set the reading point back to thebeginning of the file using thefrewind command:

frewind(fid)

headers = textscan(fid, ‘%s’, 3);

fclose(fid);

clear fid;

31

Page 36: Main

Note that in thetextscan command above we follow the format parameter with the value 3,which instructs thetextscan command to read 3 lots of string data (specified by‘%s’ ).

We now have two cells:anthro basic (containing the numeric data) andheaders (containingthe header strings).anthro basic is a 1x3 cell, each element of which contains one of the threecolumn vectors with the corresponding numerical data.headers is a 1x1 cell containing a 3x1cell containing strings. Figure 4.2 is a schematic representation of how the data have been importedfrom the text file to these two cells. This result obtained from textscan is probably not the bestway to arrange the data in Matlab variables. In the followingwe will see how we can rearrange thedata more usefully.

anthro1.txt headers & anthro_basic (Matlab cells)

SubjectID Age Weight[Kg]

3 30 90.000

8 NaN NaN 9 NaN NaN

10 35 65.772

11 NaN NaN

12 NaN NaN 15 NaN NaN

17 NaN NaN

18 25 39.463 19 NaN NaN

20 39 79.380

21 NaN NaN

27 21 68.040 28 63 77.112

33 21 88.452

40 18 49.896

44 42 83.462 48 22 56.700

50 20 117.936

51 22 72.576

58 22 68.040 59 19 72.576

60 21 50.000 61 22 61.236

65 30 92.988 119 23 81.648

124 19 77.112

126 21 48.535 127 20 68.040

131 20 70.308

133 30 68.040

134 23 80.000 135 19 70.308

137 20 72.576

147 34 70.000

148 26 60.000 152 21 65.772

153 25 68.000

154 26 62.000

155 22 56.700 156 22 56.246

158 22 81.648

162 26 86.184 163 23 73.937

165 NaN NaN

‘ ‘ , ‘ ‘ , ‘ ‘

Figure 4.2: Schematic of the import from the text file to the two cell arrays.

4.1.2 Indexing Cell Arrays

Because a cell array can contain different types of data stored in various array sizes, cell arrayindexing is a little more complex than indexing numeric or character arrays.

There are two methods of accessing data in a cell: cell indexing and content indexing. The firstreturns a cell with the contents of the indexed range as elements. It is chosen using the parenthesesoperator (). The second returns the contents themselves (rather than the contents in a cell). It ischosen using the curly brackets operator{}.

32

Page 37: Main

For example,

anthro basic(1)

returns

ans =

[45x1 double]

whereas

anthro basic {1}

returns the column vector stored within the first cell:

ans =

3

8

9

10

11 etc.

We can also index a cell inside a cell with consecutive context indexing (using{}{}) or the datainside the matrix inside a cell with consecutive cell and content indexing.

For example, if we want to retrieve the weights of the 10th-13th subjects from theanthro basic

cell we can write

anthro basic {3}(10:13) .

As another example, if we want to retrieve the string ‘Subject’ from the headers cell (i.e. thefirst 7 characters of the contents of the first cell within theheaders cell) we use the command

headers {1}{1,1 }(1:7) .

Now that we have seen how to access the data, we can also see howto rearrange it in more suit-able ways. We can concatenate the data in one numerical arrayto facilitate processing (since allelements are numeric, we do not need a cell to store them). We can do this with

anthro num = [anthro basic {1} anthro basic {2} anthro basic {3}];

Note that cell arrays impose a memory space overhead for their creation compared to numericarrays. This overhead is proportional to the number of elements of the cell. Compare the byte

33

Page 38: Main

size of theanthro basic and theanthro num variables in the Workspace window (keepingin mind that they both hold the same data).

If the same data are arranged in a 45x3 cell with

anthro cell = num2cell(anthro num);

the memory space requirement increases even further (see Figure 4.3).

Figure 4.3: Cell memory overhead.

Finally, what if we want all the data (header strings and numerical data) in one cell? This can bedone by creating a new cell which holds as elements the two cells (anthro numandheaders )that we obtained fromtextscan .

onecell 1 = {anthro num headers };

This works but it is unnecessarily nested (a cell containingcells that, in turn, contain strings andcolumn matrices with numerical data). A more natural choicewould be to concatenate everythingto a 46x3 cell array, the first row holding the headers and the 2:46 rows holding the numericinformation.

onecell = [headers {1}’;mat2cell(anthro num,ones(1,45),ones(1,3))];

The concatenation is effected by use of the square brackets []. Note the use of content index-ing (headers {1}) in order to obtain the 3 strings contained in the 3x1 cell inside the 1x1 cellheaders . Note also the use of themat2cell command for converting the 45x3 numerical arrayanthro numto a 45x3 cell. For more details on the use ofmat2cell see the MATLAB ProductHelp for:

MATLAB → Functions → Programming and Data Types → Data Types → Cell Arrays →

mat2cell

34

Page 39: Main

Returning to theanthro basic cell, suppose we wanted to plot the age variation against theSubjectID. We only have age information for some of the subjects (see Figure 4.1) so it would bepreferable to only include these cases in the plot (i.e. skiptheNaNelements). Appropriate use ofcell indexing allows us to do this in a vectorised way (i.e. avoiding loops):

temp1 = anthro basic {2}(˜isnan(anthro basic {2}));

figure;plot(temp1,‘ * -’)

The first line above retrieves theAge data for the indices that do not containNaNelements andputs them into the vectortemp1 . The second line produces the plot in a new figure window.

In order to pick the SubjectId information for labelling thex-axis, we can use cell indexing againto store the SubjectId data in the vectortemp2 . Again, note the use of themat2cell commandwhich is used to convert the numerical values to a cell of appropriate dimensions containing strings.

temp2 = anthro basic {1}(˜isnan(anthro basic {2}));

temp3 = num2str(temp2);

set(gca,’XTick’,[1:length(temp1)])

set(gca,’XTickLabel’,mat2cell(num2str(temp2),...

ones(1,size(temp3,1)),size(temp3,2)))

xlabel(’SubjectID’);ylabel(’Age’)

The result is shown in Figure 4.4 (you may have to resize the figure to see the ticklabels).

3 10 18 20 27 28 33 40 44 48 50 51 58 59 60 61 65 11912412612713113313413513714714815215315415515615816216315

20

25

30

35

40

45

50

55

60

65

SubjectID

Age

Figure 4.4: Plot of age variation against SubjectID.

35

Page 40: Main

4.2 Structure Arrays

4.2.1 Creation and Indexing of Structure Arrays

The previous example showed how cells can contain literallyanything from the MATLAB world,and it exemplified (just some of) the existing tools for accessing and indexing the contents of cells.

However, cells are not necessarily user friendly. The main reason is that the cell container (versatileas it may be) does not facilitate the structuring of information. Another option is the stucture arraydata type.

In the following we will collect all the information of the CIPIC database in a structure array. Thisstructure array will have a dimensionality of 45x1 (copyingthe number of subjects in the database)and it will have 5 fields, one for each of the subjects’ id, age,sex, left and right ear HRIRs. Thisarrangement of the data in the structure array is depicted schematically in Figure 4.5.

cipic(n).SubjectID

.Age

.Sex

.HRIR_Left

.HRIR_Right

cipic (45x1 Matlab structure arrary)

Data for the identifier number, age, sex and Left and Right ear Head Related Impulse Responses for 45 subjects

Stored in the 3 (45x1) matrices ‘age’, ‘id’ (numeric) and ‘sex’ (string)

And

In the 90 (25x50x200) matrices ‘hrir_l and ‘hrir_r’ of the workspace .mat file hrir_final.mat inside the folders subject_xxx

Figure 4.5: Schematic of the arrangement of the CIPIC data in aMATLAB structure array.

You may want to clear the workspace. You need to have loadedanthro simple.mat on yourworkspace (this contains three variables with the 45 subjects’ id, age and sex data).

We first need to create a structure array with three fields. Thestruct command is used to createa structure array and define its fields and their values. In this instance we define only the threefields holding the id, age and sex information (we describe the creation of the remaining two fieldsholding the HRIR in Section 4.3). For structure arrays of dimensionality m-by-n, the values haveto be given as m x n cell arrays.

36

Page 41: Main

cipic = struct(’SubjectId’,num2cell(id),...

’Age’,num2cell(age),’Sex’,num2cell(sex));

Again, compare the combined byte size of the 3 variablesid , age andsex with that of thecipic

structure array. Similar to cell arrays, structure arrays impose a memory space overhead for theirimplementation.

As with cells, structure arrays also have a unique syntax forindexing and organising data. Thesyntax for accessing an element is of the formstruct(n,m,...).fieldname where thesubscriptsn, m, etc. determine the element of the array andfieldname the field. In the specificexample considered here, the array is of dimensionality 45x1 so only one index is needed. Hence

cipic(30).Age

will return

ans =

20

and

cipic(30).SubjectId

will return

ans =

131 .

You can readily verify from Figure 4.4 that this is the expected result.

Again, as with cells, we can concatenate specific data from selected fields in cells or numeri-cal arrays using e.g.{cipic.Sex }, [cipic.SubjectId] , [cipic(1:10).Age] . See4 Structuring Data.m for code examples and exercises.

37

Page 42: Main

4.2.2 Dynamic Fieldnames

In this section we will add anthropometric data to the above structure array. We use this exampleto introduce the concepts of:

• Vectorisation in cell arrays using anonymous functions.

• Dynamic fieldnames in structure arrays.

Open the fileadvanced2.m for the exercises in this section.

The distribution of the CIPIC database that we are using here as an example includes an ex-tensive set of anthropometric data for the subjects of the database, such as pinna dimensions,pinna angles relative to the head, body dimensions and pinnaposition, and weight. These arestored in the variablesD, theta , X and WeightKilograms included in the MATLAB fileanthro extra.mat which you can find in the course material. These variables arenumeri-cal matrices, each having 45 rows and varying numbers of columns depending on the number ofanthropometric measurements describing the body and pinnadimensions etc. Details about theseanthropometric measurement data can be found in the fileanthropometry.pdf which you canalso find in the course materials.

In the example considered here we add two more fields, namedSomatometry andPinna , toour structure array. The fieldSomatometry is a scalar structure having 18 fields, one for eachof the 17 body dimension measurements originally in the 45x17 matrix X and one for the bodyweight originally in the 45x1 vectorWeightKilograms . Each of these 18 fields will hold ascalar for the corresponding element of somatometric data.The fieldPinna is a scalar structurehaving 10 fields, one for each of the 8 pinna dimensions originally in the 45x16 matrixD (whichhas 8 columns for the left ear and 8 for the right ear) and one for each of the 2 pinna angles relativeto the head, originally in the 45x4 matrixtheta (which has 2 columns for the left ear and 2 forthe right ear). Each of these 10 fields will contain a 1x2 vector holding the left and right ear valuesfor the corresponding element of pinna-related data.

As will become apparent, by arranging our data in such a way inthe structure array we can use thefieldnames as descriptors of the corresponding elements of data and avoid the confusing variablenamesD, X, etc. and the lack of information regarding which of their columns holds which elementof data.

We also need to create the structure array fieldnames. We can do this by creating a cell with thedescriptions as shown below:

anthro params = {

’x1’, ’head width’;

’x2’, ’head height’;

38

Page 43: Main

’x3’, ’head depth’;

’x4’, ’pinna offset down’;

’x5’, ’pinna offset back’;

’x6’, ’neck width’;

’x7’, ’neck height’;

’x8’, ’neck depth’;

’x9’, ’torso top width’;

’x10’, ’torso top height’;

’x11’, ’torso top depth’;

’x12’, ’shoulder width’;

’x13’, ’head offset forward’;

’x14’, ’height’;

’x15’, ’seated height’;

’x16’, ’head circumference’;

’x17’, ’shoulder circumference’;

’d1’, ’cavum concha height’;

’d2’, ’cymba concha height’;

’d3’, ’cavum concha width’;

’d4’, ’fossa height’;

’d5’, ’pinna height’;

’d6’, ’pinna width’;

’d7’, ’intertragal incisure width’;

’d8’, ’cavum concha depth’;

’theta1’, ’pinna rotation angle’;

’theta2’, ’pinna flare angle’;

};

Ideally we want to use these descriptions (which were mark-copied from the CIPIC documentation)as field names. However, fieldnames cannot contain blanks (’ ’ ), so we need to replace’ ’ with,say,’ ’ . We could achieve this using nested for-loops, but this can be avoided by making use ofthe cellfun command for a vectorised operation in cells (similar thingscan be done with thestructfun command in scalar structures).

anthro params=cellfun(@(x) strrep(x,’ ’,’ ’),anthro params,...

’UniformOutput’, false);

With cellfun we apply the operation described by the anonymous function defined in the first inputargument as@(x) strrep(x,’ ’,’ ’) to the cellanthro params specified in the secondinput argument. More details about the use of anonymous functions and function handles aregiven in Unit 3: Structuring Code. The parameter’UniformOutput’ , which is set tofalse

(third and fourth input arguments) specifies whether the results of the operation applied by thefunction of the first argument are such that they can be concatenated in an array without the needfor encapsulation in a cell array. In our example, this is notthe case, hence the valuefalse . Lookup the commandcellfun in the MATLAB help for more information,

39

Page 44: Main

Now we can create the new fieldsSomatometry andPinna which in turn are structures. We canuse dynamic field names drawn from theanthro params cell instead of typing the fieldnamesindividually.

Note: for the exercises inadvanced2.m , the cipic structure is copied and given the namecipic all .

for n = 1:45

for m = 1:17

cipic all(n).Somatometry.([anthro params {m,1} ...

’ ’ anthro params {m,2}]) = X(n,m);

end

cipic all(n).Somatometry.Weight=WeightKilograms(n);

for m = 1:8

cipic all(n).Pinna.([anthro params {m+17,1 } ...

’ ’ anthro params {m+17,2 }]) = D(n,[m m+8]);

end

for m = 9:10

cipic all(n).Pinna.([anthro params {m+17,1 } ...

’ ’ anthro params {m+17,2 }]) = theta(n,[m-8 m-8+2]);

end

end

By enclosing in brackets “() ” the expressions for the fieldnames (i.e. those following a dot “. ”in the structure syntax) we specify the fieldname as the string to which the expression resolves,rather than explicitly specifying the string. In this way wecan pass the elements of the cell arrayanthro params as the fieldnames of the structure.

4.3 Multidimensional Arrays

To conclude this part of the course, we import the HRIR data from the CIPIC database into thecipic structure. In the original CIPIC distribution, the HRIRs are given as two 3D multidi-mensional arrays for each subject (one for the left ear and one for the right ear HRIRs) with thefirst dimension subscript corresponding to the azimuth of the sound source, the second dimensionsubscript to its elevation and the third dimension subscript to the sampled time index of the HRIR.

Creating and indexing multidimensional arrays is a straightforward extension of the standard MAT-LAB notation with additional subscripts used for indexing,e.g.array(dim1,dim2,dim3,...) .However, not all operations defined for 2-dimensional arrays are valid for arrays of higher dimen-sion.

The CIPIC HRIR data are stored in the filehrir final.mat inside the

40

Page 45: Main

standard hrir database folder included in the course material (if moved elsewhere youneed to specify thedata path variable accordingly). This folder contains subfolders named assubject XXX(whereXXX is the subject ID). Each of these subfolders contains the data for thecorresponding subject.

The following piece of code goes through these subfolders one-by-one, loads the data and inputsthem in the structure array:

data path = ’CIPIC hrtf database \standard hrir database \’;

for n = 1:45

temp = load([data path ’subject ’ ...

num2str(cipic(n).SubjectId,’%03.0f’) ’ \hrir final.mat’]);

cipic(n).HRIR Left = temp.hrir l;

cipic(n).HRIR Right = temp.hrir r;

end

The CIPIC database includes a dummy-head as one of its subjects (KEMAR dummy-head withSubjectID equal to 165). Accessing its HRIR data is done by

KEMAR = cipic(find([cipic.SubjectId] == 165)).HRIR Left;

The arrayKEMARthat we created is a 3-Dimensional array. In order to access the HRIR corre-sponding to a source at 80◦ to the left and 45◦ below the horizontal plane we can use the followingline of code (for the azimuth and elevation angles convention see thehrir data documentation.pdf document included in the course materials). Note that weneed to use thesqueeze function to reduce the dimensionality to 2D for plotting.

figure;plot(squeeze(KEMAR(1,1,:)));

4.4 Summary

In this unit we have covered the following topics on Cells, Structures and Multidimentional Arrays:

• Reading data from a .text file into a cell usingtextscan .

• Indexing data in cells using cell and context indexing.

• Indexing data in structure arrays using thestruct(n).fieldname syntax.

• Accessing and restructuring data from cells, structure arrays and multidimentional arrays.

• Using dynamic fieldnames in structure indexing.

• Vectorisation in cell indexing usingcellfun .

41

Page 46: Main

For more information on any of the topics covered, try MATLAB’s ‘Product Help’ or visithttp://www.mathworks.com/products/matlab/.

4.5 Test Yourself

1. True or False: The expressionC(1,2) , where C is a 3-by-2 cell array, will return a cell datatype.

2. The data type returned by the expressionC{1,2 }, where C is a 3-by-2 cell array, will be:(A) a 1-by-1 numeric array(B) a 1-by-1 cell array(C) a structure(D) any data type.

3. True or False: As cell arrays can contain any data type, it is recommended to use them inevery instance in place of numerical arrays.

4. True or False: The dimension of a structure array is equal to the number of fields it contains?

5. True or False: All operators and functions that take numerical arrays as input argumentswork in the same way for 2D and multidimensional arrays.

42

Page 47: Main

Chapter 5

Visualising Data & GUI Development

The aim of this unit is to provide an overview of the visualisation techniques and graphical userinterface (GUI) development tools available in MATLAB R2010a.

In this unit we introduce the concept of a graphics object andhow these objects are structuredin MATLAB. We describe methods for accessing handles to objects, how to use these handlesto modify object properties and how to add interactive graphics objects to figures. We will alsointroduce the various plot types available in MATLAB’s Plot Catalog and explain how to generateand export animations. Finally, we explain how to develop GUIs using the Graphical User InterfaceDevelopment Environment (GUIDE).

By the end of this unit you will have developed skills that willenable you to:

• Explain the hierarchy of graphics objects and their associated properties.

• Modify the properties of graphics objects using object handles.

• Add user interface controls to a figure.

• Search for, select and modify plot types in MATLAB.

• Generate and export animations.

• Develop graphical user interfaces using GUIDE.

Open5 Visualising Data.m for the exercises in this unit.

For exercises 1, 2, & 3 we will be plotting equal loudness contours from the ISO 226 (2003)standard, which show the relationship between the sound pressure level (in dB SPL) and perceivedloudness level of pure tones.

43

Page 48: Main

For exercises 4, 5 & 6 we will be using the CIPIC database provided by the Center for ImageProcessing and Integrated Computing, University of California, Davis (Algazi et al. 2001), thatyou used in Unit 4: Structuring Data.

5.1 Object Handles

What is a ‘handle’? In MATLAB graphics are made up of objects. Each object has its ownhandle (you can think of this as an address) and a set of properties which describe the functionand appearance of the object. These properties can be modified by using the handle to access theobject.

Root (current MATLAB session)

Figure

Axes Uicontrol Uimenu Uicontextmenu

Image Line Patch Rectangle Surface Text

Level 0

Level 1

Level 2

Level 3

Figure 5.1: Hierarchy of graphics objects

The hierarchy of graphics objects is shown in Figure 5.1. Thelevel 3 objects shown are associatedwith the Axes object. We will look at the user interface (Ui) objects later in this unit. Level 3objects are often referred to as the ‘children’ of level 2 objects and level 2 objects are the childrenof level 1 objects and so on. For more information on graphicsobject hierarchy, go to:

Help → Product Help → MATLAB → User Guide → Graphics → Handle Graphics Objects→ Organisation of Graphics Objects

The handle to a graphics object can be obtained when you create the object or by using commandssuch asfindobj . To obtain the handle of an object when it is created, asssigna varible to theoutput of the function used to create the object. For example:

hline = plot(f,Lp);

‘hline’ now contains the handle to the line object created bythe plot function.

htitle = title(‘60 phon equal loudness contour’);

‘htitle’ now contains the handle to the title text object on the current axes.

hx = xlabel(‘Sound pressure level (dB)’);

‘hx’ now contains the handle to the x axis label text object onthe current axes.

44

Page 49: Main

To find handles to graphics objects we can use the findobj command, e.g.

hlineobjs = findobj(gca,‘Type’,‘line’);

gca returns the handle of the current axes. We can obtain the handles to the figure window and tothe axes using the ‘get current figure’gcf and ‘get current axes’gca handle commands, e.g.

hfigure = gcf ;haxis = gca ;

The findobj command will only return the handle of an object if the object’s HandleVisibilityis turned on. For the hline object above we can check that the HandleVisibility is set to ‘on’ using

get(hline, ‘HandleVisibility’)

If the HandleVisibility of an object is turned off, we can still obtain the handle by using thefindall command instead.

5.2 Modifying Object Properties

All graphics objects have a number of properties that can be modified. For text objects these prop-erties include: Color, FontName, FontSize, Interpreter (for LATEX or TEX instructions), Position,Rotation and String (for a full list, see Text Properties in the MATLAB Product Help documenta-tion). For example, to change the string property of a text object, we can use theset function:

set(htitle, ‘String’, ‘Equal loudness contours’);

To change the colour, style and thickness of a line object we can use theget andset functionsto retrieve the properties of the line and modify them:

set(hline, ‘Color’, ‘r’);

set(hline, ‘LineStyle’, ‘:’);

lw = get(hline, ‘LineWidth’);

set(hline, ‘LineWidth’, 2 * lw);

To change the properties of an axes object we can use the specific handle for the axes object, or thegca command:

set(haxis, ‘XScale’, ‘log’, ‘Xgrid’, ‘on’);

set(gca, ‘XScale’, ‘log’, ‘Xgrid’, ‘on’);

What advantages are there of using a specific handle such as ‘haxis’ instead ofgca ?

45

Page 50: Main

Note that it is possible to change more than one property of a graphics object using the sameset

command.

For more properties that you can modify, see Axes Propertiesin the MATLAB Help documenta-tion. Here are a few quick and simple ways of changing plot options without using handles:

xlabel(‘x axis label’) Sets the xlabel (or ‘ylabel’ and ‘zlabel’)title(‘Title of graph’) Adds a titletext Adds text at a specific locationgrid Adds a grid to the plotlegend Adds a legendaxis off Turns off the axis

To delete a figure, use theclose command. Note thatclose is the same asclose(gcf) andclose all deletes all figures that do not have hidden handles.

5.3 Adding Uicontrol Objects

To make a figure interactive, we can add a user interface control such as a push button (Figure 5.2):

hfigure = figure;

hline = plot(f,Lp);

xlabel(’Frequency (Hz)’);

ylabel(’Sound pressure level (dB)’);

title(’60 phon equal loudness contour’);

set(gca, ’XLim’, [20 12500]);

hbutton = uicontrol(‘Style’, ‘pushbutton’, ‘String’, ‘Button’,...

‘Position’, [385 300 100 70], ‘Callback’, ’disp(‘‘Click!’’)’);

hbutton is now the handle to a Uicontrol object, which displays on thecurrent figure. When it isclicked, the Callback property executes thedisp function, which displays the word ‘Click!’ in thecommand window. This type of ‘Callback’ is called a ‘String Callback’ as the Callback propertyis a string of commands to execute.

If we generate a second figure window, we can move this Uicontrol object by changing its ‘Parent’property:

hnewfigure = figure;

set(hbutton, ‘Parent’, hnewfigure);

We can also modify the Callback property of this Uicontrol object:

46

Page 51: Main

Figure 5.2: Figure with Uicontrol object

set(hbutton, ‘Callback’, ...

‘set(hfigure, ‘‘Color’’, [rand, rand, rand])’);

Another type of Callback that we can use is a ‘Cell Array Callback’:

set(hbutton, ‘Callback’, ‘change scale callback’, gca);

In this example the Callback calls a function calledchange scale callback . This functionchanges the x-axis scale from logarithmic to linear or vice versa.

When using functions in Callbacks that require input arguments (such asgca in this example), thefunction name and input arguments need to be specified in a cell array (hence the curly brackets).The input argument,gca , is the handle to our current axes (if you have lots of figures open it isbetter to specify the unique handle of the axes that you want to manipulate, rather than usegca ).

The following example uses the ‘KeyPressFcn’ callback, which enables the user to interact withthe GUI by pressing keys on a computer keyboard.

set(hfigure, ‘KeyPressFcn’, ‘change scale keypressfcn’, gca);

For more properties that you can modify, see Uicontrol Properties in the MATLAB Help docu-mentation.

47

Page 52: Main

5.4 Plot Types

MATLAB plot functions can be categorized by the dimensionality of the data to be plotted, e.g.

1-D (vector): plot , hist , stem

2-D (matrix): imagesc , mesh, surf , plot3

3-D (volume): isosurface , contourslice

0 1 2 3 4 5-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

Time (ms)

Ma

gn

itu

de

Subject 3: left ear HRIR at 0 deg. azimuth and 0 deg. elevation

Time (ms)

De

gre

es

Azim

uth

Subject 3: left ear HRIRs at 0 deg. elevation

0.5 1 1.5 2 2.5 3 3.5 4 4.5

-45

0

45

0

0.5

1

1.5

2

2.5

x 104

-100

-50

0

50

1000

1

2

3

4

Azimuth (degrees)

Subject 3: left ear HRTFs at 0 deg. elevation

Frequency (Hz)

Figure 5.3: Examples ofplot , imagesc & surf Figures.

For more plot functions have a look at the list of plots in the MATLAB help documentation (seeFigure 5.4

Help → Product Help → MATLAB → User Guide → Graphics →

Plots and Plotting Tools → Figures, Plots, and Graphs → Types of MATLAB Plots

Alternatively, to interactively experiment with different plot functions, choose the variable in theWorkspace that you would like to plot and open the Plot Catalogby clicking on the Plot Selectoricon in the Workspace menu bar (see Figure 5.5).

48

Page 53: Main

Figure 5.4: List of plots in the MATLAB Help documentation

Figure 5.5: Plot Catalog

49

Page 54: Main

5.5 Animations

Animations can be generated in MATLAB by saving a sequence ofplots using thegetframe

command to generate a movie or by modifying the properties ofgraphics objects and updatingthem using thedrawnow command.

5.5.1 Creating a Movie using Getframe

Create the axes, labels and fix the axes limitsplot(t, squeeze(hrir l(1,9,:)));

set(gca, ‘XLim’, [t(1) t(200)], ‘YLim’, [-1 1], ...

‘NextPlot’, ‘replacechildren’);

xlabel(‘Time (ms)’)

ylabel(‘Magnitude’)

title(‘Subject 3: left ear HRIR from -80 to +80 degrees azimuth’)

for k = 1:length(azimuths)

plot(t,squeeze(hrir l(k,9,:)));

M(k) = getframe(gca);

end

movie(M)

Here we change theNextPlot property of the current axes object fromreplace toreplacechildren . This ensures that the previous line object is removed before the next lineobject is plotted, but without resetting the axes.

The getframe command returns a movie frame. A movie frame is a struct with two fields;‘cdata’ (the image data) and ‘colormap’.

movie(M,n,fps) plays movie M n times at a frame rate of fps frames per second (the defaultframe rate is 12 fps).

To export the video as an AVI (audio/video interleaved) file you can use themovie2avi conver-sion function, e.g.

movie2avi(M, ‘mymovie’, ‘fps’, 15);

Here movie M will be saved asmymovie.avi with a framerate of 15 fps.

Alternatively, you can create an AVI file object using theavifile function and add frames tothis object in the for loop:

50

Page 55: Main

Create the avi file objectaviobj = avifile(‘mymovie.avi’,‘fps’,15);

Create the axes, labels and fix the axes limitsplot(t, squeeze(hrir l(1,9,1)));

set(gca, ‘XLim’, [t(1) t(200)], ‘YLim’, [-1 1], ...

‘NextPlot’, ‘replacechildren’);

xlabel(‘Time (ms)’)

ylabel(‘Magnitude’)

title(‘Subject 3: left ear HRIR from -80 to +80 degrees azimuth’)

for k = 1:length(azimuths)

plot(t,squeeze(hrir l(k,9,:)));

M(k) = getframe(gca);

aviobj = addframe(aviobj,M(k));

end

Close the avi file objectaviobj = close(aviobj);

5.5.2 Modifying Graphics Object Properties using Drawnow

figure;

surf(f,azimuths,HRTF(:,1:length HRIR/2));

Viewing angle in degrees for anticlockwise rotation (not the azimuth angle of the HRTF):az = [pi/2:0.01:4 * pi/2] * 180/pi;

axis off

for k = 1:length(az)

Use ‘view [az el]’ command with azimuth and elevation input parameters:view(az(k), 60);

drawnow

end

Here we use the ‘view’ command to animate rotation of the viewpoint in an anticlockwise directionabout the z axis. We could also use the axes object camera properties (e.g. ‘CameraPosition’) orthe ‘rotate’ and ‘rotate3d’ functions to interactively rotate the axes.

drawnow forces the figure window to update in the loop. If it is commented out or left outsidethe loop, the figure is updated at the end of the loop and only the final frame is visible.

51

Page 56: Main

5.6 Graphical User Interface (GUI) development in GUIDE

In section 5.3 we began to create very simple GUIs by adding a push button uicontrol object to afigure. We can also quickly create GUIs by using MATLAB’s Graphical User Interface Develop-ment Environment (GUIDE).

Open GUIDE using the commandguide in the command window. This opens a quick startwindow where you can choose to create a new GUI or open an existing one.

ELC GUI.fig is a simple GUI that displays equal loudness contours. OpenELC GUI.fig inthe GUI Layout Editor. On the left hand side of the Layout Editor are buttons for selecting graphicsobjects. In the main window of the Layout Editor is the half finished GUI calledELC GUI.fig

(see Figure 5.6).

Property InspectorM-file Editor

Figure 5.6: ELCGUI.fig in the Layout Editor

ELC GUI.fig has an axes object, a popup menu, a push button, two radio buttons and varioustext objects. Select the axes object and then click onView → Property Inspector, or click theProperty Inspector icon in the toolbar at the top of the Layout Editor, or simply double click theobject. The Property Inspector shows all of the properties and settings for the selected graphicsobject, and you can modify these properties (see Figure 5.7).

Find the ‘Tag’ property for the axes object. You will see thatthis property is set to ‘axesELC’. This

52

Page 57: Main

Figure 5.7: Property Inspector

is a user-specified label and we can use this to access the axeshandle to modify the axes object inthe code for the GUI. If you leave the Property Inspector openand click on other graphics objectsin the GUI, you will see their properties.

Now click onView → M-file Editor, or click on the M-file Editor icon. This opens the code filefor the GUI. In the M-file Editor, click on thef() show functions icon. This lists all the object createand callbacks functions. InELC GUI OpeningFcn you will see default properties for the radiobuttons and axes object, which are set as the GUI is created. The handles structure for the GUI isupdated using the command,

guidata(hObject, handles);

wherehObject is the handle of the object whose callback is executing.

Variables created within a callback function are local to that function and cannot be accessed byother functions. To access the properties of other objects,we can use theget andset functionswith the Tag property of the object.

Note: if the properties of objects are modified using theset command, the handles structure forthe GUI must be updated in order for these changes to be seen byother functions.

To run the GUI, click the green arrow icon or by typeELC GUI in the command window.

53

Page 58: Main

To run a finished example, typeFinal ELC GUI in the command window.

OpenCIPIC GUI in GUIDE (see figure 5.8). This GUI has two axes, one popup menu, a numberof text box objects and two editable text boxes (note: the ‘Enable’ property of these text boxes hasbeen set to ‘off’ so they appear greyed out and the user cannotenter data).

Figure 5.8: Basic CIPIC GUI layout

Open the m-file for this GUI using the pencil-pad M-file Editoricon and inspect the code. In theCIPIC GUI opening function,CIPIC GUI OpeningFcn , you will see

handles.cipic = getfield(load(‘CIPIC GUI data.mat’), ‘cipic’);

This line of code loads the CIPIC struct that you saved as a .matfile in Unit 4: Structuring Data,and saves it in the handles structure of the GUI. After loading the CIPIC struct, the subfunctionupdatePlots is called with the handles structure as an input:

54

Page 59: Main

updatePlots(handles);

Every time this subfunction is called, it gets the currentlyselected subject from the popup menuobject with the tag ‘menuSubject’ and uses this informationto locate and display the age and sexof the subject in the editable text boxes. The subfunction then plots the left and right HRIRs forthe subject for an azimuth of 0 degrees and an elevation of 0 degrees.

To run a finished example, typeFinal CIPIC GUI in the command window.

For more information on creating GUIs using GUIDE, see ‘Creating GUIs with GUIDE’ in theMATLAB Help documentation.

5.7 Summary

In this unit we have learned about:

• MATLAB graphics objects, object hierarchy and object handles.

• Using object handles to access and modify object properties.

• Making interactive figures or ‘GUIs’ using Uicontrol objects

• The 1-D, 2-D and 3-D plot functions that can be accessed in MATLAB’s Plot Catalog.

• Generating animations using thegetframe command and by modifying object propertiesand updating them usingdrawnow .

• Graphical user interface development in GUIDE.

For more information on any of the topics covered, try MATLAB’s ‘Product Help’ or visithttp://www.mathworks.com/products/matlab/

5.8 Test Yourself

1. A Uicontrol object is a child of which object?(A) Axes(B) Figure(C) Image(D) Uimenu

55

Page 60: Main

2. Which of the following would you use to return the handle of an object if the HandleVisibil-ity of the object is off?(A) find

(B) findall

(C) findobj

(D) findfigs

3. Which of the following would you use to plot data stored in a vector?(A) plot

(B) imagesc

(C) surf

(D) isosurface

4. True or False: AVI files can be generated using thedrawnow command?

5. Which of the following is not an interactive Uicontrol object?(A) checkbox

(B) edit

(C) slider

(D) text

6. hObject is (select one)(A) the handles structure of the GUI(B) the handle of the object whose callback is executing(C) a type of graphical object(D) a graphical object property

References

Algazi, V.R., Duda, R.O., Thompson, D.M. & Avendo, C. (2001) TheCIPIC HRFT database.2001 IEEE Workshop on the Applications of Signal Processingto Audio and Acoustics, 99-102.

ISO 226 (2003) Acoustics - Normal equal-loudness-level contours (second edition). InternationalOrganization for Standardization, Geneva.

56