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.

  1. Obtain a mathematical model for a problem of interest.
  2. Translate the model into a computer code, in this case written in MATLAB.
  3. Use the code to analyze the problem of interest.
  4. 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.

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.

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:

  1. Preserve all digits during calculations.
  2. Present final results to the appropriate number of digits.

Summary

  1. MATLAB code for computing the roots of the quadratic equation is written as a function called quadraticRoots that takes three inputs, a, b and c, and returns a vector with the two roots.
  2. The quadraticRoots function can be called from the command line, or from another function.
  3. 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 variable ans.
  4. We test the function by substituting the values returned by quadraticRoots back into the quadratic equation.
  5. The recommendd approach to testing quadraticRoots (and for all manipulations in MATLAB) is to store the values returned by quadraticRoots in a MATLAB 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

  1. Download the quadraticRoots code and store it in a directory (a.k.a. "folder") on your computer.
  2. Run the code for a variety of values of a, b and c. What happens when the values a = 3, b = 3 and c = 3 are used? Do the roots returned by quadraticRoots satisfy the quadratic equation in that case?
  3. Write another m-file function called quadraticRootsTest.m that feeds quadraticRoots a series of coefficient values. For each set of a, b and c values, verify that both roots satisfy the quadratic equation.

Document updated 2017-01-08.

Go back to the Examples page.