Introduction to Matlab, MSc in Robotics Contents Prerequisites ........................................................................................................................................... 3 Course description .................................................................................................................................. 3 Description of Matlab ............................................................................................................................. 3 General tips in using Matlab ................................................................................................................... 4 Matlab development environment..................................................................................................... 4 Case sensitivity and variable/script/function naming ........................................................................ 5 The “diary” .......................................................................................................................................... 5 The command history and command window ................................................................................... 5 Getting help ........................................................................................................................................ 6 Simple variables in Matlab and some special characters/words ............................................................ 7 Simple variables .................................................................................................................................. 7 Memory usage ................................................................................................................................ 9 “Operational” and “relational” characters, words/variable/constant names in Matlab ................. 10 Other special characters in Matlab ................................................................................................... 11 Single inverted commas ................................................................................................................ 11 Percentage signs ........................................................................................................................... 11 Commas and semicolons .............................................................................................................. 11 Ellipses........................................................................................................................................... 12 Colons............................................................................................................................................ 13 Round brackets ............................................................................................................................. 14 Array variables ...................................................................................................................................... 15 Scalars, vectors and matrices............................................................................................................ 15 Array declaration and initialisation ................................................................................................... 15 Array data access, array indices ........................................................................................................ 16 Efficiency of array usage and memory pre-allocation ...................................................................... 20 Three dimensions and above ............................................................................................................ 20 Scalars, vectors and matrices............................................................................................................ 20 Mathematical operators and usage with arrays ............................................................................... 21 Finding the size of arrays .................................................................................................................. 22 Vectors, sizes and indexing ............................................................................................................... 23 Exercise ............................................................................................................................................. 24 Scripts, functions, debugging and variable scope ................................................................................. 24 Scripts................................................................................................................................................ 24 Functions ........................................................................................................................................... 25 Debugging ......................................................................................................................................... 27 Variable scope ................................................................................................................................... 29 Global variables............................................................................................................................. 30 Variables in scripts ........................................................................................................................ 31 Code looping and branching ................................................................................................................. 31 Code looping: for loops .................................................................................................................. 31 Code branching: if statements ....................................................................................................... 33 Code looping: while loops.............................................................................................................. 35 Error checking and testing .................................................................................................................... 37 Testing for efficiency ............................................................................................................................. 37 Figures and plotting data ...................................................................................................................... 38 Saving data to files ................................................................................................................................ 41 Loading data from files ......................................................................................................................... 41 Strings and interacting with users ........................................................................................................ 41 Prerequisites It is very much recommended that you have a basic knowledge of another programming language, e.g. the introductory course on C programming that you should have completed. An understanding of the strengths and weaknesses of more than one programming language can bring a greater understanding of how programming languages work in general. Knowledge of several languages can save much time if the “best” language for the job is chosen from the outset, based on the project constraints (language functionality, limited processing power, limited memory, availability of language on platform, etc.). If you are unfamiliar with C programming, some reading on this language is recommended to allow comparison with Matlab as a programming language (and because it can be used together with Matlab – see below). Background reading of “learning” (“how-to” rather than “reference”) type books would help greatly (e.g. 1,2). Also, general books on programming itself (e.g. 3) would help. These are available in various quantities in the libraries. Various online sources of material are also available, but nothing beats a well-established, reviewed and edited book (for a well-established language like C). There are books on Matlab (e.g. 4,5), and it is very easy to find a lot of good quality code and tutorials online. Much can also be learned by checking the help and tutorial features built in to Matlab (see the Help in Matlab section below). Course description This course intends to bring you up to speed with Matlab so that you can use it in the various units that you take within your MSc. The intention is to talk through usage of Matlab, some commonly used commands programming structures, and some techniques for creating scripts, functions and whole programs, plus ways to save and output results so that they can be used elsewhere. Description of Matlab Matlab (officially: the rather shouty name of “MATLAB®”) is a programming language and development environment. Many people come to Matlab thinking that the “Mat” part stands for “mathematics”, and that it is an environment that is used for doing symbolic maths. While Matlab does have a toolbox 6 for doing symbolic maths, this was not its initial or main purpose – Matlab stands for “Matrix Laboratory” and it was initially developed to make matrix calculations and manipulations simpler to carry out. Apart from easy matrix manipulations, Matlab allows functions and data to be quickly plotted and visualised, and provides tools that allow investigations of data to be carried out more quickly than in many other environments. Matlab also provides tools for creation of user interfaces (UIs, both textbased and graphical) and Matlab code can be interfaced with code written in other languages, e.g. C, C++, Java, and Fortran (by calling MEX-files, pre-compiled code in DLLs (dynamic-link libraries), or using other similar techniques. 1 Kernighan, B.W., Ritchie, D.M., The C Programming Language (multiple editions) Kelley, A., Pohl, I., A book on C :programming in C (multiple editions) 3 B.W. Kernighan, R. Pike, The Practice of Programming 4 B. Hahn, D. Valentine, Essential MATLAB for Engineers and Scientists 5 D.M. Etter, Introduction to Matlab 6 Toolbox: a kind of “add-on” library of tools, which you usually need to pay extra for (to get a licence to run it) 2 Matlab is considered to be a fourth-generation programming language (compare to third generation languages such as C, Pascal, FORTRAN, and COBOL) and is a high-level programming language compared to these languages. This means that much of the work of writing programs is hidden away and programs can be written using far fewer commands and lines of code than in lower-level languages. This makes Matlab an ideal tool for quickly analysing data, finding solutions to problems and doing quick “what if” investigation. Matlab does not require code to be compiled before running (it is an “interpreted” language), as C and other languages do, and this can speed up development, but may cause the final solution to run slower. The interpreted nature means that the code can be debugged and additional commands executed as the code is being run, which can change the course of the program and the end result, without the need to recompile and re-run the code. A downside of Matlab is its expense, but if using it as a student or for personal use, licences can be far less expensive than commercial licences. Additional toolboxes (described later) come with additional licence requirements, and additional expense. This, and the commercial nature of Matlab has driven development of open source products like GNU Octave and Scilab, which share some similar features and language, and so may allow side-by-side development with Matlab, and relatively easy portability between the products at a lower cost. These come with the downsides of open source software (e.g. often slow support and product development), but also the upsides (e.g. inexpensive products that are less likely to be scrapped by a company or fail if the company does). General tips in using Matlab Matlab development environment The main Matlab development environment looks (initially) like this (may differ with version, and usually does not have this licence warning message!): The window sections can be moved around to other places in the main window, “unpinned” from the window into separate, floating windows, etc. In this default view, though, the current folder ad its (file/folder) contents is on the left, the command window is in the middle and the workspace and command history is on the right. These last two show details of the variables within the current “scope” discussed later and a list of recent commands, respectively (if any). The command window, especially will be used next and other aspects will be shown later. Case sensitivity and variable/script/function naming It is very important to note that Matlab is (generally) case-sensitive, so trying to run the function cos() , for instance, will not work if you type Cos() or CoS(). It also means that it could be possible to have multiple very similarly named functions or variables (the same apart from capitalisation) and so call or use the wrong one. Variable, script and function names cannot contain spaces or start with a number, though underscores are OK if you wish to use that form of naming (e.g. Function_name or variable_name, rather than camel case FunctionName or variableName, or some other format). This therefore (also) applies to script and function file names – you will not be able to run a script of function if it has a space in its file name or begins with a number. The “diary” You can turn on the “diary” in Matlab by using the diary command. This records everything that is typed into the workspace, where you will be working to start with, and so you can keep a record of everything typed in. This will allow you to look back through, and re-run commands, if you would like to review your learnings. First, navigate Matlab to the directory where you would like to save files for your this introduction (a memory stick or a backed-up remote folder on a server that will not be cleared at the end of your session), using the current folder window, or by typing the path, between single quotes, into the command window after the cd (change directory) command then pressing [Enter], e.g.: >> cd 'F:\Introduction to Matlab' The command cd can also be used to ask Matlab what the current directory is (by typing it on its own and pressing [Enter]), or using the pwd command (“show (print) working directory”). To move up a directory from the current one, use cd .. (with a space between the “cd” and the two dots). After finding your preferred folder, type into the command window: diary 'MyWorkRecord' (followed by [Enter], as before) where MyWorkRecord is the name of the file that you want to save the commands into. Do provide a file extension if you want to open the file in another application at any other time, as Matlab may not give it one by default. To stop the diary, use the command diary off. This seems to be done when you close Matlab, but it’s better to be safe and close the file to make sure it is properly saved and your work is safe and recorded. The command history and command window As you type commands they will appear in the command window. This holds a decent-sized, but not infinite, list of recent commands, and you can double click on a command to run it immediately, as if you had typed it into the command window. You can also run one, or a set of contiguous commands by clicking the first (or last) command you want to run, holding down [Shift] and then selecting the last (or first) command you want to run in the list,. Once highlighted, drag these commands across to the command window, then press the [Enter] key to run the list of commands. You can select a set of non-contiguous commands by holding down [Ctrl], clicking the commands, dragging to the command window and then pressing [Enter]. Previous commands can also be run by making sure the cursor is in the command window (flashing caret – press [Ctrl][0] to get there from any window within Matlab), and pressing the up arrow/cursor key. If a small amount of text has already been typed in the command window (e.g. “dia”, for the beginning of the diary command that was typed in), this search of previous commands will be limited to commands that started (in this case) with the letters “dia”. Getting help Please note that you can get help in Matlab at any time by typing (into the command window): help XXXX where XXXX is a function name, and pressing the [Enter] key. This gives a brief description (it prints out the comments just under the function declaration, as you’ll see later). For instance, if you type help cos, you get: >> help cos cos Cosine of argument in radians. cos(X) is the cosine of the elements of X. See also acos, cosd. Overloaded methods: codistributed/cos gpuArray/cos Reference page in Help browser doc cos (Older versions also relay information with the function name capitalised, which is not very useful in a case-sensitive programming environment) The underlined blue parts are internal hyperlinks to help on other related functions, and the last one (with doc in it) will open a help browser pop-up window that gives more help (including images, etc., not just simple text). You can get directly to the more detailed information on variable/function XXXX by typing: >> doc XXXX This kind of help only works if you already know the function name, of course, and just want a reminder. If you are less sure, you can use the lookfor function, e.g.: lookfor int8 This will (slowly if it’s being used for the first time) look through all of the help and return links to help topics that contain the word. Pressing [F1] also brings up a general help browser, or help on something specific if it’s highlighted (in the command window or the code editor, described later). You can also get help from the “Help” menu, as ever. There are some general sections that might be worth browsing and there are also some tutorials available within Matlab itself. Functions can also be found using the fx “Browse for functions” icon/button just to the left of the current cursor position in the command window, and they can be searched through in the small popup window using by typing into the search box there. If you still can’t find help on something, it may not exist in Matlab or the help may just be having an unhelpful day – try using Google to find what you want instead. There is a very large repository of code hosted at “MATLAB Central”, and lots of code supplied by others, so someone may have already done something similar to what you want. Please be careful to check the code for safety, though and avoid copyright/plagiarism issues, especially during your course. Simple variables in Matlab and some special characters/words Simple variables Matlab is a weakly-typed language and variables can be assigned without first declaring their type (unless they are to be used for symbolic maths). For example, if x = 21 is typed into the command window and [Enter] pressed, the following is shown: >> x = 21 x = 21 The double arrows and space on the first line above (“>> ”) simply show that the command window is ready to receive a command (i.e. Matlab is not doing something else). Here, the variable x has been created (declared) and assigned a value in one command. No initial declaration of the variable is required in C, this would have to be written as something like: long x; x = 21; Other data types (i.e. integers, real numbers, characters, etc.) might be chosen for the declaration, depending on what “21” meant and what other values it might take, such as: short x; unsigned short x; etc., or even: float x; double x; etc., if the variable is to be used for real numbers. The declaration and assignment would also have to be surrounded by some kind of function definition to contain the statement so it could be compiled and there could be no additional feedback (without additional statements) that x had been given the correct value. Matlab variables can contain other data types, and their data type can be changed at any time. For instance, if, having assigned 21 to x above, you then type x = 'Hello world', you would see the following: >> x = 'Hello world' x = Hello world Here x‘s data type has been transformed into a string (array) of characters long enough to hold the characters in the string “Hello world” (11 items, including the space) and the characters have been added to the array. Note how Matlab aligns character arrays to the left, but indents values somewhat. This helps you to see the nature of the variable’s contents if it is not immediately obvious (e.g. a results of 1234 may be a value or a string of characters). Transforming from one data type at run time could not be done in C, and an error or something strange would likely happen if you tried this. If the variable was already assigned as a character type, changing the number of elements in the array in C would require advance preparation and would likely stray into more complex programming territories, including use of functions like malloc, realloc, calloc and/or free for assigning memory before the space can be used to store new data. This is all handled for you in Matlab. Matlab variables can also contain additional information about values, such as when handling complex numbers. If you type z = sqrt(-1) into the command window (where sqrt is the square root function), you will see: >> z = sqrt(-1) z = 0.0000 + 1.0000i Here the variable z contains both a real and an imaginary part of the resulting variable. You could instead use the variable i, which is the square root of -1 and add real numbers to get real and imaginary parts: >> z = 6.70 + 5.54i z = 6.7000 + 5.5400i Variables can also have an array of elements assigned to them at any time (arrays are described more fully later), for instance if you typed y = [1 2 3] then x = 9 * y then you would see: >> y = 1 : 3 y = 1 2 3 >> x = 9 * y x = 9 18 27 Here y is created as an array containing three values, 1, 2 and 3. The previous contents of x are then discarded and it’s set to be an array of the same size as y, with each of the values in x equal to the values at the equivalent positions in y, but multiplied by 9. This shows that variables can be changed by a direct assignment (of constant values) or by computation in a statement like that above. Here each element of y is multiplied by 9 and the resulting three-element array is assigned to x. Variables can also be changed dynamically by the output of a function, so if you now entered x = sin(0.5), you would see: >> x = sin(0.5) x = 0.4794 The contents of x would here revert back to an individual value equal to the sine of 0.5 radians. For the Sine of the same value in degrees, use the sind function. Alternatively you could convert the value before using a formula within the function brackets, e.g.: >> x = sin(0.5 / pi() * 180) or in one statement, with nested functions (a function call within a function call), using a function like radtodeg: >> x = sin(radtodeg(0.5)) The radtodeg function may be part of a toolbox that is not available, but in this case it would be easy to recreate one, and this would enable easier code reuse and likely cause fewer syntax errors than frequent use of expressions like 0.5 / pi() * 180 throughout a piece of code. Creation of functions is described later. You can see already that it is very quick to open Matlab, try something out and get a result, compared to a using lower-level language like C. Memory usage A downside of this easy variable allocation is that Matlab defaults to using double data types unless told otherwise. Since doubles use more memory than a lot of other data types, this can lead to large memory usage when dealing with large data sets (which is often something Matlab is used for). This can be shown using the whos function, and may also be seen in the workspace window (if it’s open). If you first type clear into the command window, then this will clear all variables from the current workspace, releasing them from the system’s memory (it can also be used more specifically to just clear certain variables, etc.). Then type in some declarations/assignments like those carried out above, as below (x = 90 [Enter] y = 1.654 [Enter] z = int8(3) [Enter] whos): >> x = 90 x = 90 >> y = 1.654 y = 1.6540 >> z = int8(3) z = 3 >> whos Name Size Bytes Class x 1x1 8 double y 1x1 8 double z 1x1 1 int8 Attributes You should end up with three variables displayed, the first two being doubles and the last being an int8 data type. If the “90” assigned to x would always be an integer within a program, and one that would only ever be between the values -128 and 127, it could have been defined as an int8, but Matlab doesn’t know this, so it will play safe and use a double, which uses more memory (8 bytes compared to 1 – see above) but can contain a much wider variety of values. This was explicitly done in the declaration/assignment of z by using the int8 function, which converts variables of other data types to signed (i.e can be negative or positive) 8-bit integer data types (as there are 28 = 256 possible values from -128 to 127). The 1x1 part shows that these are individual (scalar) values (essentially a 1 by 1 array of values, as everything in Matlab is an array – this is discussed next). Each data type requires a certain amount of memory and has lower and upper limits to the values that can be assigned. These are listed under “Strategies for Efficient Use of Memory” in the help, together with some useful strategies for efficient memory usage, if this turns out to be an issue. “Operational” and “relational” characters, words/variable/constant names in Matlab These characters and words in Matlab are similar to many other languages, including C. As with C, there is a distinction between the operational equals/equation operator, “=”, which makes something equal to something and the relational equals/equation operator, “==”, which asks whether something is equal to something else. As such, the relational equals is like a function with a return value of 0 for false (“no, they are not equal”) and 1 for true (“yes, they are equal”). The arithmetic operators (+, -, *, / and ^), and other similar operators are similar to C and many other languages when used with scalar values. When used with arrays (matrices), their behaviour can differ, and this is discussed in the section on array variables. The relational operators for “is less than”, “is greater than”, “is less than or equal to” and “is greater than or equal to” are <, >, <= and >=, as with many other languages. The operator for not equal to is “~=” (some other languages use “!=”, “<>” or other systems). Again, these relational operators return a true or false value, which means that they can be used for branching logic in your program (where decisions to do one thing or another are made). Some reserved words in Matlab include i and j, to represent the square root of -1, NaN, to represent a result that is not calculable (“not a number”), eps, which gives the accuracy of floating point numbers (no number is infinitely accurate when calculated by computer, and rounding errors can occur), Inf, which represents a value that was calculated as being infinite, and pi, which contains the value of pi. Caution should be used, as Matlab’s flexibility with use of variables means that it does not stop you overwriting i, say, with something else (another number or array of values), and until you call the clear function or restart Matlab, the variable will not contain its original value and meaning. Even something like the function clear could be overwritten so that it becomes a variable (e.g. if you typed -- but please don’t! -- clear = 56 , Matlab would refer to that variable, rather than the function name (seemingly) until you restarted Matlab, as you could no longer use clear to delete from the memory clear. The section "How MATLAB Recognizes Command Syntax" in the Matlab documentation describes Matlab’s interpretation of what you ask it to do. Other special characters in Matlab Some special characters that Matlab uses include single inverted commas, percentage signs, commas, semicolons, ellipses, colons and round brackets. Single inverted commas These are used to enter strings into variables, or to send strings to functions. A single inverted comma after a matrix (after the variable that represents a matrix, e.g. mat1'), transposes that matrix. Percentage signs Percentage signs (%) are used at the front of anything that is a comment. Use comments to explain parts of the program that may not be easy to follow (though if you can make your code easy to follow by using helpful variable and function names, that can help more than not doing so, and having to rely on explanation through comments). Comments will not be executed as code, and they can take up an entire line or be put at the end of a line of code. It is also worth mentioning that the use of white space (especially blank lines) can greatly aid the readability of code and this, together with comments, can help to divide sections from each other and make the resulting program easier to read and understand. These do not slow the program down in any way as they are disregarded by the interpreter. Commas and semicolons Commas and semicolons are used in arrays to separate columns and rows, respectively. For instance, typing k = [1, 2, 3; 4, 5, 6] into the command window would give: >> k = [1, 2, 3; 4, 5, 6] k = 1 2 3 4 5 6 Here, the commas specify that 1, 2 and 3 (and 4, 5 and 6) should be put into separate, consecutive columns, while the 1, 2 and 3 should go in the first row, and then 4, 5 and 6 should go in the second. Commas do not have to be use in this way – spaces can be used on their own instead, as with the previous declaration/assignment of y. Semicolons must be used, though, if assigning arrays in this manner. Arrays will be discussed more later on. Commas can also be used to separate multiple statements on one line, thought this can make programs less clear and may be harder to debug, so unless they are extremely short statements it is probably best avoided. An example might be: >> l = 6, m = 25, n = 2 l = 6 m = 25 n = 2 This will execute each of the three statements in turn, as shown. Commas are also used to separate function arguments (variables sent to functions), e.g. rand(2, 3), a function call that will return an array of random numbers between 0 and 1 with two rows and three columns (six values in all). Up until now, Matlab has echoed back to you the result of all of the assignments and calculations that you have typed into the command window. The same would be the case for all statements (that return a result). If a semicolon is used at the end of a statement, however, this tells Matlab to supress the result. So if you typed a = 345; at this point, Matlab would declare a and set it to be an individual value of 345, but return nothing as confirmation that this had happened: >> a = 345; Gives no result back. You can check the value in a, by just typing a and pressing return (without typing a semicolon): >> a a = 345 Its value will also be shown in the workspace window, if it is open, and whos or (more specifically) whos a would say something about the size and type of a. Other related, and useful commands, include which, which indicates whether an identifier is a variable, a built-in Matlab function (and where it is located on your system), user-defined function, or something else, and what, which lists files in the current directory. While it might be good to have the results of operations shown to you in the command window as you go along, once a piece of code grows to encompass many operations, the constant printing of results to the command window significantly slows the progress of the code. In this case you might want to terminate with a semicolon most, or all, commands that report results to the command window. Statements in Matlab are therefore terminated with a commas, semicolons, or just a carriage return (new line), as with the first commands that you typed into the command window. Ellipses Since a new line can indicate a new statement, but long lines (over 80 characters long) can make code hard to read (especially if the user needs to scroll sideways), an ellipsis (three full stops / periods, “...”, not the single character that represents a ellipsis, “…”) can be used to continue code from one line to the next without separating the statement into two, thus: >> l = [1 2 3 4 5 6 7 8 9; ... 9 8 7 6 5 4 3 2 1] You will note on typing the ellipsis then pressing the carriage return, that Matlab does not create any output, as it is waiting for you to finish the statement (complete the second row of the array, in this case). Please note, any additional spaces in Matlab are not considered by the code interpreter. So these the statement b = [2 56] will be interpreted in the same way as b = [ 2 56 ] or b=[2,56]. Note also that (as above) spaces are not needed around the equals/equation operator (=), the arithmetic operators (+, -, *, / and ^), and other similar operators that have characters distinct from the alphanumeric characters (A-Z, a-z, 0-9 and underscore) that are allowed in variable and function names. Spaces here are personal choice, and may be added for legibility, but Matlab does not insist on it. Colons Colons are used to create vectors and sequential values, for accessing subsets of values in arrays and in creation of for loops. Examples of these are: >> d = 1 : 0.5 : 3 >> l(:, 2:3) = -1 and >> for indx = 0 : 1 : 4 h = indx * 2 end The first command sets a new variable, d, to be the values the result from incrementing from 1 upwards with an increment of 0.5 until the value 3 is reached (or exceeded). It therefore returns the result: d = 1.0000 1.5000 2.0000 2.5000 3.0000 If the last value were exceeded during the incrementing, it would not be included, so >> d = 1 : 0.5 : 3.1 would give the same result for d. The second command indicates that within the array l, the elements that match the criteria of being in any row (the colon on its own, “:” is shorthand for “1:end”, which means from the first row to the last row, i.e. all rows, as discussed in the section on finding the size of arrays) and between the second and third column (inclusive) should be set to a value of -1. It should therefore return: l = 1 -1 -1 4 5 6 7 8 9 9 -1 -1 6 5 4 3 2 1 as the 2 and 3 in the first row, and the 8 and 7 in the second are set to 1. Arrays will be discussed in more detail below. The third command (or set of three commands, representing the setting up of the for loop, a command that is repeatedly carried out as long as the for loop continues, and the closing statement of the for loop) will result in a set of outputs from: h = 0 to h = 8 as each time through the for loop, the value of indx is incremented from a starting value of 0 by a value of 1 (the middle “1” in the for statement), until it reaches (or exceeds) the value 4. Within the loop, h is set to twice the value of indx, and since there is no terminating semicolon, the result is of the calculation is echoed to the command window. The colon used to create the array in d is closely related to the syntax used in the for loop, and like the assignment of d using the colon notation, if the first line of the first for loop read for indx = 0 : 1 : 4.1, the loop would not be run for indx with a value of 4.1. The array in d could be built up using a for loop, with a similar structure to the statement that assigned the array to d: >> for indx = 1 : 1 : 5 d(indx) = 1 + ((indx – 1) * 0.5) end The first assignment of d is clearly quicker to type, and due to the way that Matlab functions, will also be quicker to execute. Here, the increment of the for loop has a value of 1. Since this is the default in Matlab, the middle part can be ignore and for loop line could read for indx = 1 : 5. You will also note that when typing this into the command window that Matlab will not execute any part of the for loop until it is complete (the closing end has been typed). For loops will be discussed more later on. Round brackets These are used in a similar way to most other programming languages, that is to say for calling functions, for accessing particular elements of an array, of for forcing precedence where it might otherwise not occur. An example of the last usage would be (56 + 87) * 6, which would add the two numbers before multiplying. This is against the normal order of operator precedence in Matlab, which is: 1. Brackets (()) 2. Transpose (.'), power (.^), complex conjugate transpose ('), matrix power (^) 3. Unary plus (+), unary minus (-), logical negation (~) 4. Multiplication (.*), right division (./), left division (.\), matrix multiplication (*), matrix right division (/), matrix left division (\) 5. Addition (+), subtraction (-) 6. Colon operator (:) 7. Less than (<), less than or equal to (<=), greater than (>), greater than or equal to (>=), equal to (==), not equal to (~=) 8. Element-wise AND (&) 9. Element-wise OR (|) 10. Short-circuit AND (&&) 11. Short-circuit OR (||) Array variables Scalars, vectors and matrices As mentioned above, all variables in Matlab are arrays. 1 x 1 arrays are referred to as scalars, 1 x n arrays (a single row of values) or n x 1 arrays as vectors (a single column of values), and n x m arrays are known as matrices or arrays (2D arrays). Multiple dimension variables (3D or more) are usually known as arrays. Array declaration and initialisation Arrays can be declared in a number of ways. Some have been seen already, where an array can be declared and initialised with a set of constant values in one statement. These could equally well have been pre-defined variables (like p and q, below), so an array could be created as follows: >> p = 1; q = 2; r = [p q; q p] r = 1 2 2 1 Here p and q are declared, with the semicolons suppressing the echoing of the results of these declarations, and then they are used to create a 2 x 2 array, r, with the values within p and q being used to set the values within r. This is a one-off operation – no link is implied between the value of p, q and r in the future and they are not bound in any way; these are just a set of sequential commands. So if p and/or q change value at a later point, and the command r = [p q; q p] is not run again, there would be no change in the array r as a result of p and/or q changing. Arrays can also be created and filled with zeros or with ones using the zeros or ones commands. This may seem an odd thing to do at first, but it can have its benefits, as described below. If you want an array to be filled to a known size with the same, known value in each position, say, a 4 (rows) x 3 (columns) array with 7 in each position of the array, then you could use the ones function, multiplying the result by 7, to get something like: >> arrayOfVals = ones(4, 3) * 7 arrayOfVals = 7 7 7 7 7 7 7 7 7 7 7 7 Reasons for using the zeros function include that given in the section on efficiency of array usage, below. Array data access, array indices Accessing data in an array requires use of indices of the array row and column (for a 2D array – more indices are needed for an array with more dimensions). Say an array were created by typing: >> s = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16] s = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 To access the position where the value is 10, you would need to type s(3, 2) – the third row and second column, to access the position where the value is 8, you would need to type s(2, 4) – the second row and fourth column. To change the value at the third row and second column from 10 to 300, you could use: >>s(3, 2) = 300; If the semicolon were omitted, it would echo back the values of the entire array, showing the array after the change, and thus showing what had changed: s = 1 2 3 4 5 6 7 8 9 300 11 12 13 14 15 16 To add the values in the second and third column in the second row together and then put them into the top, right position, the command would be: >>s(1, 4) = s(2, 2) + s(2, 3) s = 1 2 3 13 5 6 7 8 9 300 11 12 13 14 15 16 To access a sub-set of the rows, the colon can be used, as described previously, thus: >>s(1:3, 2:4) Since the result is given nowhere to “go” (there was no variable associated with the result of what is essentially a function call), it is allocated to Matlab’s ans variable, which holds the “most recent answer”: ans = 2 3 13 6 7 8 300 11 12 This shows the array between rows 1 and 3 and columns 2 and 4 (inclusive). The ans variable is generally not used directly (as with other variables) – as soon as another calculation is done, the new “most recent answer” will replace what was in the variable, so the next calculation using ans would be different to the previous one (e.g. type 1[Enter], then ans+1[Enter] several times in a row – each time the value of ans becomes one more than previously). If the command were s1 = s(1:3, 2:4), then the result would be put in a new variable, s1 , and it can therefore be further manipulated as a sub-set of the values of s. As discussed above, however, the values are not linked to s, and s can be changed without s1 being updated. A colon on its own (as mentioned previously) would give all rows (if in the first index position) or all columns (if in the second). Variables can be used in place of these values (they do not have to be constant, but must be integers, not numbers with fractional parts, and must be within the bounds of the array), so this would also work: >> s2 = s(p:q, 2:3); This can be a useful way to index through an array, if needed – you can increment (or otherwise step through) the value in a variable to move through the various positions within an array, using the index variable to indicate a specific point in the array, and so use or change a value at that point. Since the content of variables can be replaced at any time, arrays can change size, and Matlab allows for an array to expand to a size to include a new value inserted into it, for instance, if you were to type: >> s(5, 6) = 31 Matlab would expand the array to allow the new value, entering at row 5, column 6, with any other unspecified values in the array being set to zero, so the result would be: s = 1 2 3 4 0 0 5 6 7 8 0 0 9 10 11 12 0 0 13 14 15 16 0 0 0 0 0 0 0 31 While writing to a non-existent array location expands the array to include the position and add the value in, trying to read from non-existent location will generate an error. Arrays have to have the same number of rows and columns (and the same through the other dimensions) throughout – i.e. they cannot be “ragged arrays” (as can be possible in some other programming languages), where there are a different number of elements, e.g. if the number of columns varied throughout the rows, so this assignment would not be possible: >> s = [1 2; 5 6 7 8 9; 10 11 12; 13 14 15 16] The error given would say: Error using vertcat Dimensions of matrices being concatenated are not consistent. This is as the command above is essentially taking four arrays (a 1 x 2, 1 x 5, 1 x 3 and a 1 x 4 array) and trying to concatenate them (join them together) in the “vertical” direction (along the first dimension, which is the row direction). The first command for assigning s: >> s = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16] is actually shorthand for: >> vertcat([1 2 3 4], [5 6 7 8], [9 10 11 12], [13 14 15 16]) where four arrays, each of one row and four columns are concatenated together in the vertical direction, or even more generally: >> cat(1, [1 2 3 4], [5 6 7 8], [9 10 11 12], [13 14 15 16]) where the same four arrays are concatenated together along the first dimension, which , as mentioned above, is the direction “down the rows). The second assignment of s does not work, therefore, as the arrays have o all be the same “width” to be concatenated in the “height” direction. To illustrate this further, this would work, and result in the same array as s was (originally, before elements of it were changed): >> s3 = cat(1, [1 2 3 4], [5 6 7 8]); >> s4 = [9 10 11 12]; >> s5 = [13 14 15 16]; >> s5 = cat(1, s3, s4, s5) s5 = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Here, a 2 x 4 array is made, then two more 1 x 4 arrays, and these are all the same width, so they can be concatenated together in the first dimension. The shorthand for this would be (using nested square “array assignment” brackets): >> s6 = [[[1 2 3 4]; [5 6 7 8]]; [9 10 11 12]; [13 14 15 16];] Or the easiest way would just be as with the original assignment of s. So there are many ways to assemble arrays in Matlab. A section of array could be replaced with another section of an array, e.g.: >> s5(3:4, 3:4) = [-1 -2; -2 -1] This would replace the bottom 2 x 2 part of the s5 array, leaving: s5 = 1 2 3 4 5 6 7 8 9 10 -1 -2 13 14 -2 -1 If a sub-matrix is added to the array as above, but at indices that don’t exist, the array will expand to fit in the extra values, as shown earlier for adding in individual values (with zeros again filling any unspecified regions – e.g. try the command s6(4:5, 8:9) = [-1 -2; -2 -1]). Parts of arrays can also be deleted, though those parts this would have to be entire rows or columns, or sets of rows or columns, or a ragged array would result. This can be done by assigning them to be empty, using the open and close square brackets with nothing between them (“[]”), e.g.: >> s5(1, :) = [] s5 = 5 6 7 8 9 10 -1 -2 13 14 -2 -1 This deletes all of the columns (“:”) in the first row (“1”). This open-close bracket arrangement can also be used to declare an array that starts empty, or to make an existing array (completely) empty. For instance the following set of commands shows the declaration and initialisation of a variable as an empty array, checking it using whos filling it with some values, checking it again, then making it empty once more and one final check. >> s7 = [], whos s7, s7 = [44 55 66; 77 88 99], whos s7, s7 = [], whos s7 s7 = [] Name Size s7 0x0 Bytes 0 Class Attributes double s7 = 44 55 66 77 88 99 Name Size s7 2x3 Bytes 48 Class Attributes double s7 = [] Name Size Bytes Class Attributes s7 0x0 0 double Note the size of 0 x 0 indicates an empty array, and there is a function to check this state, too, named isempty. To test this, try: >> isempty(s7) ans = 1 This “true” return value indicates that the variable is indeed empty. Efficiency of array usage and memory pre-allocation It might seem a good idea, and more memory-efficient, to use Matlab’s dynamic variable-changing abilities to expand an array only once a new piece of data is obtained and it is ready to be placed in the array, expanding the arrays as the program progresses, but this turns out to be an inefficient way of doing things. As mentioned before, to change the size of arrays in a lower level programming language would require calls to functions to allocate memory for additional data within the array and may require moving blocks of memory around, making copies of data and then deleting it from the sections of memory available. If this were happening every time new data was created or received from an analysis or data logger, it would require constant shuffling of large amounts of data around the memory spaces. Although Matlab makes this easy for you, it still has to do these operations “under the hood” and as just as inefficient at these operations as these lower level languages, as that is what the program is ultimately written in. In Matlab, it generally more efficient to pre-allocate memory for an array, to be at least as large as the amount of data that you expect to put in it, and then fill it in the appropriate places as you progress through your process. This may require more memory initially, but it is more efficient. This is usually what the zeros function is used for, therefore: fill an array with zeros then add pieces of data in as they become available, in the next “empty space” (the next zero, row of zeros, etc.). Newer versions of Matlab have (in the code window, which you will see later) orange indicators down the right hand side of the (code) window (which you will see later) that show where code may not written as efficiently as possible,. This is one of the inefficient coding practices that is highlighted. Another is the lack of termination of lines that would echo results to the command window, as described earlier – both slow the code down significantly. Three dimensions and above For more information, see “Building a Preallocated Array”, and the other parts within the “Resizing and Reshaping Matrices” section in the help browser (the “full” help, rather than the brief one given in the command window). Scalars, vectors and matrices Matlab can handle 3D arrays and arrays with many additional dimensions, though these can be much harder to visualise and display on a screen, and if displayed are shown in “layers” in the command window, where the rows and columns in the first “depth” dimension is shown first, then the second, and so on. This can be illustrated by making a 3D (2 x 3 x 4) array, as follows: >> layer1 = [1 2 3; 4 5 6]; >> threeDimArr = []; >> threeDimArr(:, :, 1) = layer1 * 1; >> threeDimArr(:, :, 2) = layer1 * 2; >> threeDimArr(:, :, 3) = layer1 * 3; >> threeDimArr(:, :, 4) = layer1 * 4 To explain this, a 2D (2 x 3) array was created, a variable threeDimArr declared (and initialised as empty – note 3DArr would not be a valid Matlab variable name) before adding in the 2D arrays in “layers”, each layer being 1, 2, 3, and finally 4 times the values in the first. Since the last line contained no semicolon, the fully formed array should be shown in the command window, one “layer” at a time. The array was initially specified as being empty, in case such a variable already existed, as if it did, there might have been a concatenation error if it was a different size to the 2D matrices that were being added in slice, by slice. A way to do this in one statement is to use the cat function along the third dimension, as below: >> cat(3, layer1 * 1, layer1 * 2, layer1 * 3, layer1 * 4) Check that the function call above gives the same result (by, for instance, assigning it to a different variable, then subtracting one from the other, which should result in an array of the same size, full of zeros). Try the size function on this array, too, to see how the size of 3D arrays is reported. Mathematical operators and usage with arrays When + and - are used with two scalar values, they are simply added together or subtracted as normal. When adding or subtracting a scalar to/from a matrix, the scalar is added to or subtracted from (or the matrix is subtracted from the scalar) in an element-wise manner, i.e. each element in the array has a value added or subtracted, or is subtracted from that value. When used between two matrices, an element-wise addition or subtraction will occur, but only if the two matrices have the same dimensions. When *, / and ^ are used between two scalars, their behaviour is as normal. When * and / are used between a matrix and a scalar, the matrix is multiplied or divided by the scalar. When multiplying two matrices, the number of columns in the first matrix should match the number of rows in the second (this is a proper matrix multiplication, rather than an element-wise one). With division, the two matrices need to have the same number of columns, so a scalar could only precede a matrix if it was a column matrix (again, this is a proper matrix division, rather than an element-wise one). Matrices can be raised to the power of a scalar (e.g. c^2 is the same as c*c), but the matrix must be square (due to the multiplication rule given above). In order to get element-wise multiplication, division or powers of matrices, a dot should be put before the *, / and ^ operators, making them .*, ./ and .^. Unless specifically carrying out matrix operations (e.g. data and coordinate transformations), it is more common to want to multiply, divide or get the power of a set of numbers in an array in an element-wise fashion, but it is very easy to forget to use the dot-version of these operators. There is also a backslash divide operation, or “left matrix divide”. This is used like A \ B, where the result is the matrix division of A into B, which is roughly the same as INV(A) * B , i.e. B (matrix) multiplied by the inverse of A. This is often used for finding the solution of a set of simultaneous equations. It is worth trying these operators out in as many ways as you can find, using combinations of scalars, vectors and matrices to make sure that you understand the actions that they allow. Finding the size of arrays Since arrays can change size, it’s important, before doing something with an array, to know how large it is. The word end can be useful in this situation, as it signifies the maximum index (i.e. the maximum row, column, etc. number) of an array, so it can even be used without explicitly knowing the size of an array. In its use to find the maximum index of an array (in a particular dimension) it can be used on its own, or like a variable, e.g. s5(1:end-1, :), which would indicate all columns of s5 and rows from 1 to the second-to-last (i.e. rows 1:(4–1) or 1:3, as end is equal to 4 for this dimension of this array). These uses of the colon (to mean “all”, or 1:end) were briefly mentioned earlier. The size of an array can also be found using the size function, e.g.: >> s5ArrSize = size(s5) s5ArrSize = 3 4 Here, s5 is passed to the size function and the result is returned into a new variable named s5ArrSize. Since the array is a 2D array, two values are returned, i.e. the variable that is returned and passed into s5ArrSize is an array with two elements. These elements specify the size of the array in the same order as Matlab dimensions are specified in, i.e. number of rows, then number of columns, then number of “depth” layers, etc. To obtain just the size of one dimension, and return an individual value, a second argument, that of the dimension required, is passed to the size function, so the results of testing these two individually would be: >> s5NumRows = size(s5, 1), s5NumCols = size(s5, 2) s5NumRows = 3 s5NumCols = 4 where this time the number of rows in s5 has ended up in the variable s5NumRows and the number of columns in s5 has ended up in the variable s5NumCols. You should see how these variables could then be used as (upper) limits so that the rows and columns might be iterated through, from the lower index limit to the upper index limit, filling in values, for instance. Note that the lower limit of arrays in Matlab is (generally) a value of one, rather than a value of zero, as in some other languages (i.e. some languages have arrays whose indices run from 0 to n-1, whereas Matlab’s run from 1 to n, where n is the number of elements in the array). Other useful functions related to manipulating arrays and their sizes include reshape, rot90, fliplr, flipud, flip and transpose (the last doing the same as the single quote operator mentioned above). Take a look at the help entries for these to understand what each of them does, and try them out on a 2D matrix to show their effects. You might like to also look at the “Resizing and Reshaping Matrices” help topic for more information. Vectors, sizes and indexing Vectors (1 x n “row arrays” or n x 1 “column arrays”) are a special case compared to arrays with more than one dimension. These arrays are often created using the notation similar to that seen in the command d = 1 : 0.5 : 3, above, where a regular sequence of values is required. This would create a single row of values, whereas the command dDash = (1 : 0.5 : 3)' would transpose the vector seen in d before assigning it to dDash, giving a column vector. Since vectors only have one dimension, indexing is simpler, as only one value needs to be given, regardless of whether it is a row or column vector. So all of these values would be the same: d(1, 4), dDash(4, 1), d(4), and dDash(4). Check this for yourself and make sure that you understand this indexing. It is also possible to index through, say, a 2D array using only one index, and the order that the value will be returned in, with an increasing value of the index is the value in the first row, first column, to the last row, first column, then the first row, second column, to the last row, second column, and so on until the row of the last column. Try this by using the following commands: >> s8 = [1 2 3; 4 5 6; 7 8 9]; disp(s8); disp(s8(1:prod(size(s8)))); The first command makes a 3 x 3 matrix, s8, the second displays it using disp and the third displays the values in sequence, with the index of s8 going through each of the values from 1 to 9. Here the 9 is arrived at by using the size function to return a two element vector containing the array size (3 rows and 3 columns), multiplying these together using the built-in Matlab function prod, which multiplies together all of the elements in an array (along one dimension only – like several functions in Matlab it works along the “first non-singleton dimension” unless specified otherwise – see the help on this function for more information). A function that works in a similar way is sum (see the help for more details on that function, and note how it works on both row and column vectors and on 2D or higher dimension matrices). Matlab code can be very compact – this kind of output might take several lines to achieve the same result in another language. There is a danger that increasing levels of terseness will remove meaning, however, and so the code may be “better” (easier to understand and use, and/or maintain at a later date, even if not as compact, or maybe even as efficient) if nesting many functions in this way is avoided in actual programs that you write. At the very least, they may require more commenting. The size of vectors can also be found using the length function, which returns only one value, unlike the size function, which returns two values even in the array only has one dimension (one of the size values is simply “1” – the first if it’s a row matrix or the second if it’s a column matrix). This also works on arrays with more than one dimensions, but returns only the largest dimension (equivalent to doing max(size(X)), where the max function returns the maximum element in any array). It is recommended for matrices with two dimensions or more that a more specific approach is taken, using size, especially if array dimensions might change throughout the code. Exercise The mathematical term dot product (“∙”) refers to an operation carried out, usually on vectors, that results in a single value, where for example: [1, 3, -5]∙[4, -2, -1] = (1 * 4) + (3 * -2) + (-5 * -1) = 4 - 6 + 5 = 3 Using what has been explained above, find two different ways to calculate the dot product of two row vectors, the first containing the values 1, 2 and -3 and the second containing the values 3, 6 and 7. The answer should be -6. Try and find the shortest way possible (shortest command) and try and make your solution as general as possible (i.e. it should still work if the number of elements in both vectors changes). Scripts, functions, debugging and variable scope Scripts A script is as simple as being a text file (with the file extension “.m”) with a set of commands in it. Since these files can be saved they are a good way to write and maintain code. Any of the commands that you’ve been typing into the command window can be placed in a script. You’ll now move to using the editor, and so the diary that you set going may be less useful, as it saves only the commands typed into (or otherwise executed) in the command window. You could stop it if you like, or leave it running to catch any additional commands that are entered. To open the editor, you could make a new M-file – there are many ways, including suing the “New Script” menu/button, the “New” drop-down list menu/button (then selecting “Script”), press [Ctrl]N to open a new script, or press [Ctrl][Shift]0 (zero) to shift to the editor (from the command window, which you can get back to using [Ctrl]0). Once you have a new script open, the first thing you should do, to avoid losing work, is to save the new script as something sensible. Remember not to use numbers at the start or spaces. Remember – to avoid losing work: save early, save often! Matlab does auto-save, but it’s best not to reply on these files. Also, while there are multiple levels of undo, it might be best to regularly save versions of the file as you go along (e.g. FileName001.m, FileName002.m, etc.), so if you go down a long branch of changing code that doesn’t work, you can get back to a previous version that worked. Earlier version can always be discarded once you are happy with a final chunk of code. You might want to undock (right click the top of the code editor sub-window and press “Undock”), if it starts in a docked format, and have it float above the other windows (within Matlab’s main window), so that switching between these is a (maybe) easier [Alt][Tab] rather than the other shortcuts/mouse clicks and to give more screen “real estate” to the other windows within the main one. To make a script that would carry out the previous actions you set in place to create vectors and find the dot product of them move back to the command window, copy the code from the command window or the command history window and paste it into the editor. All “>>” and extra spaces (at the front of lines of code) that you might copy across from the command window should be deleted, leaving just the individual commands, preferably one per line on the editor. Please also keep all lines to no more than 80 characters long by using ellipses. Once you have the set of commands in the code editor and you have saved the file, the commands can be run by clicking the “Run” button, or pressing [F5]. If this works, you should see the script name appear in the command window, as this is the other way to run the script (type its name into the command window and press [Enter]). The code will be run and any commands that you have left “open” (with no semi-colon afterwards) will echo assignments, etc. back to the command window. When writing a standalone piece of code (i.e. there are no proceeding scripts or functions called), you may want to put the following three commands at the top (or a subset of them if not all are needed): close all; clear; clc; These commands close any figure windows that might be open (described later), clear all (nonglobal) variables in the current workspace/scope and clear the command window, leaving you with a clear view of the results of the script’s actions. Anything that comes up in terms of new windows or output in the command window will be as a result of this script and not any previous scripts or commands directly typed into the command window, so no confusion can occur. So, you now have a piece of code that you can run any time you like, and this piece of code can even be run by another script, or directly from the command window, just by typing its name on its own line. If that script is saved in another folder, though, a full or partial path to the file will be required. A partial path is only required for folders below the current one (e.g. run('Test folder\TestScript001.m')), but a full one is required if the folder is on a different folder “branch” (e.g. run('C:\Matlab files\Test folder\TestScript001.m')). Since this sends the string representing the file name and path to the run statement in quotes (as a string, or character array), spaces are allowed in any of the folder names (the file name should still be spacefree, though). The code is rather limited, though; it would only be able to do the dot product of two particular variables unless it was changed each time. It would be better to be able to do the dot product of any two (row) vectors. For that, you could use a function. These are described next. Functions As another example of a set of operations that might be put into a function, we could look at the Fibonacci sequence. This starts with two ones and all subsequent values in the sequence are the sum of the two previous values. Say you wanted to find the total of a particular Fibonacci sequence, maybe the numbers 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 and 144, you could make a script named “TotalTheseVals.m” containing the code: %Show the total of a particular Fibonacci sequence. valArr = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]; totalOfSeq = sum(valArr) Running this would give an output, but it would only work for one particular sequence, not any sequence, and so would need to be manually changed to get any other total value. You can make a function that does the totalling part, but for any array of values that is sent to it. This is a rather trivial thing to make into a function, but this is just the first example, and it will be improved later. To start with, you should make a new function. Newer version of Matlab make it easy to make a new function by using the “New” drop-down list menu/button (then selecting “Script”). This creates the outline of a function: function [ output_args ] = Untitled3( input_args ) %UNTITLED3 Summary of this function goes here % Detailed explanation goes here end The outline shows you what’s needed, with the initial and final (opening and closing) keywords of function and end, an initial function name of UntitledXXXX and the position that input and output arguments should go, between round and square brackets, respectively. It also shows the initial comment, which Matlab uses to relay help to the user. To illustrate this, you should (select then over)type (or delete then type) TotalValues as the function name, and then saved the file with the name “TotalValues.m”. Matlab has been checked to see if it already has a function or variable of this name and it does not – this is worth doing to make sure there is no confusion later on. The function name (at the top of the code in the file) should match the file name – this is how Matlab finds the functions it is asked to run. Once this is done, go to the command window and type: >> help TotalValues UNTITLED2 Summary of this function goes here Detailed explanation goes here You will see that the comment at the top of the function (just underneath the line with function on it) was returned by the help function. Typically, the first part (without any indenting after the % comment character) is where you would write a brief summary of the function, then you would write a more detailed description underneath that, with some indenting, to separate the two sections (visually) from each other. This a recommended format – you could write anything there, but it’s best to stick to standards. Other things can be included in the text returned by help, too. For example, if you look at help for the function cos (type help cos), and then look at the function for cos (type edit cos and it will open in the code editor), you’ll see how the comment and the text returned by help compare. You can only see the “top” (description) of this function, as it is a built-in function, which is pre-compiled and can’t be edited, but it still requires a help entry, which this provides. Note that there is a part that says “See also” in the comments. This is a sign to Matlab to make the next two functions mentioned into click-able hyperlinks. You could do the same in your function if there were related functions – just add the names of functions that Matlab can find in the current directory, or in the other paths that it looks at (type path into the command window and look at help path to find out more about these paths). Note also that the help function stops relaying these comments to the command window once it reaches a blank space (or other non-comment line) that breaks up the block of contiguous comment lines at the top of the function. So, next you should change the UNTITLEDXXX in the comment at the top of the function to be the same as the actual function name and write something informative below, following the format shown. Also the input_args and output_args variables should be changed to variable names that are more appropriate for this function. In this case, change input_args and output_args to valueArray and totalOfValueArray, respectively, as describes what they are (what will be passed into and returned from the function). This is a simple function (but can demonstrate some useful things), so just put this line of code inside it, after the comment at the top: totalOfValueArray = sum(valueArray); Once saved, the function can be run. Try this first from within the command window, by typing: >> TotalValues You will see an error message indicating that at least one input argument was not passed to the function that it needed to complete its job (“Not enough input arguments”). It also shows the line on which the error occurred (“Error using TotalValues (line XXXX)”). To investigate this more fully, you can make the code go into debug mode. Debugging Go to the line of code in the code editor with the sum function on it. Either press [F12] or left-click on the small line just to the right of the line number (itself to the left of the line of code). Only executable lines of code have these small lines next to them – you’ll see none of these on lines with comments on, or blank lines, for instance. This will toggle a red dot on/off, indicating a breakpoint. Alternatively, to put a breakpoint on the first executable line in this file, type dbstop in TotalValues in the command window. Code in Matlab runs linearly through from the top to the bottom (unless cycled back up to a previous line using a for loop or similar). If code execution is about to execute a line that has a breakpoint on it, it will stop and wait until some action is carried out by the user. The point where the code has “reached” in its execution is shown with a small green arrow pointing to the right. Run the code again by typing TotalValues in the command window (or using the up arrow key until that command is reached), then return to the code window and you should see the code has paused on the line with the breakpoint (it is now in debug mode), with the green arrow pointing at the line that will be executed next. Normally, if you hover your mouse over a variable in debug mode, Matlab will show you what it contains (or an overview if it’s a big array). Hovering over the variables on the line of code (valueArray and totalOfValueArray) shown nothing, though, indicating they do not exist, at least within the current “scope” (discussed below). This can also be seen by briefly going to the command window again and typing whos. While in debug mode, commands can be executed and they will be run just as if they were a line of code being run, or as commands normally run when not in debug mode. You can see that nothing is returned, so no variables are present within the current “scope”. You will also notice that the usual “>> ” prompt in the command window is replaced with “K>> ”, to show that Matlab is in debug mode. It is natural for totalOfValueArray not to exist, as it has not been declared or set to anything previously, and this line would do that, except that valueArray does not exist either, so if the code continued, it would try to take do sum on a non-existent valueArray and pass the result into totalOfValueArray. To show this, first a brief discussion of the debug tools. Some of the icons/buttons at the top of the code window change to allow debugging functions to be used. These functions include (not in this order on the screen): ï€ “Step In”, which runs through the code one line at a time and “steps into” any called functions or scripts it comes across, with the debugging moving to the first executable line in the file for that called function or script. Hovering the mouse over this button shows the shortcut to be [F11]. ï€ “Step”, which does the same, but steps over any called functions or scripts it comes across, continuing in the current file (but not stepping down into “sub-files”), with the shortcut [F10]. ï€ “Step Out”, which carries on until the execution has left the current file and returned to the “file” (or other script/function/place) that called it, with the shortcut [Shift][F11]. ï€ “Continue”, which allows the code execution to go off again at normal speed and no longer in debug mode, at least until it might encounter the another breakpoint, or the end of the program, with the shortcut [F5]. ï€ “Run to Cursor” – place the cursor on a line and press this button to get the code to run until It reaches the line with the cursor on, (no shortcut key). This is equivalent to setting another breakpoint on the line with the cursor on and pressing [F5], then removing the breakpoint again. So to make the line execute, press any of the shortcut keys above to get the next line to execute. The code will stop regardless of which is used and the same error will be shown in the command window. So you can see that if you pass nothing into the function (as an input argument) then nothing will end up in the variable valueArray and so no calculation can be done using it. To remedy this, type the following in the command window: >> valArr = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]; >> TotalValues(valArr) This makes an array, valArr, and passes that array into the function TotalValues as the first (and in this case, only) input argument. If the breakpoint is still present on the (only) executable line of code within, the execution will stop there again; hover over the valueArray variable again to see what it contains. This can be done at either position of valueArray in the function (in the brackets at the top, where it comes in as an argument) or on the line that’s about to be executed. Now it has a value, it can be used, so press Step ([F10]) to step through that line of code and execute it. The green arrow should move on to the end keyword/function (so that is the next thing that will be executed), and if you hover your mouse over the totalOfValueArray variable, you’ll see that it’s been assigned as a result of the sum function call. Note that this function could be called from a script, or another function, as well as it could be called from the command window. Also note that while this function only had one input argument and one output argument, it is possible to have multiple input and/or output arguments, and these can all be of different types. Functions can also have also can have optional arguments, so a function can be called in a variety of ways, and different functionalities can be set up within the function, depending on the number and/or type of arguments that are set to the function. See the function nargin in the (full) help (i.e. doc nargin) for more information and examples. Variable scope There are some more things to take away from this. Firstly, that the variable valArr was passed into the function in the first (and only) input argument position, and in the process, a copy of this was made in memory and it was assigned to the variable valueArray – this was deliberately made a different name to illustrate this. If the input argument within the function file was named AAbbEESADJWE it wouldn’t make any difference – the first argument in the list in the place that calls a function gets copied into the first argument that is listed in the function itself (at the top of the file). To illustrate that what is in the function (in valueArray) is a copy of valArr and not the same thing (the same point of the machine’s working memory), before exiting the function (now that totalOfValueArray has been assigned), empty the contents of valueArray using the command valueArray = [];, then press press [F10] twice more to execute the end function and then leave the function completely (or press [F5] just once to continue until this function is exited on and exit). If valueArray and valArr were the same variable, in the same piece of memory, then valArr would also have been emptied, but typing its name in the command window (after the function’s exited) or typing whos shows that it’s still the same as it was before the function was called. Also you will see that totalOfValueArray has been deleted from the list of variables – this also only exists for the duration (or scope of the function) and is deleted once its value has been passed back to the workspace. In this case it’s passed into ans. If the calling statement in the command window were terminated with a semicolon, the return value would still be passed into ans, but this would not be reported in the command window. If the call was instead resVal = TotalValues(valArr) then the “result” of this function (the output argument) would be returned into the variable resVal. A semicolon wold suppress reporting of this, too. One more thing to note is that within the scope of the function, only variable that have been passed into the function and those created within the function can be “seen” by the function. To show this, again run the code (using TotalValues(valArr)) to the point where the line of code is about to be executed, then return to the command window and type whos. You will see that the only thing that exists in the current scope is valueArray. Press press [F10] once to step on and calculate totalOfValueArray and you will see, on returning to the command window and typing whos again that there are just the two variables now that were passed into, and created inside, the function. Step on or continue until the command function is complete and you from another can call to typing whos that the scope of the workspace has again been resumed, with the variables that were there before still there (the value in ans will have been updated) and that were present when within the scope of the function have been deleted from memory. This is true of all layers of functions – if the function you were just inside called another function, that function would not have access to the workspace’s variables or those within the function that called it. Global variables The exception to this rule is that of global variables, but Matlab is slightly odd in its use of global variables. They can be declared somewhere (say, the workspace, or a script or function that calls another function). They can then be shared with the sub-functions that are called form there, but only if they are also declare the same variable name as global within the sub-function. In most programming languages, variables declared as global just tend to be available to all procedures (functions, etc.) regardless of location or need for declaration within the sharing procedure (especially if declared at the declaring a variable at the “top level” of the program). Some languages also have more than one level of “global-ness” to their variables. Alternatively a global variable could be created within a sub-function and later shared with another function “higher up” the function “call stack” once declared in there (but this might be less likely). In any case, the variable needs to be declared, for instance by using a statement like: global testVar; in two separate functions (or other places, like a function and the workspace, with generally nonshared scope) and this then allows those places to get access to the same piece(s) of data, at the same point in memory. These can be large arrays or individual values, like any other variables. An advantage of global variables include the ability to share large arrays between functions without making copies of them in memory, allowing multiple functions to access the data in the same array(s). This can save excessive duplication of data, which, when working with large data sets, can make Matlab run out of memory. While this can happen when sending large blocks of data to functions in Matlab, it is generally more of a problem in older implementations of Matlab. In newer versions it appears that if the array passed to a function is not changed, it represents the same piece of memory (i.e. it is passed “by reference” as can be done explicitly in C), but if the array is changed in any way, a copy of that array is made and the change that was made is applied to the copy of the array. At this point, memory usage could jump up significantly if large data sets are being passed to a function. This is a relatively complex issue and so help should be sought in the case of memory issues. Also, some of the comments just before this “Global variables” section may be somewhat simplistic in their discussion of variables passed to functions, but it is still the case that a variable passed to a function that is then changed does not change the original variable that was passed, but a local copy. Another advantage of global variables is that a large number of variables might be more easily shared between a script, function or the workspace, and a called function, without requiring a long list of input and output arguments in the called function (or the place it is called from). Note also that breakpoints also appear to be held in global memory and so cleared when the clear all command is issued (but not the clear command without the all). Variables in scripts One more comment to make on variables and their scope is that variables in a script are shared with whatever place called them (script, function or the workspace), as a script just represents a collection of commands that are run as if they were run within the location that called the script. Code looping and branching Code looping: for loops To illustrate an example of a code looping construct, you shall use a for loop in the following code. Since the summing part in the function that was just created was the only thing that happened within the function, it was a rather trivial a use of a function. Making a function that created a Fibonacci sequence up to a certain value or up to a certain total value (when all values are summed) would be more useful as it would replace several lines of code in the original script with one function call. Recall that the previous function, TotalValues, only totalled values sent to it, and was really therefore just duplicating the work of the sum function. Also recall that the Fibonacci sequence was just created manually using a set of values (valArr = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144];). A function can be made to automate this so it does not have to be manually created. Make another function as you did before and call it FibonacciSequenceTotalToTerms, in the function name and the file name. Add an input argument, numTerms and an output argument, totalOfSeq. Add in a useful comment for help to report on, then add in the code for the function. The file might end up looking like this: function [totalOfSeq] = FibonacciSequenceTotalToTerms(numTerms) %Total of a Fibonacci sequence up to a certain number of terms. % % This function creates a Fibonacci sequence up to the number of terms % given in numTerms, then totals all of the terms and returns the total. %Pre-allocate the memory for this array. fibSeq = zeros(numTerms, 1); %Allocate the first two values, which are always 1 and 1. fibSeq(1) = 1; fibSeq(2) = 2; %Continue from term three until the end of the array, filling the array %with values that are the sum of the previous two values, as per the %Fibonacci sequence. for indx = 3 : numTerms fibSeq(indx) = fibSeq(indx-1) + fibSeq(indx-2); end %Total the terms in the sequence and return that total value. totalOfSeq = sum(fibSeq); %End of the function (if this is in its own file, with no other functions %or anything else below the last line of code before this, then the end %statement is optional. end Now the usefulness of the function is clearer – by running this function, and sending only one value to it, into numTerms, the code can create a Fibonacci sequence up to this number of terms total the terms and return the result. Even better, once this function is created and checked, you don’t even have to know, or care (as long as you trust the person who wrote it!) what goes on inside – the values are created, added and destroyed again once the function is complete, leaving only the result that you wanted – the total. Run the code by entering, say: >> FibonacciSequenceTotalToTerms(14) And you should get a return value of 1595. Use dbstop in FibonacciSequenceTotalToTerms or manually put a breakpoint on the first executable line then run the code again using the same command, requesting the total to 14 terms. As you can see (hover over these with the mouse), the variable numTerms has accepted the inout argument (the constant value 14), and doing whos will show that to be the only variable in the current scope. Stepping on a line (e.g. [F10]) initialises fibSeq to be a vector that has numTerms rows and 1 column (it could have been the other way around, as you will remember from the section on indexing vectors, as is done in the for loop next). Two more steps sets the first two values in the vector. In the for loop (one of a set of looping constructs), the variable indx is set to take each of the values in turn between 3 and has numTerms (14, in this case). Step into the loop, past the “opening” line of the for loop to the single line within, then before stepping any further, check the value of indx. It should be 3, and it will be used as an index of the vector fibSeq, assigning to fibSeq(3) (the first time through the loop) the value that the sum of fibSeq(3-1) and fibSeq(3-2), i.e. fibSeq(2) and fibSeq(2), the two values before the “current” value. Take one more step and you will see that this value has been assigned. Since Matlab can’t display too many values in the “datatip” (yellow box that pops up when variables are hovered over), if you were using a big data set you could check the values at these positions by selecting one of them in the code, say, fibSeq(indx) and then pressing [F9], which will execute whatever is selected in the command window (a shortcut to selecting, copying, going to the command window, pasting and pressing [Enter]. In this case it should report a value if 3. You could do the same for fibSeq(indx-1) and fibSeq(indx-2), or any other existing variable (in scope). Stepping a few more times shows that the for loop is repeated, and each time execution point is stepped past the end statement, the value of indx is incremented, and so the insertion point for the new value in the vector fibSeq is moved on one (from index 3, to 4, to 5, etc.) and the indices of the two values being added together to make the value entered in that position are also indexed on, so the value entered is always the sum of the two previous values. Stepping on some more shows that the two lines of code that are executed repeatedly are the line inside the loop and the end statement – the opening line is only run once, so if a breakpoint were put on that, the code would only stop once. If the for loop were to be done many times, and it had been sufficiently examined, another breakpoint could be placed on the next statement after the for loop and [F5] pressed, or the cursor could be placed there and the “Run to Cursor” button pressed. Stepping on, the last statement is executed, summing all of the elements in the vector fibSeq and the function is then exited, assigning the answer to ans. If whos is run again, it can be seen that the variables that were used inside the function have been deleted. Code branching: if statements An alternative function that allows the user to find out how many terms it would take to reach, or exceed, a certain total. Since, if an arbitrary total were given, it would not be clear how many terms in a Fibonacci series would be require to reach (or exceed) that total, this code would not be able to give an immediate answer. It would instead have to increase the number of terms in the Fibonacci series, checking the total each time the number of terms was increased, until the total met or exceeded input argument value, then return from the function with the number of terms that met the input criterion. This would require a code branching construct like an if statement, resulting in a function like: function [numTerms] = FibonacciSequenceTermsToTotal(totalOfSeq) %Number of terms required to reach, or exceed a given total of a Fibonacci %sequence. % % This function takes as an input the total of a Fibonacci sequence up to % the number of terms and iterates through a sequence until it is found % how many terms are require to reach, or exceed, that total. The number % of terms is returned in numTerms. %Pre-allocate the memory for this array. It was previously found (using the %function) that the maximum number of terms in these sequences could be %1473 before the sequence reached an "infinite" number (beyond a double %type's upper limit of approx. 1.7977e+308). numTerms = 1473; fibSeq = zeros(numTerms, 1); %Allocate the first two values, which are always 1 and 1. fibSeq(1) = 1; fibSeq(2) = 2; %Continue from term three until the end of the array, filling the array %with values that are the sum of the previous two values, as per the %Fibonacci sequence. for indx = 3 : numTerms fibSeq(indx) = fibSeq(indx-1) + fibSeq(indx-2); %If the required total has been equalled or exceeded, set the number of %terms to the current value of indx, then exit the function. if sum(fibSeq) >= totalOfSeq numTerms = indx; return; %Exits the function immediately. end end end Here the function name has been changed, the input and output arguments swapped to represent the opposite functionality, and an if statement has been added to the for loop. Since the approach here is slightly different, the number of terms (and thus the initial size of the vector holding the Fibonacci sequence) is unknown. A maximum possible size is set, therefore. The maximum size was found using the previous function, increasing the number of terms until the resulting total returned Inf, showing that the total of the sequence was an "infinite" number (beyond a double type's upper limit of approx. 1.7977e+308 – not infinite, but very large). So, numTerms can be initially set to this maximum size (1473), this can be used to size the array and if a total is found that exceeds the total required, the number of terms taken to reach that point can be entered into numTerms and the function can be exited using the return statement (directly, without any more loops being carried out). If a small total is entered, the process can be followed through step by step using debug mode, as before, to show the sequence of commands carried out. If returned Inf is entered, the loop will run to the maximum number of 1473, the value in numTerms remaining unchanged as the if statement is never true, so the code within is not run. If the for loop only needed to be exited within the if statement – maybe some more code needed to be done to finish things off before exiting the function – then a break statement could be used in place of the return statement. This would move to the next line of code after the for loop that the code was currently in. This also works for other looping constructs like the while loop discussed next. Code looping: while loops A while loop is an alternate looping construct that repeatedly executes statements while a condition is true, so it contains both a looping element and a testing element, unlike a for loop, which loops through statements for a fixed number of times, incrementing a variable each loop. The same function can be rewritten to use a while loop: function [numTerms] = FibonacciSequenceTermsToTotal_W(totalOfSeq) %Number of terms required to reach, or exceed a given total of a Fibonacci %sequence. % % This function takes as an input the total of a Fibonacci sequence up to % the number of terms and iterates through a sequence until it is found % how many terms are require to reach, or exceed, that total. The number % of terms is returned in numTerms. % % This function is like FibonacciSequenceTermsToTotal, but uses a while % loop rather than a for loop. %Pre-allocate the memory for this array. It was previously found (using the %function) that the maximum number of terms in these sequences could be %1473 before the sequence reached an "infinite" number (beyond a double %type's upper limit of approx. 1.7977e+308). numTerms = 1473; fibSeq = zeros(numTerms, 1); %Allocate the first two values, which are always 1 and 1. fibSeq(1) = 1; fibSeq(2) = 2; %Continue from term three until the end of the array, filling the array %with values that are the sum of the previous two values, as per the %Fibonacci sequence. indx = 2; while sum(fibSeq) < totalOfSeq %Increment indx (this was previously inherent in the for loop). indx = indx + 1; %Continue finding the total until it is equal to or greater than the %required total. fibSeq(indx) = fibSeq(indx-1) + fibSeq(indx-2); end %Set numTerms to the current value of indx - this is the number of terms %needed to meet or exceed the required total. numTerms = indx; end Here, the while loop can test for whether to continue or not, so the if statement that was inside the for loop can be used instead as the conditional statement that the while loop requires. The while loop, on the other hand, does not inherently increment anything each time it completes a loop, so for this problem, indx is used like a counter that it incremented by 1 each time through the loop in a separate statement (1 is added to its current value and that value is reinserted back into indx). While this kind of loop can be used for this problem, the logic is somewhat reversed compared to the way it was written with the for loop. Since the while loop executes the code within while something is true, but the previous if statement exits the code only if something is false, the logic of the conditional statement is reversed from sum(fibSeq) >= totalOfSeq to sum(fibSeq) < totalOfSeq. The starting value of indx also needs to be 2, rather than 3 in the for loop, as it need to be incremented before the total is calculated, or the check would exit on the total being met or exceeded with a value one greater than required. This is because in the original version the execution goes: add new value > check total > exit if total met or exceeded (at if line) > increment indx and loop (at end line) But if the while loop version went: add new value > increment indx > check total (at while line) and exit if total met or exceeded then the value in indx would be one more than the actual number of terms required to get to the total, as it was incremented after the total was calculated. But if it is incremented before: increment indx > add new value > check total (at while line) and exit if total met or exceeded then the value in indx needs to start one lower than it wold otherwise be, as it is incremented before it’s used in the line that adds a new value into index 3 (on the first iteration). Either this or the first version would have to be used, but 1 subtracted off the final value of indx before setting the return value and exiting the function. If this was not thought through carefully, and tested with a variety of values, this error might have been missed. This is a very common error, where the result is “off-by-one” and is at least slightly related to the “fencepost” error (described here: http://en.wikipedia.org/wiki/Off-by-one_error) – another indexing-type error that is easy to miss. It can be seen, therefore, that the functionality of the for and while looping constructs differs, and that one may be better suited to any particular problem than the other – here it’s seen that workarounds/adjustments have to be made that leave the final code looking less obvious than it might otherwise be, which would require at least some additional commenting. Error checking and testing It can be seen from the issues with the code above that testing you code is essential, and it should be done with a wide range of inputs wherever possible – it’s safer to assume your code is broken until you’ve proved beyond reasonable doubt that it isn’t. To do show how to do some basic testing, Try running the (simpler) function with some other inputs to see how it reacts (the first, FibonacciSequenceTotalToTerms, function). Try to push the code to the limits of the values that might be entered – large values, small values, negative values, integers, non-integers, strings of characters, etc. to see if/where it fails. You will note that only one value can be sent to this function – if you tried to input, say [15 16 17] to get a variety of outputs, it causes the function to fail. It could be altered of course, to allow a vector (or array of any size) to be sent to it if it were changed to allow this. You might like to think of how this could be achieved, and how the results would be sent back (preferably in an array of the same size, with totals in). The function is also limited to only being able to run on input values that are positive integers, of value 3 and above, and there is likely to also be an upper limit, due to the somewhat exponential nature of the output vs. the input. It is important for code that is to be used by others, or reused in many places, that it be robust, and so it is always worth keeping in mind the ways that code might fail and what can be done to alleviate these failures. Testing your code with a wide variety of inputs also allows you to know how best to run that code, what its failure conditions might be and so allow you to limit what is passed to it, or better still, give it some inherent way of “gracefully failing” if a certain input, command, etc. were known ahead of time to cause failure. The code could then avoid running certain commands with fail-prone inputs, perhaps, by branching off to give an error message or flag (an indicatory value in an “error code”type variable) or simply returning something like a zero value in the return variable. Testing for efficiency It is wise to check code for efficiency, too. This is probably not as necessary when there are few operations or small amounts of data involved in a program, but time savings can often be made if an eye is kept on using efficient coding practices. For instance, the FibonacciSequenceTotalToTerms function uses memory pre-allocation to speed up the values being entered into the vector (as mentioned previously), rather than expanding the vector as the code proceeded. The duration of four calls to this function were recorded using tic and toc, a pair of statements that when called in that sequence reports the time elapsed between the calls, creating a simple method for timing chunks of code, thus: >> tic, FibonacciSequenceTotalToTerms(1400), toc ans = 7.2473e+292 Elapsed time is 0.000910 seconds. Here, the total of a large number of terms is found and it is seen that it took 0.9100 ms. The average of four of these (timings do vary somewhat, depending on what the PC is doing) was 0.0011 s. The pre-allocation line was commented out (so it did not run) by placing a percentage sign at the front of the line ([Ctrl][R] automates this on the line(s) that are selected and [Ctrl][T] “un-does” comments one at a time). The file was saved (otherwise Matlab may run the old, unsaved and unchanged version) and run again several times, with the last four times giving an average time of 0.0028 s. While these are both very quick indeed, the pre-allocation method can be seen to be faster, and the differences would be greatly magnified with large datasets. Doing the sum of the entire vector (sum(fibSeq)) every iteration , in the if statement in the second function (FibonacciSequenceTermsToTotal) was also found to be slower than accumulating a total in a separate variable as the sequence was expanded. Code to implement this, in FibonacciSequenceTermsToTotal2, requires a bit more explaining, though and may be less clear, so there may be a trade-off between clarity, brevity and speed. Figures and plotting data Some simple data plotting and visualisation will be discussed next. Simulated data is created in the script CreateSimulatedAcquiredData (in the file “CreateSimulatedAcquiredData.m”). Open that file in the code editor, and you will see that it is created using commands that should already be familiar to you. Time data is created (in variable timeData) that runs from time = 0 s to time = 10 s, with an interval of 0.001 s. This might represent the time intervals that accompany data that have been acquired from a data acquisition device or piece of data analysis code, with a sample frequency of 1 kHz. The data itself is relatively simple and consists of a main sine wave (perhaps from an oscillating piece of machinery, though it could equally well be the voltage across two wires in a piece of electrical equipment, etc.). Since this represents real-world data, there is two “layers” of noise added to the main sine wave, at lower amplitude and higher frequency. A figure is created to plot the data on. This is always a good idea when handling data as it immediately allows you to visualise the data and check it seems as you expect. It is far harder to get an understanding of data just from the values it contains. You should have a look at the help for the plot command, and other commands used in the script. There are also some comments in the file, but the help will give more information in all cases. This shows the basics of plotting data on a 2D plot, and annotating the plot and the figure itself with various labels. Also, make sure you step through the code one line at a time and check that you understand what each line is doing. Once the plot is present, you could also try the text command, which puts text of your making on the plot relative to a point (relative to the values on the axes) that you specify (as X-Y coordinates, on a 2D plot). You could put a label on to say what the peak values, were, for instance, and the line function could allow you to draw a line from the point to meet the text placed on the plot. Also make sure you have a go with the buttons on the toolbar that allow you to zoom into and out of the plot (reset to the original view with a double-click), rotate the plot (makes more sense with 3D plots) put a data cursor on the plot to show a particular value, and various other tools, all of which have help available. There are also several ways in which you can save the plot, including to standard image formats (some giving better output quality / smaller file size than others) and the opportunity to save as a “.eps” file. This is a type of vector image, which is infinitely scalable rather than “jaggy” when zoomed into as with raster graphics, and can result in a file both of much smaller size and much higher quality (especially for simple line-type images, such as the plot shown. Please see the Wikipedia entry on vector graphics if you are unfamiliar with them, which can be found here: http://en.wikipedia.org/wiki/Vector_graphics. Using this kind of image in a report (especially with the use of editors/PDF compilers like LaTeX, etc.) can result in high quality, yet very compact output files (especially good quality PDFs). If inserting into MS Word, “.emf” or other formats might be more appropriate. Experimentation is recommended. Programs like Ghostview can be used to view EPS files. Use of vector graphics and editors/PDF compilers like LaTeX can be a somewhat complex subject, but the end results usually exceed the quality of those produces using “standard” tools such as MS Word, especially when creating larger thesis-type works. Figures can also be saved as “.fig” files – Matlab’s own format that saves all of the current settings of the figure, together with the data within, and allows the figure to be re-opened and edited if required. All of these saving options can be reached using Matlab functions, too, so a piece of code can be written that not only analyses and plots data, but saves it in your preferred format. This can allow standard output formats to be created, which can take the manual labour out of creating multiple figures, and help them to maintain a more uniform look between images, as every aspect can be controlled. You will notice that when the figure was created, using the figure command, the result was placed in the variable figNum. This is a “handle” to the figure itself (there are also handles to parts of it, like the axes within), and allows commands to be used that are directed at the figure. For instance, the command print(figNum, '-depsc', 'TestImg') will “print” that figure to a colour EPS file named “TestImg.eps”, or the option '-dpng' instead of '-depsc' will print to a PNG file instead. There are many more options that allow the setting of resolutions and sizes (especially for for raster images) and much can be found in the full help for the print command (type doc print). The 'Name' and 'Data to save to file' parts shows the use of a property name-setting pair, where the property 'Name', here is set to the string 'Data to save to file'. Properties of “objects” that you have obtained handles to can be fund using the get command, which should be used like this: get(figNum). This will produce a list of the properties associated with that object and the handle to it allows access to these, via the property-setting pair. So looking at the properties for the figure, whose handle is figNum, you might see that the property Color is set to [0.8 0.8 0.8], showing the red, green and blue “channels” of the colour that makes up the background (values going from 0 = none to 1 = full saturation). To set this to a different colour, you could type: >> set(figNum, 'Color', [0 0 1]) which would set the background of the figure to blue. Matlab uses RGB (red, green and blue, in that order) values, usually ranging from 0 to 1 or 0 to 255 to allow colours to be specified. So [1 0 0] would set things, the background in this case, to red, [0 1 0] would set it to green, [1 0.5 0] would set it to orange, etc. A few standard colours can also be used, e.g. 'b' for blue. These are listed in the line colours seen in help plot. Line styles and symbols are also listed. When the command plot(timeData, testData1, 'r'); was issued, a handle to that series of data (the line, series of dots, or similar seen on the plot, depending on the line style, etc.) could also be obtained, e.g. using testData1Hdl = plot(timeData, testData1, 'r');. Again, information on this series (once it’s been plotted and the handle obtained) can be found using the handle name and get: >> get(testData1Hdl) This would return the current settings for this series and then set used, with the handle name and an appropriate property-setting pair to change the series style, markers, line colour, etc., or even the data itself. Getting handles to the series and changing the data through set(handleName, 'xdata', xDataValues); is the best way to change data if the data is to be updated regularly, as in an animation, scrolling through a series of data, or otherwise showing data in a more dynamic manner (rather than plotting the data only once for a static plot). If the plot were repeatedly updated using the plot command, rather than via the series’ handles, the plot can become quite flickery. A smoother animation can be obtained using the handles method. This was especially an issue with older versions, but may also improve plotting in newer versions. Other properties that can improve animation are setting the 'DoubleBuffer' property of gcf, the handle to the figure itself, which can always be used after a figure has created, to 'on' (this allows an off-screen pixel buffer to be assembled and then printed to the screen once the drawing is complete, allowing flicker-free rendering, and setting the 'DrawMode' property of gca, the handle to the figure axes, which can be used after a plot has been made on the figure and so “axes” are present, to 'fast', which speeds up plotting by ignoring the relationships of the objects in three dimensions (e.g. sorting depending on view, etc.). Many other plot types are available as standard, and it is always possible to programmatically construct your own plots, as it is very easy to create 2D or 3D data at points, and “join the dots” to create shapes and wireframe type graphics. Patches can also be created, which represent a filled 2D polygon filled with a colour of your choice, allowing assembly and rendering of 3D surfaces and shapes (see patch, fill, fill3, etc.). Being able to do all of this programmatically and repeatably allows many kinds of rich visualisations to be created. Using the inbuilt functions can give you a useful plot in very few steps, though, and functions like plot, plot3, surf, mesh, etc. should be investigated to see what they can provide. The full help generally gives at least one representative example that can be tested out and investigated. The “2D and 3-D Plots” section in the help is very useful and describes many ways of creating and using these data visualisations, as well as animating them and recording these animations to movies that can be played outside of Matlab. Saving data to files The data is saved in files in a variety of ways in the script SaveSimulatedAcquiredData. These all have their own advantages and disadvantages. It is worth looking up all of the options for these methods of saving in the help. Loading data from files Depending on the method and file type that the data was saved with and into, the re-loading procedure will be different. Mat files can be loaded just using load, but files saved (more manually) to text files and similar will require other, probably more complex methods of loading the data back into Matlab. See functions like fopen, how to use its output arguments (including optional ones), Strings and interacting with users Strings (of characters) act very much like arrays of values in Matlab, but they are rendered as the characters according to their ASCII code. It is important to understand how to concatenate these, convert values to use with strings and assemble them into messages that can be written to files, displayed in plots, or otherwise relayed to users, if meaningful feedback is to be given. Functions such as disp, num2str, sprint, msgbox, input, etc. are important here.