Notes on MATLAB programming

(Earlier versions of this page were titled MATLAB as a programming language)

Jonathan Jacky, Apr -- Aug 2006 begun, unfinished topics end with ..., Mar 2007 fill in some topics, minor tweaks, June 2007 fill in biquad example, fix matlab-numpy link, Mar 2008 Separate Commands section, add plot commands.


I recently learned MATLAB to design and analyze digital filters for a project (also here and here).

You can get a lot of work done in MATLAB without programming. Nevertheless, its programming language has some unusual features, particularly regarding matrices and persistence. It also provides most of the facilities of a conventional language, so you can program in a familiar style if you wish, but you can often do much better if you take advantage of its unique features.

The MATLAB programming language and IDE support an ad-hoc programming style where it is easy to turn the useful parts of an interactive session into a program.

This page is not intended to be a reference or even a summary of MATLAB, for that see the references. Instead, I point out some important differences from other languages, that I expect will be interesting to programmers and useful for newcomers.

REPL, Commands, Program structure, Data types, Matrices, Exceptions, Persistence, Large systems, Alternatives, References

REPL and IDE

Invoking MATLAB usually starts a read-evaluate-print loop (REPL). You type an expression, statement, or command at the command prompt >>, and MATLAB prints the result (if there is one), or executes some side effect such as displaying a graph.

Invoking MATLAB usually starts an Integrated Development Environment (IDE) that includes a window for the REPL, editor windows for writing code, a command history window, a file system browser etc.

Random mouse motions can cause the panels in the IDE to scatter like leaves before a storm. To restore them, use the main panel menu bar: Desktop -> Desktop Layout -> Default.

The REPL makes it easy to do ad-hoc calculations and plotting. The MATLAB programming language and IDE make it easy to turn the useful parts of a REPL session into a program.

You can also run MATLAB without the IDE in a terminal window.

matlab -hPrint command line options
matlab -nodesktop   Run in terminal with no IDE
matlab -r command Start MATLAB, execute command, remain in REPL unless command ends with exit

You create a variable just by assigning to it. There are no variable declarations. You can assign values of different types to the same variable.

Be warned that MATLAB will happily and silently allow you to reassign variables that it initially assigns, such as pi and i. I haven't found any way to define a constant.

Scripts and functions in the filesystem are loaded implicitly, just by naming them. There is no command to load or import code. The load command is used for persistence.

Three dots ... at the end of a line continues the command on the next line, like backslash \ in the Unix shells or Python.

An optional semicolon ; at the end of a command is not a a terminator or separator. Instead, it suppresses printing the result. You often want this, especially when the result is some huge array.

Identifiers are case-sensitive. A is different from a, etc. It is confusing that help output shows function and command names in capitals. If you type them in that way, they will not work.

Array indexing begins at 1, not 0 as in most programming languages.

Use single quotes for strings: 'abc', etc.

You can't use a hyphen - in an indentifier. MATLAB thinks it's a minus sign. Use an underscore _ instead.

The variable ans stores the value computed by the last command (the "answer"), so you can use it in the next one.

You can use wild cards in variable names in commands where that makes sense, for example whos x* and clear x*.

Commands

Here are some useful commands for interacting with the REPL. There is a much larger command summary here.

Many commands have several variants with the same name but different argument lists and return values, so it is a good idea to consult help about any command you use.

ver Print information about version and license, including all installed toolboxes
help command Print information about command (including functions and scripts).
which command Print full path to source file for command.
type command Print source code for command.
lookfor com Print list of commands whose name or brief description contains the string com.
help + (or any other operator) print information about all operators and special characters.
 
format compact Print fewer blank lines, to fit more on the screen.
format long Print lots of digits in results, format short for few.
 
A = 2048 Assign scalar 2048 to variable A
t = 0:0.1:2*pi Assign vector [0.0 0.1 0.2 .. 6.2 ] to variable t
y = A*sin(t) + A Assign vector of function values to variable y. Here *, +, and sin are vectorized.
y Print vector y
 
