# Matlab by Example

This document attempts to introduce you to matlab by leading you through a useful task, stopping off for some sightseeing on the way. If instead you want a tutorial, then Mathworks' own is as good as any. Some other references are at the end of this document.

Suppose you have a text file of data - 3 numbers per line - from an experiment where values have been obtained at various 2D position. A typical text line is

45 77 12.78

which means that at (45, 77) the value's 12.78. This example will show you how to

- Read the values into Matlab
- Eliminate outliers and duplicates
- Show the z values as a 2D surface
- Find a best-fit mathematical function for the data
- Save the resulting data
- Make a movie

## Read the values into Matlab

First download the data file into a file called `data.txt`. Start matlab and use `cd` to **c**hange **d**irectory (i.e. change what folder you're in) so that you're where the data file is. For example, if the file is in a folder called `Downloads`, type `cd Download` in Matlab

Type

load data.txt

Typing

whos

will show you that there's now a variable called `data`

Type

data

and you'll see the values.
`data` is a matrix. In fact, just about everything in matlab is a matrix,
so once you can create and manipulate them you're well on the way to mastering matlab.

### Matrix creation

Here are some ways of creating matrices. Note that you don't have to explicitly create matrices before using them, and you needn't specify their sizes - they can grow on demand.

`x=[2 6 7]`- create a row vector`x=[x 8]`- add another element to`x``x=[2 ; 6 ; 7 ]`- create a column vector`x=1:6`- create a vector with elements 1, 2, 3 ...6`x=1:0.5:6`- create a vector with elements 1, 1.5, 2, 2.5 ... 6`x=linspace(1,6,11)`- create a row vector with 11 equally spaced elements running from 1 to 6`x=ones(4,5)`- create a matrix full of 1s with 4 rows and 5 columns`x=1:3; y=4:6; z=[x y]`- join 2 vectors`x=1:3; bigx=repmat(x, 2, 3)`- replicate`x`twice vertically and 3 times horizontally

### Matrix manipulation

Before we continue, let's try some matrix operations.

`size(data)`- gets the number of rows and columns. Note that it returns a matrix called`ans`. We could instead dos=size(data)

to put the answer into`s`. Now`s(1)`(the 1st element in the array) will be 106 and`s(2)`will be 3. To suppress screen output, put a semi-colon on the end of the line.`data(:,1)`- shows the 1st column.`data(1,:)`shows the 1st row.`data(:)`returns all the elements as a single column.`data2=data+5`- returns a new array whose elements are each 5 more than`data`'s elements.`data+data2`- adds the matrices`data'`- returns the transpose of`data`. Typing`size(data')`shows you the size of the transpose`data' * data`- multiplies a 3x106 matrix by a 106x3 matrix to give a 3x3 matrix.`data.*data2`- (note the dot) multiplies each element in`data`by the corresponding element in`data2`. The matrices need to be the same size.

### Matrix functions

Matlab has many functions. To find out more about a particular function, type `help` followed by the function name.

`sum(data)`- sums each column.`mean(data)`- finds the mean of each column.`mean(data(:))`would find the mean of the whole matrix (though that's not useful to us in this situation).`max(data)`- finds the maximum number in each column

## Eliminate outliers and duplicates

Any experimental data is likely to contain erroneous or duplicate data.
Here we'd first like to eliminate duplicate rows. Whenever you want to find out
how to do something and you can think up a keyword you can use
`lookfor`. So

lookfor duplicate

will look for routines whose descriptions mention "duplicate". Alas there are none. So let's try this

lookfor unique

This displays several routines. Typing

help unique

tells us the details. So type

udata=unique(data,'rows');

to create a new matrix with unique rows. It also sorts the rows. Sometimes we don't want that, but it's ok here.

Let's suppose that all z data less than -5 is bogus. We'll set
these values to 0. One way to do this would be to use a `for`
loop checking each value much as in a language like Fortran. Here's the code to
do that

but there's a quicker way, using the `find` command.

toosmall=find(udata < -5)

will return the locations of all the elements in `udata(:)` that are less than 5. Doing

udata(toosmall)=0

will set all those elements to 5. We could do this all in one line

udata(find(udata < -5))=0

`udata` should now have 101 rows.

### Creating commands

Until now you've been typing commands on the matlab command line. If you
put these commands into a file into a file (called `mycommand.m`,
say - the suffix is important), then typing `mycommand` will run the commands in the file.
Any text in the file to the right of a `%` character is ignored. From
now on you might prefer to create a file, add new commands to it and
run the file. Use `clear` to clear out variables before re-running. Use `close` to close all graphics windows. Everything so far could be
done using the following file

Much of Matlab is compiled code, though there are many `*.m` files too.
If you type

which load

(asking where the `load` command is) you'll see that `load` is `built-in` (it's compiled code) but

which flipud

shows the location of `flipud.m` which you can look at by typing `type flipud`. It's only 4 lines of code - see if you can understand it.

## Show the z values as a 2D surface

Let's first create some vectors to aid code legibility

Matlab has several ways to plot 3D data. First try

plot3(xvalues, yvalues, zvalues ,'.')

Note that `plot3` (like nearly all matlab commands) can cope with
vector arguments.
The final `'.'` puts a dot at each data point.

The results aren't easy to visualize. We'd
like a surface. For that we need to do more work because some of the more useful matlab commands require the data to be on a regular grid.
You can prepare this data for use with the `griddata` command

% First define a regular grid. % We'll set up a 20x20 grid steps = linspace(-1,1, 20); [XI,YI] = meshgrid(steps, steps); % XI and YI will both be 20x20. XI contains the x-coords of each point % on this new grid, and YI contains the y-coords. % now interpolate - find z values at each of these grid points ZI = griddata(xvalues, yvalues, zvalues,XI, YI); % Display this as a surface surf(XI,YI,ZI); hold on ; % this stops the next command clearing the graphics window % plot the original data too plot3(xvalues, yvalues, zvalues,'.')

You should get a figure like this

Note that during interpolation, matlab warned that the data contained lines that have different z values for the same (x,y) point. It used the mean z in such situations.

## Find a best-fit mathematical function for the data

We might already have in mind a model for the data. For this data, the z values peak at (0.0) and seem to depend on x periodically, so I'm going to try to fit the data to a formula like this

A1*sin(A2*x) + A3./sqrt(0.5+x.^2 + y.^2);

and I'd like to find constants A1, A2, and A3 such that the values of this expression are
as close to z as possible.
Matlab has several optimisation routines. I'm going to use `lsqnonlin` (which you might not have - see later). To use this we have to set the problem
up appropriately. We need to specify initial conditions and an expression
to minimize. The optimisation functions are rather technical, so I won't
go into details - they're online.

a0=[10 10 10 ]; % initial conditions for A1, A2 and A3 - just a guess % the next line uses 'anonymous functions'. It sets up a function f % that takes a (containing A1, A2, A3) as input. % It's this function that will be minimized f=@(a) a(1)*sin(a(2)*XI) + a(3)./(0.5+sqrt(XI.^2+YI.^2)) -ZI; % here we can choose options for the optimisation routine. options=optimset('Display','iter'); % now we optimise. The returnedafvector will contain the A1, A2, and A3 we want af=lsqnonlin(f,a0,[],[], options)

When I run this I get

Is this a good fit? Let's see

Ztheoretical= af(1) * sin(af(2)*XI) + af(3)./(0.5 + sqrt(XI.^2+YI.^2)); max(Ztheoretical(:)-ZI(:)) mean(Ztheoretical(:)-ZI(:))

Let's also see this visually. We'll add the theoretical results as a grid. We'll also add titles, and save the result in a jpeg file.

close; % clear the graphics surf(XI,YI,Ztheoretical); title('best fit'); xlabel('x'); ylabel('y'); colorbar; % add a color-coded key to z values print -djpeg -zbuffer demo1.jpg

The result should be something like this

which isn't a perfect fit, but there was noise in the data.

### Handle Graphics

We've been changing the figure using commands. We could also have used the menus to change many of these properties. Underlying both of these methods is a third, more direct way. Each part of the figure and the graphs in them has a unique identity number (its "handle") with a set of properties. Type

get(gca)

and you'll **g**et the list of properties for the **c**urrent **a**xes.
To change any feature you can get its handle
then use the `set` command to change a property. For example, to change
the title we can use

titlehandle=get(gca,'Title'); set(titlehandle,'FontSize',20);

### Toolboxes

Matlab has many add-ons called Toolboxes. `lsqnonlin` belongs to
the Optimisation Toolbox. If you haven't paid for it, you won't have it.
Typing

ver

will show you what's installed, though even if a toolbox is listed, you may not be able to run its routines (the license may have expired, for example).

Fortunately, there are many add-ons that are free. The MATLAB Central: File Exchange has thousands of files to download.

## Save the resulting data

Suppose we wanted to store the cleaned, interpolated values in `XI`, `ZI`, and `ZI`. We could do `save XI YI ZI 'newdata.txt'` but that would save all the elements in the matrices. If we wanted to save in a file with the same form as the original we need to use lower level commands which are like those of the C language.

fp=fopen('newdata.txt','w'); [rows,cols]=size(XI); for i=1:rows for j=1:cols fprint('%f %f %f \n', XI(i,j), YI(i,j) Ztheoretical(i,j); end end fclose(fp);

## Make a movie

A figure can be saved into a 'frame' and the frames put together to make a movie. In the code below the viewpoint is changed for each frame. I've forced each frame to be the same size (436 by 344) because otherwise it's hard to make a movie from them.

i=1; for az=0:-10:-90 a=viewmtx(az, 30, 60+(az/2)); view(a); M(i)=getframe(gcf,[0 0 436 344]); i=i+1; end viewmovie(M);

### Octave

octave is free, and is
similar to Matlab. The code in this example works on linux with octave 3.0.0 until
the `griddata` line. With a different operating system, a newer version of Octave, or extra Octave modules you may have more luck!