An Introduction by Example
This example is written for users just starting to learn MATLAB
. Consider
this an introduction to a problem-solving process where MATLAB
is an important
part, but not the only part. In this example, we don't show you how to create a
MATLAB
program. Instead we'll describe how the program works and how to use
it. The goal is to give you a high level view before digging into the details.
Nonetheless, the program is simple enough that you should be able to read and
understand it with a little coaching.
You may want to read the first 10 or 15 pages of the textbook before you follow
along with this example. When you're ready to continue, download the
quadraticRoots
code, (Hint:
right-click, "Save as…"), have MATLAB
running, and follow along by typing
the commands that follow the >>
symbol in the gray boxes, below.
Roots of a quadratic equation
Suppose you want a reusable function to evaluate roots of the quadratic equation
The standard solution is
There is a better way to compute , but we'll think about that later.
A MATLAB
Solution
A MATLAB
function to evaluate the formula for
is listed below
(download the code).
function x = quadraticRoots(a,b,c)
% quadraticRoots Compute the two roots of the quadratic equation
%
% Input: a,b,c = (scalar) coefficients of the quadratic equation
% a*x^2 + b*x + c = 0
%
% Output: x = vector of the two roots
%
d = sqrt( b^2 - 4*a*c);
x1 = (-b + d)/(2*a);
x2 = (-b - d)/(2*a);
x = [x1, x2];
end
After downloading the code
to your computer, try to run it from MATLAB
with
>> quadraticRoots(1,4,1)
Don't type the >>
at the start of the line. >>
is the command prompt
that MATLAB prints to tell you that it is ready to accept your next (typed)
command.
Chances are something went wrong when you downloaded the code and asked
MATLAB
to run it. If that's the case, don't worry, read on. If it did
work, then gratulations! And read on, anyway.
quadraticRoots.m
is an m-file function. It's called m-file because it
has a file extension of m
. It is a function because it is a stand-alone
piece of code that performs a calculation in its own memory space.
A user communicates to the function supplying it with inputs. The function
returns results with outputs.
Looking inside quadraticRoots.m
The first line in quadraticRoots.m
is the function definition line, which
specifies the name of the function (quadraticRoots
), the local input variables
a
, b
and c
, and the local output variable x
. We say that a
, b
, c
and x
are local to the quadraticRoots
function because those names are
only known inside the function. As you will soon see, when we call
quadraticRoots
from the command line or from another function, we can use other
variable names or constants as inputs, and we can assign the output to any
valid MATLAB
variable name including, but not limited to, x
.
The lines that begin with %
are comment statements that do not affect the
computations performed by MATLAB
. Comment statements are important because
they help us humans understand what the code means or what it is supposed to
accomplish.
These three lines do the real computational work:
d = sqrt( b^2 - 4*a*c);
x1 = (-b + d)/(2*a);
x2 = (-b - d)/(2*a);
The code is almost self-explanatory. sqrt(...)
is a call to the built-in
square root function: the result is the square root of the input argument.
b^2
is the MATLAB
expression for . The 4*a*c
expression evaluates
the product with the multiplication operator *
is necessary between
each of the operands. The result of evaluating sqrt( b^2 - 4*a*c)
is stored in
the variable d
. Note that the equals sign does not mean equals in the
mathematical sense. Rather, it means that the number that results from
evaluating sqrt( b^2 - 4*a*c )
is stored in the variable named d
.
We see
and we think
In other words, the equals sign acts like a left-facing arrow that takes the
result of b^2 - 4*a*c
and assigs it to d
. The value stored in d
is then
reused in the subsequent lines.
The creation of the x1
and x2
variables uses straightforward computations to
assign the final values of the two roots in the quadratic equation. The last
line x = [x1, x2]
forms a row vector with two elements x1
and x2
and
assigns the values in that vector to the new variable x
.
Again, we see
and we think
From the function definition line (the first line in the m-file), we know that
the values in x
are returned to the place that invoked the quadraticRoots
function. In the following examples the function is called from the command
line, but the function could be called from other functions and the results
could be stored in variables local to those functions.
The last line in the file has the single statement, end
. That signals that
no more code is expected in the definition of the function called quadraticRoots
.
Using quadraticRoots
To use the quadraticRoots
function, you need to have the quadraticRoots.m
file in a place where MATLAB
can find it. It's a good idea to make a directory
(or "folder") on your computer where you can store MATLAB
code. Actually, you
probably want to store your code in different directories, according to the project
you are working on. For now,
download the code
by right-clicking on the link and using Save as...
to put the
quadraticRoots.m
file in a good place. A directory called ME350/mfiles
(or ME350\mfiles
on Windows) is an example of a good place.
Once you have downloaded the file, you need to orient MATLAB
so that it can
run the quadraticRoots.m
file. The short version is that you want to
use MATLAB
's internal file browser to open the directory (folder) that
contains quadraticRoots.m
. Refer to these web pages for the details
Once you have the file on your computer, and have oriented the MATLAB
file
browser so that MATLAB
can "see" the quadraticRoots.m
file, you can use the
quadraticRoots
function like this (where >>
is the command prompt)
>> quadraticRoots(1,5,2)
ans =
-0.4384 -4.5616
>> quadraticRoots(-3,5,2)
ans =
-0.3333 2.0000
Notice that we did not assign the output of the quadraticRoots
function
to a variable. As a result, MATLAB
assigns the output to the generic
variable ans
(for "answer"). A better way to use the function is to
store the results in a variable like this.
>> r = quadraticRoots(1,5,2)
r =
-0.4384 -4.5616
Inside the quadraticRoots
function, the two roots are stored in the local
variable x
. When we use an expression like
r = quadraticRoots(...)
the values assigned to x
inside quadraticRoots
are passed back to the
calling function, in this case the command window, and assigned to the variable
r
. You could say (and be technically correct) that the values stored in
x
when the function is running are copied to the variable r
when the function
terminates. Once the function is finished, the local variables inside that
function no longer exist.
The Big(ger) Picture
We don't need MATLAB
to complete the trivial task of finding the roots of a
quadratic equation. However, this simple example shows the basic steps involved
in more complex engineering analysis with MATLAB
, or with other numerical
analysis software.
- Obtain a mathematical model for a problem of interest.
- Translate the model into a computer code, in this case written in
MATLAB
. - Use the code to analyze the problem of interest.
- Verify the results.
In the first few weeks of this class, we will use a lot of MATLAB
practice
so that you can reliably perform step 2, above.
But wait! We have not completed the important step 4, verifying the results of the calculations. How do we know that the function works?
Validating the Code
The quadraticRoots
function is a simple MATLAB
program to evaluate a familiar
formula. It is tempting to just read the code and say, "Yup,
that looks right." Don't do that!
Of course you should read the code and make sure it looks right, but that is not enough. Engineers need to have a healthy skepticism for their work. "Just looks right", is good enough only when the outcome of being "wrong" doesn't matter.
The obvious way to check the results is to substitute the roots back into the original quadratic equation to verify that the equation is satisfied.
Not Recommended: Copying Values from the Screen
The simple and not recommended way to perform the check is to use the printed values returned to the command window as the roots. Here is an example of doing it the wrong way.
First, let's define new variables a
, b
and c
to hold the constants
in the quadratic equation.
>> a = 1;
>> b = 5;
>> c = 2;
Notice that by ending each line in a semicolon, we prevent MATLAB
from echoing
the values back to the screen. Now that we have a
, b
and c
, we can easily
test the values returned by the quadraticRoots
function. We evaluate the
quadratic equation using the roots returned by quadraticRoots
and assign the result to new MATLAB
variables. If the values
returned by quadRoots
are truly the roots, then the value of the quadratic
expression should be zero.
Again, the following code has the correct basic idea, but in one particular detail it is not a good example of how to test the code.
>> LameErr1 = a*(-0.4384)^2 + b*(-0.4384) + c
LameErr1 =
1.9456e-04
>> LameErr2 = a*(-4.5616)^2 + b*(-4.5616) + c
LameErr2 =
1.9456e-04
These are lame errors because were using the values printed to the screen, which have a limited number of significant digits.
We expect that the roots would satisfy the original equation and they do, sort
of. The values of LameErr1
and LameErr2
are small compared to a
, b
and
(most importantly) c
. Notice that the magnitudes of LameErr1
and LameErr2
are 0.0001, which is the same order of magnitude as the last digit in the values
copied from the command window. In other words, the accuracy of the test (in
this case) is limited by the accuracy of the input value, . Also note
that the errors are apparently equal, which is a coincidence in this case, and
not an indication of a deeper problem.
Recommended: Use Values returned by the function
The recommended strategy for testing the function is not too different from the non-recommended strategy. We'll show the steps, then explain what the steps and results mean
>> r = quadraticRoots(a,b,c)
r =
-0.4384 -4.5616
>> err1 = a*r(1)^2 + b*r(1) + c
err1 =
0
>> err2 = a*r(2)^2 + b*r(2) + c
err2 =
3.5527e-15
The first line, r = quadraticRoots(a,b,c)
creates a new variable r
to
store the roots. Notice that r
contains two values (as expected), which
means that r
is a vector of length 2. The values of r
can be extracted
individually with subscripts, i.e., as r(1)
and r(2)
, where (1)
means
"first element" and (2)
means second element. We'll learn more about
vectors and subscripts soon enough.
The second line, err1 = a*r(1)^2 + b*r(1) + c
, uses the values stored in r
along with the predefined constants a
, b
and c
, to evaluate the quadratic
equation with the first root returned by quadraticRoots
. The result of err1
being exactly equal to 0 is a much better indicator of the correctness of our
code than the error of 1.9456e-04
in the non-recommended version of the test.
An error of exactly zero is unlikely, but as this case shows, it does occur.
The third line, err2 = a*r(2)^2 + b*r(2) + c
, repeats the test for the second
root. The result of err2
being 3.5527e-15
is also much better than the
error of 1.9456e-04
in the non-recommended version of the test. For the
second root, the errors are very small compared to any of the terms in the
quadratic equation. (For example, compare the magnitude of err2
to the
magnitude of c
.) That gives us confidence that quadraticRoots
is working
correctly for the values tested.
The advantages of the recommended strategy are
- The roots are stored in MATLAB variables, which simplifies the testing because you don't need to manually re-enter the values.
- The roots are stored to the full precision used by MATLAB, not limited to the 5 digits presented in the default display.
The second reason is the most important.
Some Comments on Significant Digits
Most practical engineering calculations have only two or three, or maybe four digits of accuracy. For example, when machining a part, the best precision we can expect will be a few tenths of a millimeter (a few thousands of an inch). Inexperienced engineers show their lack of experience by quoting results to an unrealistic number of significant digits.
So why are we so worried about the "right" way to check the results when the "wrong" way gives a value of about 0.0001 instead of 0?
There are (at least) two reasons for paying attention to, and using, MATLAB
's
full precision. First, MATLAB
is going to carry all calculations to 15
decimal places (approximately) so there is no extra work in designing
calculations that take advantage of all that precision. The second, and most
important reason is that roundoff errors propagate through a calculation.
In many, many calculations those roundoff errors will not be a problem. However,
when roundoff does corrupt a calculation, it may not be obvious. Therefore
it is simply a good habit to design your calculations to preserve the
accuracy of all intermediate results as much as possible.
We can summarize the advice as follows:
- Preserve all digits during calculations.
- Present final results to the appropriate number of digits.
Summary
- MATLAB code for computing the roots of the quadratic equation is
written as a function called
quadraticRoots
that takes three inputs,a
,b
andc
, and returns a vector with the two roots. - The
quadraticRoots
function can be called from the command line, or from another function. - If you call the function from the command line, and you do not assign the output
of the function to a
MATLAB
variable, then the roots are stored in the generic variableans
. - We test the function by substituting the values returned by
quadraticRoots
back into the quadratic equation. - The recommendd approach to testing
quadraticRoots
(and for all manipulations inMATLAB
) is to store the values returned byquadraticRoots
in aMATLAB
variable (a two-element vector, in this case), and then evaluate the test using that variable. Even though roundoff errors occur in all numerical calculations, the recommended approach does not introduce unecessary round-off errors.
Practice
- Download the
quadraticRoots
code and store it in a directory (a.k.a. "folder") on your computer. - Run the code for a variety of values of
a
,b
andc
. What happens when the valuesa = 3
,b = 3
andc = 3
are used? Do the roots returned byquadraticRoots
satisfy the quadratic equation in that case? - Write another m-file function called
quadraticRootsTest.m
that feedsquadraticRoots
a series of coefficient values. For each set ofa
,b
andc
values, verify that both roots satisfy the quadratic equation.