who List all user-defined variables
whos List all user-defined variables, along with their sizes and types ("classes")
clear all Remove all user-defined variables, to avoid confusion from previously assigned values.
 
plot(y) Plot values of y as a function of index (in this example x axis ranges from 1 .. 63)
plot(t,y) Plot values of y as a function of t (here x axis ranges from 0.0 .. 6.20)
plot(y, sqrt(y)) Plot values of sqrt(y) as a function of values of y (here x axis ranges from 0.0 .. 4096.0)
plot(t,y/100, t,sqrt(y))  Plot both y/100 and sqrt(y) as functions of t on the same plot
 
figure Create new figure to show output of subsequent plot commands, to preserve previous figure.
hold on Make subsequent commands plot on the same figure, without clearing plots already displayed there.
h = figure Create new figure, return figure handle h.
figure(h) Make figure h the current figure (or just bring figure h to the top using the window manager).
close(h) Delete figure h.
close all Delete all figures, to unclutter the screen.
 
!command Execute command with system command interpreter (not MATLAB).

Program structure

M-files, Scripts, Functions

M-files

MATLAB source code must be stored in files with the .m extension, called M-files.

Every M-file defines one MATLAB command (a statement or a function). The name of the command is the file name (without the .m extension). When you invoke a command (at the REPL or in another M-file), MATLAB searches a path for an M-file with that name, and executes it. There is no separate command to import or load an M-file.

You can't use a hyphen - in the name of an M-file. MATLAB thinks it's a minus sign. Use an underscore _ instead.

It is the convention that the first comment line in command.m has the form

  %COMMAND one-line description of command ...

for example

  %BIQUAD make cascaded biquad filter, return coeffs for 2nd order sections

The IDE file browser displays this line, and some REPL commands use it:

help command   Print first block of comment lines in command.m
lookfor com Print first comment line in each M-file whose name contains the string com.

Functions local to an M-file with @ ...

There are two kinds of M-files, scripts and functions.

Scripts

A script defines a command with no arguments and no return values. It is just a sequence of MATLAB commands (and comments). Invoking a script executes those commands, exactly as if they were typed at the REPL (or invoked in the script that invoked the command).

All variables in a script are global; they can be used and assigned in the REPL session (or script) that invoked the script.

MATLAB encourages an ad-hoc programming style where you first experiment by typing commands at the REPL, then create a script by saving the sequence of commands that worked. The MATLAB IDE supports this by providing a command history window, from which commands can be cut and pasted into an editor window.

Functions

A function defines a command that may take arguments and return values. Here are the first few lines of biquad.m:

    function [Hsosm,sosm] = biquad(bd,ad,frac_bits,gain)
    %BIQUAD make cascaded biquad filter, return coeffs for 2nd order sections
    % ... other comment lines describe inputs, outputs, etc.  ...
    H = dfilt.df2(bd,ad);
    Hsos = H.sos;
    sosm = Hsos.sosmatrix;
    ... more code follows ...

The name of the function must be the same as the file name. Notice that there are no data types mentioned in the declaration.

Functions can return multiple values, as in the previous example. That function could be called like this:

    >> bd = ...
    >> ad = ...
    >> [Hsosm,sosm] = biquad(bd, ad, 14, 1.0)

The brackets on the left hand side of this assignment might suggest that there is a tuple data type, but apparently there is no such thing; this is special syntax for function return values only. In general, [n,x,s] = ..., where the right hand side is not a function call, does not work.

There is no return statement. After the last statement in the function executes, the function exits and the values of all the variables whose names appear on the left side of the function declaration are returned.

Variables in a function are local.

MATLAB encourages an ad-hoc programming style where it is easy to turn a script (or part of a REPL session) into a function. Simply add a declaration at the top that defines the name and identifies which variables are the parameters and which store the return values.

You can ignore returned values. It is not an error to assign fewer variables than the function returns, or to assign no variables at all.

