In the last lab, we started using MATLAB without even thinking about what we were doing. It wasn't too hard to get started, but now we need to learn a few facts and rules, so that we can
We never thought about what goes on when we say
x = 1to MATLAB. In a programming language, you would probably have to declare that x was a variable, and that it had a particular arithmetic type (say integer or real or complex) and that it was a scalar (just one number), or a vector (a string of numbers), or an array (a table). We did none of that.
What MATLAB actually does is to store everything as a double precision complex array. This means that the value stored in x has about 14 digits of accuracy, that it can be set to a complex value if we like, and that x can be adjusted to accommodate a string or table of values instead of just one value.
Exercise: Verify that a MATLAB variable has about 14 digits of accuracy by computing the machine epsilon, also called the machine accuracy or unit round. The machine epsilon is the smallest positive number that can be added to 1 and produce a result larger than 1. Assume that epsilon is a power of 2, and initialize it to 1. What do you have to test to see whether to divide by 2?
epsilon = 1; while (what test goes here?) epsilon = epsilon / 2; end epsilonIf you aren't careful, you will get a result that is slightly too small. You can test your value of epsilon in two ways:
( 1 + epsilon ) - 1
Suppose that we stored the machine epsilon example above in a file called eps.m, and then we typed
epsEverything would seem fine, and we'd even get the right answer. Now suppose we went into our eps.m file and added a line that printed out the value of epsilon at every step. When we rerun the code, the added printouts never show up! Why? Because MATLAB has been ignoring the file the whole time! And why is that? Because you have to remember how MATLAB works. If you type in a single word fred, then MATLAB looks for:
To see what variable names you've defined, type
whofor a short list, or
whosfor a lot of information.
Names of built in MATLAB constants include:
We said that MATLAB treats all its variables as though they were vectors (or matrices, or general arrays, but we won't talk about that yet!). So MATLAB considers the variable x we defined earlier to be a vector of length 1. How would we define a longer vector?
The important thing to remember is, you don't have to declare the size of your variable; MATLAB decides how big the variable is when you try to put a value in it. The easiest way to define a vector is to list its values inside of square brackets, and separated by spaces or commas:
x = [ 0, 1, 3, 6, 10 ]MATLAB has a special notation for generating a set of equally spaced values, which can be useful for plotting and other tasks. The format is:
start : increment : finishor
start : finishin which case the increment is understood to be 1. So we could define the even values from 10 to 20 by:
evens = 10 : 2 : 20
Sometimes, you'd prefer to specify the number of items in the list, rather than their spacing. In that case, you can use the linspace function, which has the form
linspace ( start, end, number );in which case we could generate some even numbers with the command:
evens = linspace ( 10, 20, 6 );
Another nice thing about MATLAB vector variables is that they are flexible. If you decide you want to add another entry to a vector, it's very easy to do so. To add the value 22 to the end of our evens vector:
evens = [ evens, 22 ]and you could just as easily have inserted a value 8 before the other entries, as well.
Even though the number of elements in a vector can change, MATLAB always knows how many there are. You can request this value at any time by using the length function. For instance, if I now type:
length ( evens )I might get the value 7 (the 6 original values of 10, 12, ... 20, plus the value "22" that I tacked on later).
If you want, it's easy to start with a vector containing no elements at all, and add elements later. You just have to let MATLAB know that the variable starts out "empty":
squares = [] for i = 1 : 10 squares = [ squares, i^2 ]; end
To specify an individual entry, you need to use index notation, which uses "round" parentheses enclosing the index of an entry. The first element of an array has index 1 (as in FORTRAN, rather than C). Thus, if I want to alter the third element of evens, I could say
evens(3) = 7
By the way, the index notation can also be used to refer to a set of elements of the array. With the start:increment:finish notation, we can refer to a range of indices. Thus, we could halve all the elements with even index:
evens(2:2:6) = 0.5 * evens(2:2:6)
Exercise: Suppose I give you a vector x. Write a program that prints out the sum of all the entries in x. You will probably want to use a for loop:
for start : finish statements endNow use the start:increment:finish notation, and modify your program slightly, to print out the sum of the odd elements in the array (that is, the elements in entries 1, 3, 5, and so on).
Suppose we want a table of integers from 0 to 10, their squares and cubes. We could start with
n = 0 : 10but now we'll get an error when we try to multiply the entries of n by themselves.
n2 = n * nRealize that MATLAB thinks you're dealing with vectors, and the default multiplication operation with vectors is vector multiplication. In order to do element-by-element multiplication, we need to place a period in front of the operator:
n2 = n .* nNow we can define n3 in a similar way, and print out our values using a loop that indexes the arrays. Actually, let's just print the even values:
for i = 1 : 2 : 11 fprintf ( "%i %i %i\n", n(i), n2(i), n3(i) ) endNotice here that the for loop can also use the same start:increment:finish notation we've seen elsewhere.
Instead of using fprintf, we could have have tried printing out the values using the line
n(i), n2(i), n3(i)or
[ n(i), n2(i), n3(i) ]both of which are easier, but uglier.
Watch out when you use vectors. The multiplication, division and exponentiation operators all have two possible forms, depending on whether you want to operate on the arrays, or on the elements in the arrays. In all these cases, you need to use the PERIOD notation to force elementwise operations. For example, we could also have computed n2 using the exponentiation operator as:
n2 = n .^ 2These problems never come up with addition or subtraction; nor do they occur with division or multiplication by a scalar.
How come we didn't have this problem in the square root code of the last lab? We were able to write terms like x * x and never got a complaint.
MATLAB has loads of built in functions we can use to construct formulas, including
Naturally, many of the functions we will be looking at will be polynomials. Unfortunately, the elementwise operation notation can become pretty cumbersome for these formulas. For instance, to specify the polynomial, x^3-2*x^2+x, we must type something like:
x = 0 : 0.5 : 10;We have to be careful about both the exponentations and the multiplications. Notice that where I multiply by 2, I don't have to use the elementwise operator!
y = x.^3 - 2 * x .* x + x;
Because polynomials come up so often, there's a special command called polyval which evaluates a polynomial given a vector of coefficients, and a vector of evaluation points. For instance, we could have written:
x = 0 : 0.5 : 10;Or it might even make sense to save the polynomial coefficients in a vector first:
y = polyval ( [ 1, -2, 1, 0 ], x );
c = [ 1, -2, 1, 0 ];
x = 0 : 0.5 : 10;
y = polyval ( c, x );
A very useful command for polynomials is the roots command, which returns a vector of the (approximate) roots of a polynomial based on its coefficients:
c = [ 1, -2, 1, 0 ];Following these two commands, what would be the result of:
x = roots ( c);
y = polyval ( c, x );
We've already used an M file, root.m, to carry out a task for us. We put some MATLAB commands in it, stored it in our MATLAB directory, and then we could access the file by typing root.
One special use of an M file is to define new functions, that can be named, and then evaluated just like abs(x) and other familiar functions. To do so, we simply have to write a special kind of M file, with the right name and the right first line, and then calculate the value of the function based on the input.
For instance, we might want to define a function which, for any input x, is equal to sin(x)/x. First we need to pick a name for this function - let's try calling it slinky. Now we need to create a file called slinky.m, and here's what goes inside it:
function result = slinky ( x ) if ( x == 0 ) result = 1; else result = sin ( x ) ./ x; end
Exercise: set up the slinky function. Evaluate it at x = 0, and at x = pi. What values do we expect there? Make a table of its values from -2 to 2 in increments of 0.25.
Discussion: Does the value of slinky(pi) bother you? It should be zero, right? For that matter, you should check the value of sin(pi), which is not zero either. In "the real world" it's zero, and in Mathematica it is too. But MATLAB is a numerical calculator, not a symbolic one. In MATLAB, not only is sin(pi) not zero, but pi isn't pi and sin isn't sin.
The reason we had to jump into vectors today is that we want to do graphics. To make our simple graphs, we want to define vectors x and y of independent and dependent data. Doing a sine graph makes it look easy:
x = 0 : 0.1 : 10;
y = sin ( x );
plot ( x, y )
Exercise: Plot the slinky function over the domain of -10 to 10.
Now, let's try to plot the polynomial, x^3-2*x^2+x:x = -2 : 0.1 : 4;
y = x.^3 - 2 * x .* x + x;
plot ( x, y )
Suppose we also want to plot the x axis, to see where this polynomial is zero. We need the hold on command, which keeps the output of previous plot commands in the plot box, followed by a plot command where we give the vectors x and y explicitly:
hold onOf course, the hold off command will cause the next plot command to start with a fresh screen.
plot ( [ -2, 4 ], [ 0, 0 ] )
Exercise: On the same graph, plot the functions
plot ( x1, y1, 'r' )will plot your first curve in red. The command
axis ( 'equal' )will force the plot to use the same scale on both axes.
Start with a copy of your program root.m which produces X, the approximate square root of a number W. Let W be 16.0, and let the initial value of X be 2. Iterate using a for loop for 5 steps.
Modify your program by adding three vectors, named STEP, XVAL, and RESVAL. Before you begin your iteration, set these quantities to the values of 0, 2 and 12. On each step of the iteration, add one more entry to each of these vectors:
0, 2, 12
On one picture, plot:
You can store the results of a computation in a file by using the diary command. For instance, once you like the results you're getting from root, try the commands:
diary root.outputwhich should store the text output into the file root.output. Then we have to figure out how to print it, which is probably something like:
root
diary off
lpr -Pprinter_name root.outputif we can just figure out the printer name!
Now print out and turn in your final program, your table, and your plot. There is mercy: if we can't figure out how to print, I'll just come around and look at your screens!
Back to the MATH2070 page.
Last revised on 14 September 1999.