Functions can have optional arguments. Within each function you can use nargin, the number of arguments the function was called with, for example biquad.m (above) contains

    ...
    if nargin < 3
        frac_bits = 14;  % default
    end
    ...

There are no keyword arguments. MATLAB functions often achieve the same effect by using pairs of optional arguments, where the first of each pair is a string (the keyword), and the second is the value.

Function arguments with @ ..., earlier scheme with strings ...

Function names can be overloaded, with different parameters and return values ...

Vectorization requires care. The problem seems to be that the if statement is not vectorized - apparently if always treats the conditional expression as a scalar. If matrix elements are subject to conditionals, so that different elements might take different paths, this is the one circumstance where you must iterate. ...

Data types

MATLAB calls data types "classes". The whos command shows the classes of all of your variables.

There are no scalar classes. Scalars are a special case of matrices: matrices with one element.

Numbers, Booleans, Strings, Objects

Numbers

All numbers are stored as double-precision floating point values. Usually, many more digits are stored than are printed.

The functions round, floor, ceil, and fix return the integer nearest to a number by various criteria.

Complex numbers are entered (and printed) as in 1 + 2i (or 1 + 2j). Extract the components of a complex number with the functions real and imag, find the magnitude and phase with abs and angle.

The variables i and j are initially assigned (by MATLAB) to the imaginary constant 0 + 1i. This can be confusing because you (or scripts you use) often assign them to something else. Use 1i instead.

There is an initially assigned variable pi but not e. Use exp(1) instead.

Booleans

There is no Boolean type. MATLAB documentation refers to the logical (not Boolean) values 0 (false) and 1 (true), which are returned by logical operations.

Any nonzero value is interpreted as true when it appears as an operand of a logical operation.

Strings

MATLAB is not known for text processing, but it has a string data type. The command lookfor string shows what functions are available.

Use single quotes for strings: 'abc'

Strings are used in printed output, and to put labels and captions on graphs.

There are fprintf and sprintf functions like in C, with the usual format strings, escape characters, etc. However, if there is an array argument, the corresponding format string is applied to every element, printing out the whole array.

Printing large arrays, with control over the layout of rows and columns, is one of the rare MATLAB operations where I have found it helpful to code loops.

Strings are often used as symbols. Many functions use particular strings as arguments to select options. For example, the gensig signal generator function uses the strings 'sin', 'square', or 'pulse' to select the waveform type.

eval ...

Strings are actually 1-dimensional arrays of characters, characters are 1-element arrays. All the usual matrix operators apply.

Handles

Plot handles ...

Function handles ...

Objects

Objects and dot notation ...

Examples from filter toolbox ...

Matrices

Vectorization, rows vs. columns, constructors, accessors, assignment

An array is called a matrix. A one-dimensional array is a vector. Matrices and vectors are central in MATLAB; most of the unusual features in the language concern them. They are very easy to work with. It is rarely necessary to code loops in order to use them, as we shall see.

MATLAB itself uses arrays wherever it can. Strings are vectors of characters. The ranges in iterations are arrays. In a loop that begins for x = v ..., the index variable x iterates over the elements of vector v; in for x = A ..., x iterates over the columns in the matrix A. (But loops appear only rarely in MATLAB programs).

Vectorization, array and matrix operations, reductions

Many operators and functions are vectorized: they work on every element in a vector or matrix. It is not necessary to use any "map" function to achieve this. For example, assign x = pi/2, then sin(x) evaluates to 1, as usual. But also assign v = [ 0 pi/6 pi/2 ], then sin(v) evaluates to [ 0 0.5 1.0 ].

Some MATLAB statements are also vectorized. The statement fprintf('%8.3f', A) prints every element in the matrix A with the specified format.

Some binary operators are applied element-by-element in the obvious way. For example, if A and B are matrices, the sum A+B is the matrix of their element-by-element sums. This requires that A and B have the same number of dimensions and the same size in each dimension. Otherwise, this expression raises the error Matrix dimensions must agree.

Operators that work element-by-element are sometimes called element-wise operators, pointwise operators, or array operators.

Some binary operators are not simply applied element-by-element. Instead they have their traditional meaning from mathematics. For example, * is matrix multiplication and ^ is matrix power. These are called matrix operators to distinguish them from the element-by-element array operators.

For every matrix operator, there is also a corresponding element-wise array operator. For example, the array operators for multiplication and power are .* and .^ (notice the leading dot).

When one of the operands is a scalar, you do not have to use the array operator. For scalar c, c*A (or c+A etc.) computes the products (or sums etc.) element-wise. In this context, MATLAB treats c as a mathematical scalar, not a one-element matrix (which would have the wrong size for this matrix multiplication).

Some functions are reductions that compute a scalar from a vector. They include sum, prod, max, min, mean, and std (standard deviation). Reductions applied to 2-D matrices return a vector of the results of applying the reduction to each column.

Relational and logical operators can also take matrix operands. For example, A > 10 or A > B etc. evaluates the Boolean expression element-wise, and returns the matrix with the logical values 1 (true) at the elements where the expression is true, and 0 (false) elsewhere.

The Boolean reductions all and any act as logical quantifiers; they return 1 or 0 (true or false) to indicate whether all or any of the elements are nonzero (true).

Also, find(A) returns the vector of linear indices of nonzero (true) elements in A, and find(A > 10) etc. returns the vector of indices where the Boolean expression is true. The vector of indices can then be used to access or update those matrix elements.

The command help * (or any other operator symbol besides *) prints information about all the matrix and array operators.

Vectorization, array and matrix operators, and reductions contribute to making loops mostly unnecessary.

Dimensions, size, rows vs. columns

Scalars are matrices. Every scalar can be treated as a matrix of one element, with as many dimensions as needed in context. For example, assign a = 42, then evaluate a(1), a(1,1), a(1,1,1) etc. Therefore, no special operator or function is needed to extract a scalar from a one-element matrix, or to concatenate a scalar to a vector.

There are two kinds of one-dimensional arrays. Like mathematics but unlike most programming languages, MATLAB distinguishes between row vectors and column vectors. Built-in functions and toolboxes use the conventions of the application domain. For example, time series are column vectors, polynomial coefficients (including digital filter coefficients) are row vectors, and polynomial roots are column vectors.

Even vectors are considered to have two dimensions: row vectors are 1 x N matrices, column vectors are N x 1 matrices, for example try v = [ 1 2 3 ] then size(v).

The distinction between row and column vectors is significant for some operators and statements. For example, given the 1 x N row vector vr and the N x 1 column vector vc, vr*vc is the inner product or dot product, a scalar, but vc*vr is the outer product, an N x N matrix.

The matrix transpose operator, apostrophe ', creates a row vector from a column vector and vice versa. Given row vector vr, the assignment vc = vr' creates column vector vc.

The function application ndims(A) returns the number of dimensions in matrix A, and size(A) returns the size of each dimension, in an array of length ndims(A). The reduction prod(size(A)) returns the total number of elements. The index of the first element in each dimension is 1 and the index of the last element is end.

Constructors

Construct row vectors using spaces or commas: vr = [ a b c ] or vr = [ a, b, c ]. Construct column vectors using semicolons: vc = [ x; y; z ]. Combine both to construct matrices: A = [ a11 a12; a21 a22 ].

The entries in matrix constructors can be expressions with scalar or matrix values. You can use these constructors to build up large matrices, concatenate matrices, append scalars to vectors, etc.

The functions ones, zeros (note spelling), and random construct matrices where all the elements are 1, 0, or values drawn from a specified random distribution. Consult help about specifying sizes, etc. These functions can be used to pre-allocate arrays in order to use storage efficiently.

Range expressions (using the range operator, colon :) construct vectors, given an initial value and a final value: v = 1:10. Range expressions can include an optional increment: v = 1:2:10 and can use fractional values: v = 0.3:-0.15:-0.45. Range expressions are frequently used to code loops: for i = 1:n ....

The variety of constructors contributes to making loops mostly unnecessary.

Accessors

Use subscripts to access scalar matrix elements: x = A(i,j).

Indexing begins at 1, not 0 as in most programming languages.

The index of the last element in a given dimension is end. You can use it in expressions: v(end - 1) etc.

Use ranges to access sub-matrices: B = A(k:l,m:n).

Subscripts and ranges can be built from any integer-valued expressions. When ranges are used as accessors, they cannot include fractional values.

A range operator without operands ranges over all the accessible elements; vr = A(3,:) accesses the entire third row.

Notice that : is an abbreviation for 1:end (but i: or :j is not allowed).

A vector of indices v([i,j,k]) returns the vector of elements at those indices, the same as [ v(i) v(j) v(k) ]. (Using ranges as accessors is a special case of this). Recall that the find function returns a vector of indices.

Use a single linear index as in A(3), A(3:7), or A(:) to access any matrix one element at a time, as if it were a vector, with the elements indexed by row first (scanning down columns), so A(1) is A(1,1), A(2) is A(2,1) etc. Also, A(:) is the entire matrix flattened to a column vector.

The variety of accessors contributes to making loops mostly unnecessary.

Assignment and mutability

Matrices are mutable. You can assign new values to individual elements, sub-matrices, and selected elements by using indices, ranges, or vectors of indices: A(i,j) = x, or A(i,:) = v, or A([i,j,k]) = [ x y z ] etc.

Matrices are mutable, but most matrix operations return a new matrix, rather than updating their operands in place. For example, A' or c*A etc. does not change A. This makes it easy to program in a functional style.

Assigning a matrix to a variable creates a new copy of a matrix; it does not create an alias. The copy can be updated without changing the original: after A = [ 1 2 3 ] then B=A then B(2)=4, the matrices B and A differ. This is unlike many programming languages, where assigning an array to a variable creates an alias, and updating either A or B would change both.

You can grow a matrix by appending in a constructor, or assigning to new elements (with higher indices) but that can be quite slow. It is much faster to pre-allocate storage by initially constructing a matrix of the needed size, if that is known.

Persistence

You can easily save and restore the state of MATLAB session: the variables and their values.

You can save and restore individual matrices ...

load, store, dlmwrite ...

Exceptions

Warnings that print messages vs. errors that stop execution ...

Large systems

Quantum optics toolbox ...

MATLAB itself ...

Alternatives

Octave, open-source MATLAB clone. How complete? ...

NumPy, IDL, PDL, etc. have MATLAB-like array operations ...

References

Command summary (NumPy also)
http://mathesaurus.sourceforge.net/matlab-numpy.html

I learned what I know about MATLAB by reading (a little) in these sources, in roughly this order.

James H. McClellan, Ronald W. Shafer, and Mark A. Yoder, DSP First: a Multimedia Approach, Prentice Hall 1998 (especially, but not only, Appendices B and C.1)

Sze M. Tan, A Computational Toolbox for Quantum and Atomic Optics
http://www.qo.phy.auckland.ac.nz/acols98b.pdf

Some useful Matlab tips (some tips but mostly links)
http://www.cs.ubc.ca/~murphyk/Software/matlab_tips.html

Getting Started with MATLAB
http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/getstart.pdf

Signal Processing Toolbox User's Guide
http://www.mathworks.com/access/helpdesk/help/pdf_doc/signal/signal_tb.pdf

MATLAB Programming
http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matlab_prog.pdf

Daniel T. Kaplan, Introduction to Scientific Computation and Programming, Brooks/Cole 2004 (teaches MATLAB as a general-purpose programming language)

Matlab tips and tricks (haven't read this yet, but looks useful)
http://www.ee.columbia.edu/~marios/matlab/matlab_tricks.html

Mathworks online documentation
http://www.mathworks.com/access/helpdesk/help/helpdesk.html
http://www.mathworks.com/support/tech-notes/list_all.html
http://www.mathworks.com/company/newsletters/digest/pastissues/index04_06.html, for example sept01/matrix.html