Introduction To Programming With Matlab
Introduction To Programming With Matlab
With Matlab
Preface
This book is meant for students of engineering or science who need both a useful
programming language for solving problems in their disciplines and an introduction to
ideas from the discipline of computer science. It is a provided free of charge to students
at Vanderbilt who enroll in CS 103, Introductory Programming for Engineers and
Scientists.1 It is being provided to you as a digital book, meaning that you are
provided the digital computer files that contain it. (Because it is in this format, it is very
easy to copy portions of it. You are free to do that, but if you incorporate any part of the
book in other work, then you must give a proper citation, just as you would any book
printed on paper.) If you are reading the Microsoft Word version of this textbook, the
format of the file is compatible with Microsoft Word 1997-2010. If you are reading the
PDF version, it is compatible with all recent versions of Acrobat Reader.
CS 103 provides an introduction to programming. If you study computer science or
computer engineering further, you should, upon completion of this course, have a strong
foundation for advancing in either area as you enroll in more advanced courses that
involve programming. If this is your only course in programming, you should feel
confident that you can write the programs that you need to solve the engineering or
scientific problems that you encounter in your chosen discipline.
Style
Each of the chapters of this book corresponds to approximately one or two weeks of the
semester. This textbook emphasizes more of the general concepts from the discipline of
computer science than does the typical introduction to Matlab programming. In addition
to helping you to learn how to solve problems by writing programs in Matlab, it should
also help you to see how the study of programming in Matlab relates to the study of
computer science.
Much of the material is presented in a tutorial style (i.e., concepts are illustrated by means
of practical examples). The early chapters include lots of introductory tutorial material.
This tutorial material has two purposes: (1) To help you get started, and (2) to reinforce
your understanding of concepts that are presented in lecture. As you gain experience with
Matlab, with concepts from computer science, and with the lecture style of your
instructor(s), you will be better able to absorb material more easily. As that happens, the
style will become less tutorial, and the rate at which new material is introduced will
increase. Unlike most books, this one does not contain sets of worked examples within
each chapter. Instead examples are provided in a separate document, called
1
This book is copyrighted material. It may not be redistributed without permission from the authors, but
students in CS 103 may use the book during the course and for as long as they wish after the course is over.
They make copies for their own use including paper print-outs.
ii
Highlights.doc, which provides both an outline of the ideas in this book and examples,
with commentaries and complete solutions. These problems are presented, discussed, and
worked in class while you, as a student, watch and, in most cases, participate.
Furthermore, this book does not have sets of homework problems at the end of the
chapters. Instead homework problems are provided either in a separate document or at
the end of the book, depending on which format you received. Finally, an extended
homework problem, called a Project, is provided, which requirse a broader knowledge
of the contents of the book and which will require considerably more time to solve. All
these documents are made available on line to students in the class
Homework
The homework problems, including the Project, are provided to help you with the
understanding of the material presented in this book. Some of these problems and
projects may be assigned to you. To complete the assignments you will need to
understand the concepts covered both in the book and in the lectures. Furthermore, as in
virtually all engineering and science courses, because later concepts build on earlier ones,
you will find that each later homework assignment refers to concepts, not only from the
most recent lecture and text coverage, but from previous coverage as well. Thus, as you
work your way through the homework assignments in this class, you will enforce and reenforce your understanding of concepts that you learned earlier in the semester. You will
also be tested on the material covered in the homework assignments by means of in-class,
graded tests. If you learn the material for the homework, you should find that studying for
the tests is easy, and you should do well on the tests and in the course.
The specific version of Word used for these suggestions is Word 2007.
iii
easily by clicking on the tiny circle at the right, bottom of the Word window, as pointed
out by the red arrow below:
iv
To get the full functionality of this feature, you should click on More at the bottom. You
will then see a larger window:
You can choose to use the special features by clicking the checkboxes at the lower left.
The Use wildcards box is the most versatile. If you choose that option, then you can
click the Special box below to get a list of wildcards to choose from. You can
probably learn what you need to learn about wildcards by experimentation, but you can
also learn everything by using the Help facility.
Getting help with Word
Word provides an excellent help facility, which can be accessed simply by double
at the upper right corner of the Word window or hitting the F1
clicking the Help icon
key, and then typing a phrase, such as find into the search box and clicking Search.
Annotating your personal copy of this book
You can easily write in your personal copy of this book and you can highlight words and
sentences, just as would in a paper book. Do not write directly into the text. Instead add
comments, using Words comment facility. Lets consider an example. Suppose you want
to annotate the first page of Chapter 1 by highlighting the definition of computer science
in the second paragraph and inserting a comment about the definition of algorithm. The
result might look like this:
To highlight, select a portion of text, then click the icon of a highlighter pen under the
Home tab. To remove the highlighting, repeat the process. To insert a comment, select a
portion of text, click New Comment under the Review tab. An empty comment
balloon will appear in the margin. Type your comment into that balloon. (If your
comments do not appear in the margin, then click Tracking under the Review tab, click
Balloons, and click to the left of Show Only Comments And Formatting In Balloons
to put a checkmark there. You will find it easier to work with annotations if you turn
these balloons on.) To delete a comment, click right on it and choose Delete
Comment.
Updating your personal copy
Periodically, you will be find that a chapter has been updated on line. When that happens,
you will want to update your personal version. The simplest, but not the best, approach is
simply to replace your current version with the new version. There are two problems with
that approach: (1) You will not know what changes were made and (2) you will loose all
your highlighting and comments. Fortunately, Word provides a way to solve both
problems. Here is how you can use it. Lets suppose that your current document, which
might, for example, be Chapter 1 is called Chapter 1.doc.
1.
2.
3.
4.
5.
6.
7.
8.
9.
Copy Chapter 1.doc into a file called old_version.doc, but do not open it.
Copy the new version into a file called new_version.doc.
Open new_version.doc.
Click on the Review tab.
Click Compare. A drop-down menu will appear. Click Compare there too.
Another drop-down menu will appear. Click Compare there as well.
Under Original Document select old_version.doc.
Under Revised Document select new_version.doc.
Click Compare
10. At this point you will see a three documents in separate windows with many
annotations in the document called the Compared Document, each of which
indicates how the old version must be changed to become the new version. Click
the x at the top right of the other documents to remove them from view.
11. At the left, you will find a window in which these changes are listed. There are six
categories of changes. The first of these is the only one you need to be concerned
with: Main document changes and comments. Under that category there are
five types of changes: Insertions, Deletions, Moves, Formatting, and
vi
Comments. You will want to keep all changes other than those that eliminate
your highlighting. To undo the elimination of highlighting, scroll down and find
every instance of Not Highlight. Click right and then click Reject Format
Change. (The comments that you have added will remain unless you specifically
delete them.)
12. Now, scroll through the document. Look at each change and accept it. To accept a
change, click the right mouse button anywhere inside it and select Accept
Format Change, Accept Deletion, Accept Insertion, etc. as appropriate. (To
reject a change, click the right mouse button anywhere inside it and select Reject
as appropriate.)
As you accept changes, observe which changes are trivial corrections of
typographical errors and which are important enough to take note of in your
studies. You may even decide to add new highlights or comments as you examine
a change. You can do that at any time during this process as well.
13. When you have finished accept and rejecting changes to produce your new
annotated version, save it as Chapter 1.doc.
At this point you have updated your personal copy to the latest version, have inspected
each change, and have kept all your own annotations.
Software Versions
The Matlab examples shown in this book were run using Matlab Version 6.5, Release 13,
Matlab Version 7.0.4.365 (Release 14) Service Pack 2, and Matlab Version 7.8.0.347
(R2009a)each in the 32-bit version, but they will run also in the more recent 64-bit
versions of Matlab. The C++ example was run using Microsoft Visual Studio.Net,
Version 1.1.4322 SP1 and Microsoft Visual C++, Version 7.1.3088. The operating
systems used include Microsoft Windows XP Version 2002 Service Pack 2, Microsoft
Windows XP Professional Version 2002 Service Pack 3, and Windows 7 Professional.
This book was written using Microsoft Word 2002, 2003, 2007, and 2010.
vii
Mathematical symbols (not Matlab) are Time New Roman Italic 12 pt.
Text in the Matlab taskbar, menus, and submenus and filenames are Arial
12 pt or smaller.
Acknowledgements
This book was developed at Vanderbilt as part of a course for first-year students in the
School of Engineering. We would like to thank over a thousand students, who, during the
years from 2000 through 2010, have used it, endured its early versions, and provided
valuable feedback that has contributed to its current form.
J. Michael Fitzpatrick
John D. Crocetti
Chapter 1
Introduction
w1 g1 w2 g 2 w3 g3
,
w1 w2 w3
where w1 , w2 , w3 are the weights, g1 , g 2 , g3 are the grades, and a is the average. No one
would write a computer program to perform such a simple calculation! Lets do it
anyway, and lets write two versions, one in Matlab and one in C++. (We could use Java
in place of C++. The results would be very similar.) Here is our Matlab program:
The program itself typed Please input grades: and Please input
weights:. The user typed in [95 90 100] and [40 15 35]. The program
then typed Weighted_average = 96.1111 (skipping a line as it did so). The
brackets ([]) are required, by the way. If the user were to omit them, the program would
print a message stating that the user had made an error and would then stop without
giving an answer.
#include "stdafx.h"
using namespace std;
void main(void)
{
const int
N = 3;
float weights[N];
float sum_weights;
float grades[N];
float sum;
float average;
int
i;
cout << "Please input 3 grades: ";
for(i = 0; i<N; i++){
cin >> grades[i];
}
cout << "Please input 3 weights: ";
for (i = 0; i<N; i++){
cin >> weights[i];
}
sum = 0;
sum_weights = 0;
for(i = 0; i <N; i++){
sum += grades[i]*weights[i];
sum_weights += weights[i];
}
average = sum/sum_weights;
cout << "Weighted average = " << average << endl;
}
The program itself typed Please input 3 grades: and Please input 3
weights:. The user typed in 95 90 100 and 40 15 35. The program then
typed Weighted average = 96.1111.
Without understanding anything about programming, it is possible to see one important
difference: The Matlab program is much simpler than the C++ program. Because of that
simplicity, it is possible (1) to write the Matlab program more quickly and (2) to do it
with fewer errors. This simplicity is the major reason for using Matlab. The simplicity
factor is even greater, though, than might be appreciated at first. Note that in the Matlab
program we did not include anything about entering exactly 3 grades and 3 weights.
Lets see what happens when we run the same Matlab program and enter, say, 5 grades
and 5 weights:
Please input grades. [70 82 94 77 89]
Please input weights. [40 15 35 45 20]
Weighted_average =
81.0645
It works perfectly. In fact, there is no restriction whatever on the number of grades and
weights, except there must be the same number of each. This little program is very
versatile.
Now, lets try this with the C++ program:
Please input 3 grades: 70 82 94 77 89
Please input 3 weights: 40 15 35 45 20
Weighted average = 79.8447
It seems to work, but it does not work. The average is wrong. It used 70, 82, and 94 as
grades, and it used 77, 89, and 40 as the weights. The numbers 15, 35, 45, and 20 were
ignored entirely! This is an example of the worst kind of error. The program gives a
reasonable looking result, but the result is wrong. A less insidious error would be one in
which the program refused to run: Not giving an answer is much better than giving an
incorrect answer. It is possible to rewrite the C++ program so that it can handle an
arbitrary number of grades (and equal number of weights), just like the Matlab program,
but doing that requires that the C++ program be far more complex than the version we
have given above. That is why we said that the simplicity factor is even greater than
might be appreciated at first.
This versatility of Matlab programs is another major advantage, and it is one of the
ingenious aspects of this language. The inventors of Matlab were able to envision
numerical problems in a very general way, and, as a result, they succeeded in designing a
language that allows you to write simple programs that can handle a wide variety of
inputs. It is common for a Matlab programmer to design a program for a certain type of
input and then realize that the program, without change, can handle much more.
This simplicity comes at a price. Matlab is the winner for small programs that involve
numerical applications and are written for the use of Matlab programmers. C++ becomes
the better choice when any of these three qualities are missing. Much of the complexity
of the C++ program is there because it reduces the likelihood of error when large
programs (more than a thousand lines of Matlab or more than ten thousand lines of
C++), such as parts of a computers operating system (e.g., Linux, Mac OS, Windows
XP), graphics applications, or spreadsheets, are to be written. It is also the better choice
when non-numerical applications, such as word processors, web browsers, or database
programs are involved. Finally, when the program is to be used by a Matlab programmer,
who knows Matlabs rules and its special requirements, such as delimiting inputs by
brackets (e.g., [95 90 100], instead of 95 90 100 in the example above), running
the Matlab program is no problem. But when an application, such as a tax calculator or
the controller for a microwave oven, is to be used by non-programmers, which includes at
least 99% of typical users, the problem tends to be better solved by C++.
In the remainder of this book, you will be led through many examples that fit the three
requirements above, i.e., small programs involving numerical applications to be used by
Matlab programmers. While these may appear to be restrictive requirements, many
thousands of engineers and scientists, researchers and practitioners, both in academics
and in business, have found that almost all the programming problems that they
encounter fit this profile. For them, and for you, if you plan to study engineering or
science or are already working in these areas, when the question is Which language
should I use to solve my problem?, the right answer will almost always beMatlab.
Chapter 2
Getting Started with Matlab
To gain the most from this book, you should, as you read it, be continually writing and
testing examples in Matlab. To run the examples in this book you should have Version 7
of Matlab installed on your computer. The version you have can be determined by
clicking on the Help button and then clicking on About MATLAB. You will see the
Matlab logo pop up with the version written, e.g., Version 7.7.0.471 (R2008b). The first
number after the word Matlab is the version number (in this case 7); the numbers after
the decimals are subversion numbers (this is the non-sinister type of subversion!) .
The Desktop displays four windows: the Current Directory at the left, the Command
Window in the middle, the Workspace at the upper right, the Command History at
Chapter 2
the lower right. You will learn to type commands into the command window. When you
are ready to quit Matlab, you type quit in that window, as shown on the next line,
>> quit
and hit Enter. Matlab will then close all open windows and quit. If you have files open,
you will be asked about saving open files and given a chance to save them. You can also
quit by clicking with the left mouse button on the at the top right of the Matlab
desktop.
When you click on this button, a window will pop up showing the directory structure that
is accessible from your computer. Click on the directory you wish to use and then click
OK. You will then see that the name of the current directory that appears in the space to
the left of the button with the three dots has now changed to the one that you chose.
2.2.1 Path
When Matlab fails to find a file that it is looking for in the Current Directory, it does not
give up. It looks in other directories. It follows a path searching in one directory after
another. A path, in this context, is a list of directories through which a program
searches for a file. The notion of a search path occurs in operating systems such as Unix,
Windows, and Mac OS and in many programming environments. Matlab comes with a
path already set up, but you can change it by adding or removing directories.
Chapter 2
The beginning of
your path
(the end is
down below
here)
the display. The entire path can be viewed by using the scroll button at the right. Click
Add Folder and a window will pop up called, Browse for Folder. Inside this
window, click on the directory that you wish to add and then click OK. The directory will
Chapter 2
appear at the top of the path. Finally, click Move to Bottom to move the directory to the
end of the path. While you are in that window you can add as many directories as you
wish. If you are running Matlab on your own machine and you want to have this
directory appear on your path the next time you run Matlab, click Save to save this path
for the next time your run Matlab. If you want to leave this window open you can click
on the Minimize button in the upper right corner of the window ( _ ). Otherwise, click
Close. If you have not saved the path, a box will appear saying "Do you wish to save
the path for use in future MATLAB sessions?" Again, if you are running Matlab on
your own machine and you want to have this directory appear on your path the next time
you run Matlab, click Yes. Otherwise, click No.
Removing directories from your path.
To remove a directory from your path, you will use the same window that you used in the
previous section. If is not already open, click on File at the top left of the Matlab desktop
and then click on Set Path When the Set Path window pops up, use the scroll bar in
the display at the right to find a directory that you wish to remove. Click on that
directorys name to highlight it and then click the Remove button at the left. While you
are in that window you can remove as many directories as you wish. Again, as in the
previous section, if you are running Matlab on your own machine and you want to have
the changes that you have made appear on your path the next time you run Matlab, click
Save to save this path for the next time your run Matlab. If you want to leave this
window open you can click on the Minimize button in the upper right corner of the
window ( _ ). Otherwise, click Close. If you have not saved the path, a box will appear
saying "Do you wish to save the path for use in future MATLAB sessions?" Again,
if you are running Matlab on your own machine and you want to have this directory
appear on your path the next time you run Matlab, click Yes. Otherwise, click No.
Chapter 2
This command tells Matlab to add 1 to 2 and then assign the result to a variable called x.
Matlab executes that command and then show you the new value of x. If you wish at any
time to learn the value of x, you simply type it, and Matlab will respond as follows,
>> x
x =
3
This value will not change until x is assigned a new value by later statement. If you ask
for the value of a variable that has not yet been given a value, Matlab complains,
>> y
??? Undefined function or variable 'y'.
The act of assigning a value to x caused a new variable named x to be defined and set up
a location in memory for its value to be stored. While you might not think about it at first,
the value of the variable x must be stored in some location in the computers memory,
and that location cannot be used for any other purpose until Matlab exits. The definition
of variable (in computer science, as opposed to mathematics) is in fact a named location
in memory. Each time you assign a value to a new variable, Matlab puts the name of that
variable into a table and sets aside enough room to hold its value. As you use more
variables, you use more space. If at any time, you wish to see the variables that you have
defined, you can use the whos command, as for example,
>> whos
Name
c
x
y
Size
1x1
1x1
1x1
Bytes
8
8
8
Class
double array
double array
double array
The columns Size and Class will mean more to you later. The column Bytes shows
how much space Matlab has allocated for each variable. A byte is 8 bits. A bit is the
smallest unit of memory. It can store one of two values: 0 or 1. The number of different
values that can be stored in N bits is 2 N .
Interpretation versus compiling
The execution of a command given to a computing environment, such as Matlab, is
termed interpretation of the command. Matlab interprets the command as soon as you hit
the Enter key. This immediate response is different from the situation with a so-called
Chapter 2
compiled language, such as Java, C, C++, or FORTRAN, in which you write a program
from beginning to end and then run it. In these languages, unlike Matlab, before the
commands that you type can be run, they must be translated from the language that you
are using (e.g., C++) into a language that the computer can understand. This translation is
called compiling. Note that the word "interpret", which roughly means "translate" outside
the computing community, in fact means "execute" when it refers to a computer
language. The word compile", which roughly means gather and organize outside the
computing community, means "translate" when it refers to a computer language. You
should learn these strange new meanings right now! Matlab provides an option for
compiling, but Matlab is instead used primarily as an interactive language, which means
a language in which the user continually sees the results of his or her commands as soon
as they are issued. An interactive language is always an interpreted language.
Suppressing printing
Unless you tell it otherwise, Matlab will print the result of a command in the command
window, as it did with the x = 3 above. If you do not want the result printed, you can
type a semicolon (;) after the command. With the semicolon, the command will still
assign the value 3 to x, but it will not print the value of x. Try setting x to 5 using the
semicolon. Then, to see the value of x, type x alone (and then hit Enter). You should see
this:
>> x=5;
>> x
x =
5
Spaces
You may have noticed that in the example above, there is no space before or after the
equal sign, while in the previous example there were spaces. The spacebar can be used to
put spaces where they would occur naturally without having any effect, other than to
make the command easier to read. As we will see in the next example, variables in
Matlab can have more than one letter and can even include digits, but the letters and
digits cannot have spaces between them. Thus, examples of legal names, which are also
known formally as identifiers, are SNOBOL and Wat4, but SNO BOL and Wat 4 are
illegal because they include spaces. That should not be surprising. You would not expect
to find spaces inside a name. We will give more precise rules for variable names below.
Continuing a command to the next line
You can indicate to Matlab that a command is to be continued on the following line by
typing three dots (periods):
>> dime = 2 + ...
8
Chapter 2
dime =
10
acceleration =
9.8000
velocity =
4.5000
Here we see that the first line typed into the Command Window, which has semicolons
after the assignments to both acceleration and velocity, causes only the
weight to be printed, while the second line, which has no semicolons, causes both
acceleration and velocity to be printed.
Repeating a command
Hitting the up-arrow key () (not the one in the numeric keypad) will cause the previous
command line to appear. Hitting Enter will then cause it to be executed. Repeated
pressing of the up-arrow will cause earlier and earlier lines to appear. Pressing the downarrow key will then cause later commands to appear. When a command has appeared, it
may be altered by moving the cursor with the left-arrow and right-arrow keys and then
using Backspace and/or Delete, and/or typing new characters. The resulting command
is executed only when Enter is pressed. Try typing x = 4+1 without hitting Enter and
then altering it to x = 4-1 and then hitting Enter.
You can also repeat commands by double clicking them in the Command History
window at the lower left of the Matlab desktop. You can also highlight, drag, and drop
them from anywhere into the command window and execute them by hitting Enter.
Chapter 2
1x1
double
>> y
??? Undefined function or variable 'y'.
>> y = 2;
>> diary off
>> z = 45
z =
45
>> diary on
>> whos
Name
Size
x
y
z
1x1
1x1
1x1
Bytes
8
8
8
Class
Attributes
double
double
double
>> x+y+z
ans =
48
>> diary off
>> t = 7
t =
7
Now, if we go to the operating system and look at the file, My First Session.txt (double
clicking on it should work), we will see this
Chapter 2
whos
Name
Size
1x1
Bytes
8
Class
double
y
{ ??? Undefined function or variable 'y'.
}
y = 2;
diary off
whos
Name
Size
Bytes Class
x
y
z
1x1
1x1
1x1
8
8
8
Attributes
Attributes
double
double
double
x+y+z
ans =
48
diary off
Note that even Matlabs error message showed up! (Diaries should record the bad with
the good. It helps us learn from our mistakes!)
Syntax and Semantics
Matlab's commands must be typed correctly. If they are not, then an error message is
given:
>> 1 = x
??? 1 = x
|
Error: The expression to the left of the equals sign is not
a valid target for an assignment.
>>
Matlab is trying to tell the user what is wrong. In this case, the user probably does not
realize that the equal sign does not mean "is equal to", but instead means "assign the
value of the right side to the variable that is on the left side". This is an assignment
statement, and constants, such as 1, 2, or 18.9 cannot be assigned values. Thus,
constants cannot appear on the left side of an equal sign.
This error is a good example of the violation of the proper form of a Matlab statement.
The proper form of a Matlab statement is its syntax. A violation of the form is called a
syntax error. Violations with regard to the form of any computer language (and any
spoken language for that matter) are called syntax errors. The reason for this particular
syntactical rule (syntactical is the adjective form of syntax) is that only named
variables can be assigned values. Putting a constant on the left side of an equals sign does
Chapter 2
10
not fit the meaning of the assignment statement, and it is not allowed. Thus, it is a syntax
error.
We call the meaning of a statement, as opposed to the form of a statement, the semantics
of the statement. So here we have an error that violates both the syntax and the semantics
of the assignment statement in Matlab. (The word semantics is a singular noun. Thus
we might say, The semantics is simple, or, The semantics needs to be well
understood.) Note that despite the error, Matlab indicates its readiness for the next
command by typing another prompt (>>).
Variable names
The syntax of Matlab allows a variables name, more formally known in computer
science as a variables identifier, to be a single letter, such as x, or a word, such as
weight. In mathematical expressions, as opposed to programming expressions, we are
restricted to single-letter names for variables. Because of that restriction we know that
consecutively written letters indicate multiplication. Thus, in mathematics x = cat would
mean that the values of c, a, and t should be multiplied together and that the value of x
would be equal to the resulting product. We will see below that multiplication is
indicated explicitly in Matlab by typing an asterisk (*, which is shift-8 on most
keyboards) between the two variables to multiplied. Thus x = cat in mathematics would
translate to x = c*a*t in Matlab. The use of the asterisk to indicate multiplication is
very common in programming languages. It was used for that purpose in the very first
major programming language FORTRAN (an acronym for Formula Translator),
which was invented in the late 1950s, and it is still used today in Fortran and in both C++
and Java as well. Because programming languages use a symbol to indicate
multiplication, they can allow an identifier to consist of more than one letter. In the
version of Matlab used in writing this book, the name of a variable may include up to 63
characters, which may be upper or lower case letters. Longer names are legal but
characters after the 63rd are simply ignored. (The function namelengthmax gives the
maximum.) Matlab distinguishes between upper and lower case, so, for example, X and
x are two different variables, as are hOmEr and HoMeR. Additionally, any of the
characters in the name, other than the first one, may be a digit or the underscore ( _ ).
These rules are almost identical to those for identifiers in C, C++, and Java. Here are
some examples of legal Matlab, C, C++, and Java identifiers:
mass145square
weight_with_shoes_on
Init_velocity
hA_RDt_oR_ead_But_legal
Chapter 2
11
Matlab stores values in a form that includes more than the mere 5 digits that you see in
the examples above. If you want to see more of those digits printed on the screen, you
can use the command format:
>> format long
>> X
X =
1.00000000000000
3.40000000000000
2.00000000000000
3.14159265358979
3.00000000000000
-4.00000000000000
As you can see the numbers are now printed with more digits, which in Matlabs
terminology (borrowed from Fortran) is a longer format. There are other formats
available. To learn what they are, you can use the "help" facility. The most direct way to
use it is to type the command help followed by a space followed by the name of the
command that you want help with. For example,
>> help format
FORMAT Set output format.
All computations in MATLAB are done in double precision.
FORMAT may be used to switch between different output
display formats as follows:
FORMAT
Default. Same as SHORT.
FORMAT SHORT
Scaled fixed point format with 5 digits.
FORMAT LONG
Scaled fixed point format with 15 digits.
. . .
There are more formats displayed by this command, but we did not show them all above.
The help command will be of great value to you as you learn Matlab. Whenever you
forget how some command c works, type help c at the command prompt.
If you dont know the name of command or can't remember it, the command lookfor
might come to the rescue. The command lookfor x searches through the on-line
keywords (first lines of help outputs) given for every command, searching for the word
x, and it shows you the associated commands. For example,
>> lookfor pseudoinverse
PINV
Pseudoinverse.
This response tells you that there is a Matlab command named pinv that has something
to do with pseudoinverse. To learn what that is, you would then type help pinv
(help PINV works too.) Note that lookfor and help are (fortunately) not case
sensitive. To learn more about lookfor and to see the names of some other helpful
commands type help lookfor.
In addition to the help available with the commands help and lookfor in the
command window, there is a more graphical help system available from Matlabs Help
Chapter 2
12
Navigator, which can be reached via the command helpwin or via mouse clicks. To
access that system, type helpwin at the command prompt, or if you want help on a
particular command, such as the format command, type
>> helpwin format
To access this same graphical help system via mouse clicks, click on the Start button at
the bottom left of the Matlab window. A menu will pop up. Slide up to MATLAB. A
companion menu will appear at the right. Slide onto that menu and then down to Help
and click again. Alternatively, click on Help in the Matlab taskbar and choose Product
Help or just hit the F1 key on your keyboard. The Help window will pop up with the socalled Help Navigator on the left and helpful links in a panel on the right, as shown on
the next page.
Chapter 2
Help Navigator
13
Helpful Links
Follow any links that appear interesting. This help facility is very intuitive and easy to
navigate. If you like animated demos, then, after clicking on the start button, slide up to,
and click on, Demos (alternatively click on the Demos tab in the Help Navigator, or
click Help in the Matlab taskbar and choose Demos).
Demos tab
(The graphical help system can also be summoned by hitting the F1 key, but the
navigator does not appear.)
Chapter 2
14
white blank-page icon at the left end of the Toolbar at the top of the Matlab window, (2)
Click File/New/M-File, or (3) type edit in the Command Window and hit Enter. An
Edit Window will pop up:
If you type into this window, text will appear, but hitting Enter will cause nothing to
happen except moving to the next line, because Matlab does not interpret (execute) these
commands as you type them. Type the command
x=5
inside this window. Now save what you have typed into a file called myfirst.m by
clicking File/Save in this Edit window, changing directories to the same directory that
you chose earlier for your "current" directory, typing in the file name, and clicking Save.
You have just created an M-file. The M stands for Matlab, and the file extension is
always .m, which is pronounced dot m. So another commonly used name for an M-file
is a Dot-M file. Now go back to the command window and type myfirst (without
the.m, i.e., not myfirst.m). You should see this:
>> myfirst
x =
5
>>
Chapter 2
15
Matlab has checked to see whether you have defined a variable named myfirst (you
havent), then it looked inside its current directory for a file named myfirst.m, found it,
and interpreted the commands it found inside. Congratulations! You have written a (very
short) Matlab program, stored it in a file, and run it. You ran it by typing the name of the
file without the .m extension. It is because of this extension that the files containing
Matlab programs are called M-files. The conventions regarding file extensions for other
languages, such as Fortran, C, C++, and Java are lest strict, but typical extension for these
languages are .f, .c, .cpp, and .java.
Within the edit window, put a semicolon after x=5. Save the file again by clicking on the
diskette icon
, near the upper left. Now return to the command window and type
myfirst again. As with commands issued in the command window, the output that was
originally produced by the command x=5 is now suppressed. This suppression of output
is much more important for programs written in M-files than for commands issued in the
command window, because typically only the final result of a long set of commands
should be printed. In fact the vast majority of commands in the typical M-file will include
a semicolon to suppress printing.
Source code versus executable code
A program is a sequence of symbols that describes an algorithm. An algorithm is a stepby-step procedure for solving a problem. The text that you enter into an M-file by using
the edit window is a sequence of symbols that describes an algorithm, and therefore it is a
program, but it is sometimes also called code or source code or source. This strange use
of the word code comes from the fact that the earliest programs (i.e., in the 1940s and
50s) were written in a form that resembled a code and, like a code, it was very difficult
for a human to decipher. The reason for the modifier source is that, before the
computer runs the code that a programmer writes, it typically must translate it into an
equivalent program called the executable code that is written in another language that is
more efficient for a computer to run. Thus, the program that a human writes is not the
program that the machine runs, but it is the source of the program that the machine runs.
The language of the executable code is as difficult to decipher as the early languages
were, and for that reason it is very hard to determine how a program works by looking at
the executable code and even more difficult to modify the executable code. Companies
who produce programs for sale are eager to distribute their executable code (also known
as the executables) but rarely their source code, thereby keeping their proprietary
programming tricks secret. Similarly, your instructors in a programming course can give
you an executable version of a solution to a programming assignment so that you can run
it and thereby see first-hand how it is supposed to behave without your being able to see
how it works.
The text that you type is called alternately the program or the code, and writing such
a program is called alternately programming or coding. The person who writes the
program is the programmer (but, for some reason, not the coder). It is interesting to
note that despite the fact that we tend to think otherwise, the program that the
programmer writes is never executed by any computer; it is merely the source of the
executable computer program, and almost no one ever sees a program that runs.
Chapter 2
16
Software
A set of files containing source code or executable code or both that describes a single
program or a set of programs is called software to distinguish it from the hardware that
makes up the physical part of a computer. The disciplines of Computer Science and
Computer Engineering each deal with software and hardware, with the former
emphasizing the software and the latter emphasizing the hardware. The software written
by scientists and engineers to solve the problems of their disciplines tends to be focused
on numerical applications describing the behavior of physical systems, such as buildings,
bridges, chemical plants, automobiles, aircraft, audiovisual systems, medical devices, or
even kitchen appliances. Their programs tend to be written in a language, like Matlab,
that is tailored to their applications. Because of the design of the language, powerful
programs can be written in a few hundred lines of source code and can be written by one
person. With these programming languages, the programmer is able to focus on the
physical aspects of the system instead of the logical aspects of the program. The software
written by computer scientists and computer engineers to solve problems of their
disciplines tends, on the other hand, to be written in languages, like C, C++, or Java, that
are designed to handle more general applications, often describing non-physical systems,
such as insurance policies, bank accounts, spreadsheets, databases, payroll systems,
reservation systems, or general document processors (e.g., Microsoft Word, which was
used to write the words that you are reading). Because of the design of these languages
and the complexity of the programs, hundreds of thousands of lines of source code are
required. Such programs are rarely written by one person. A subfield of Computer
Science, called Software Engineering, studies the problems that arise when large groups
of people design large programs and the equally important problem of identifying and
correcting the many unfortunate, but inevitable, errors, or bugs, that are present in the
code that they write. In Chapter 5 we will use one of the techniques for program design
that were developed by software engineers.
P-code
As we pointed out in under Interpreting versus compiling in Section 2.3 above, the
Matlab system interprets the code that you type into the command window as soon as you
complete a command and hit the Enter key. What we did not mention there is that the
first phase of the interpretation is a translation into executable code. In Matlab, the
executable code has the special name, p-code. In Java, the executable is called
bytecode. In Fortran, C, and C++, and many other languages, it is called simply
executable code. When the name of an M-file is part of the command executed in the
command window, the entire program in the file is translated into p-code before the
execution phase. For efficiency, the p-code is also saved in memory as long as Matlab is
running and until the M-file is modified, so that the next execution of the program (before
modification) does not require the translation step. You can translate the contents of any
M-file into p-code and save it into a file for distribution by giving the command, pcode
name, where name is the name of the M-file without its .m extension. The program will
be translated into p-code and written into a P-file that has the same name as the M-file
but with the .m extension replaced by .p. The P-file will be placed into the current
Chapter 2
17
directory. One important aspect of p-code is that it is version dependent. Thus, while an
M-file written in version 7.0 of Matlab will run under Matlab 17 (we should live that
long!), a P-file written under 7 may not run under any previous version of Matlab. An
important aspect of a P-file is that, if the files name.p and name.m (i.e., two files with
the same name except for different extension) are present in the same directory, Matlab
will always run the .p file instead of the .m file. This can cause great confusion if the
programmer modifies the .m file and fails to remove the .p file. When the command
name is issued, the .p file will be run, ignoring the changes in the .m file.
Comments
Matlab understands commands that are given it in proper syntax. Humans can understand
them too, but you can help other humans understand what you are doing by including
additional text that is meant to be read only by humans. As an example, you might type in
your name at the top of the M-file to show that you are the author. If you do that, Matlab
will complain that you have made a syntax error (unless your name happens also to be the
name of an active variable or a function that takes no arguments!). To keep that from
happening, you must tell Matlab to ignore the line that contains your name. That is done
by starting the line with a percent sign (%)3. It is customary to include such information
about the production of the file in a header at the top. For example, for submitting
homework solutions in a class you might be required to include the following
information, in this order:
Your name
Your section and the registrars label for the class
The date of submission
The name of the assignment
Text such as this, which is included in the program but is ignored by Matlab, is called a
comment or comments. We are showing the comment text in a green font because the
Matlab editor shows it in a green font as well. Matlab uses color to make it easier to read
the text, but color has no effect on the meaning of the text. Comments can also be
included on the same line as a Matlab command. The rule is that everything following the
% up to the end of the line is ignored by Matlab:
number = 6
3
Two percent signs together (%%) have a special significance. They indicate the beginning of an M-file
cell, which is a set of statements that can be run separately from the rest of the code. We will not use this
facility, but to find out more, you can search for Rapid Code Iteration in Matlabs Help Navigator.
Chapter 2
18
Every modern language provides some means for including comments, and there is
always some character or characters used to indicate those parts of the program that are
comments. C, C++, and Java, for example, all use two forward slashes (//) instead of a
percent sign. Surprisingly, comments may be more important to a program than the
executable commands! That is because most programs must eventually be changed, and
humans, who rely on comments to make sense of the code, must make those changes.
Using the path to find an M-file
Inside the edit window, change the 5 to a 6. Then, using File/Save As, save the result
to a new file called mysecond.m in the directory that you added to your path above.
Type the name mysecond into the command window. You should see this new version
run. Matlab has found this new file in the directory that you added to your path and has
run it.
A vector in mathematics is simply an ordered list of numbers, and each number is called
an element of the vector. As we will see in the next chapter, a vector can be created in
Matlab, as shown above, by using a pair of brackets ([ ]) to enclose a list of numbers
separated by spaces, commas, or both. The two commands above set x and y equal
respectively to two 8-element vectors. Now give the following command:
plot(x,y)
A plot appears in a Figure window, which pops up automatically when you give the
plot command. If you want to close the figure window, either click on the in the
upper right corner or give the command close. If you want to keep that window and put
your next plot into a new figure window, give the command figure before the next
plot command. If you have more than one figure window open, close will remove
only the last one that appeared. If you want to get rid of all figure windows, give the
command close all. Your plot should look like this:
Chapter 2
19
It should be clear that plot(x,y) plots the vector y vertically versus the vector x
horizontally. These vectors must be of the same length. For each value of the index, n,
from n = 1 to n = 8, x(n) gives the horizontal position of the point that is plotted, and
y(n) gives the vertical position. There are many variations possible to this simple plot.
Dotted or dashed lines may be used, individual dots may be plotted without being
connected by straight lines, symbols other than dots may be plotted, various colors may
be used, labels may be put on the axes, etc. You can get an idea of its versatility by trying
help plot. We will give more examples in Chapter 3.
Figure windows are use whenever graphical output is required. There are many
commands in addition to plot that produce graphical output. All of them put their
graphical output into a figure window. As an example, lets display a color picture. One
of the official logos of Vanderbilt University is a letter V whose inside is the outline of an
oak leaf and an acorn. The image can be stored digitally in many file formats. One such
format, which is useful for simple cartoon-like pictures, is the so-called GIF
(pronounced either gif or jif) format. If we put a file, named Vandy_symbol.gif,
Chapter 2
20
which contains this logo in GIF format, into a directory that is on the Matlab path, and
issue the following commands, the figure below will pop up:
>>
>>
>>
>>
[V,map] = imread('Vandy_symbol.gif','GIF');
image(V);
truesize;
colormap(map);
Alumni_lawn = imread('Alumni1.jpg','JPG');
figure(2);
image(Alumni_lawn);
truesize;
axis off;
Chapter 2
Matlab:
o current directory and path
o command window
o prompt
o variable
o suppressing printing with semicolon
o identifier
o extending a command across lines
o multiple commands on one line
o assignment statement
o the help and lookfor commands
o the format command
o edit window
o M-file
o p-code and P-file
o comment
o figure window
o vector and vector element
o plot and the plot window
21
Chapter 2
22
22
Chapter 3
Matrices, Operators, and Functions
The basic unit with which we work in Matlab is the matrix (plural is matrices). We add
them, subtract them, multiply them, and perform many other operations on them. In this
chapter, we introduce the basic idea of the matrix. We show how Matlab allows you to
define matrices and to operate on them. In addition to providing simple operations on
matrices, such as addition or subtraction, which are stated using the usual plus sign and
minus sign of mathematics, Matlab provides hundreds of other operations that are carried
out by calling built-in functions, such as sqrt(x), which is a function that calculates
the square root.
3.1 Matrices
The name "MATLAB" stands for "Matrix Laboratory", which suggests (correctly) that
Matlab is designed to deal with matrices. A matrix is a 2-dimensional rectangular
arrangement of numbers, such as this 2x3, matrix, which has 2-rows and 3-columns:
1
3.3
2
3.1416
3
-4
A matrix is a useful form for dealing with sets of two or more equations involving sets of
two or more variables, a situation that arises repeatedly in all branches of science and
engineering. Scientists and engineers also work with scalars (single numbers).
Surprisingly perhaps, Matlab treats a scalar as a 1x1 matrix! In fact even the x in
sqrt(x) above is treated in Matlab as if it were a 1x1 matrix! To see the size of a
matrix in Matlab, you can use the built-in function called size:
>> size(x)
ans =
1
1
A function in mathematics is any operation that produces a result that depends only on its
input. In Matlab, as in most other programming languages (C, C++, Java, Fortran), a
function is any operation that is invoked by giving its name. The major distinction
between these two definitions is that a mathematical function will always produce the
same output for a given input, whereas that is not necessarily true for a function provided
by a programming language. Input to a function is given as a list of values separated by
commas inside a pair of parentheses that follows the name. Each such value is called an
argument (in both mathematics and programming). Here the size function was given
only one argument, x, (so no commas are needed), and it produced as its result two
numbers1 and 1. The first 1 represents the number of rows, or height, of the matrix x
and the second 1 is its number of columns, or width. It is possible to make larger matrices
by using brackets and semicolons (;). As another example, lets create in Matlab the
Chapter 3
24
matrix that we gave at the beginning of this section, assign it to the variable X, and then
call size using X as an argument, as follows:
>> X = [1 2 3; 3.4 pi -4]
X =
1.0000
2.0000
3.0000
3.4000
3.1416
-4.0000
>> size(X)
ans =
2
3
Note that the matrix is printed in row-major order, meaning that all the elements on one
row are printed before the elements in the next row. Note also that when the semicolon
occurs inside square brackets it means "end of row" (instead of suppressing printing).
Hitting the Enter key also indicates end of row, and a comma can optionally be placed
after each element within a row. Note that the word pi stands for the constant value for
in Matlab. A vector in Matlab is simply a matrix with either exactly one column or
exactly one row. They are called, respectively, a column vector and a row vector. The
commands, x = [1 4 7] and y = [1; 4; 7] produce a row vector and a column
vector, respectively. Try these commands and look at the difference in their outputs. Then
check the dimensions of x and y with size(). A scalar is treated in Matlab, not only as
a 1x1 matrix, but as a vector with only one element.
Matrices are sometimes called arrays. For most programming languages, the term array
is used exclusively, but for Matlab the choice of term depends on the application, which
in turn determines the sort of operations that are performed on them. (Array operations
and matrix operations are listed below in the section entitled, Arithmetic with matrices
and vectors) For example, when the numbers represent values in the cells of a
spreadsheet, their arrangement is called an array. When the numbers represent the colors
of pixels in an image, the term array is again appropriate. The term matrix is strictly
appropriate only when the numbers represent the coefficients in a set of linear equations,
but both matrix and array are sometimes used generically.
It is possible to have three-dimensional arrays in Matlab and even higher dimensions as
well, but few programs employ them. In some applications three dimensions are
appropriate to model the three-dimensional space that we live in. In medical imaging for
example a computed tomography (CT) image of the human body is a three-dimensional
array of intensity values that are high for bone and lower for soft tissue. Magnetic
resonance (MR) imaging similarly produces three-dimensional arrays of intensities. In
some cases a sequence of these images are combined into a four-dimensional array!
Medical image researchers world-wide employ Matlab programs to manipulate CT and
MR images, but most of their programs deal with two-dimensional slices of the threedimensional volumes or of four-dimensional time series. One reason for this
simplification is that humans can visualize two-dimensional arrangements much more
readily than higher dimensions. Another reason is that Matlab is designed for twodimensional arrays and does not handle higher dimensional arrays nearly as smoothly.
Chapter 3
25
Fortunately, most engineering and science applications do not require these higher
dimensional arrays. We will, therefore, focus on the two-dimensional ones. The depiction
below shows that the set of arrays includes all matrices, the set of matrices includes all
vectors, and the set of vectors includes all scalars.
arrays
matrices
vectors
scalars
3.1.1 Complex numbers
Matlab is fully capable of dealing with complex numbers. Complex numbers are
numbers that may include the square root of 1, which is imaginary and is symbolized by
the letter i in mathematics. In Matlab, the imaginary part of a complex number is
indicated by the suffix i or the suffix j:
>> z = 3+4j
z =
3.0000 + 4.0000i
>> z*z
ans =
-7.0000 +24.0000i
Note that Matlab responds with i, instead of j, to indicate the imaginary part of the
complex number.
3.1.2 The colon operator
Chapter 3
26
If we now check the value of X, we see that one element has been changed:
>> X
X =
1.0000
3.4000
2.0000
3.1416
3.0000
7.0000
This notation is closely related to the standard mathematical notation, in which the two
indices are written as subscripts. Thus the mathematical version of Matlabs X(2,3) is
X 2,3 . In general, X(i,j) is the same as X ij (commas are not needed in mathematical
notation when the indices are letters instead of numbers).
More than one element can be specified at a time by using the subarray operations. These
operations access rectangular shaped subarrays within a matrix. They are invoked by
giving a vector of integers for each index. Here are three examples. We use the same that
we started with:
>> X = [1 2 3; 3.4 pi -4]
X =
1.0000
3.4000
2.0000
3.1416
3.0000
-4.0000
3.1416
-4.0000
Chapter 3
27
Y =
1.0000
3.4000
3.0000
-4.0000
3.1416
-4.0000
Subarrays are more often produced by means of the colon operator. Here are the same
three results accomplished with the colon operator:
>> X(2,1:3)
ans =
3.4000
3.1416
-4.0000
>> Y = X(1:2,1:2:3)
Y =
1.0000
3.4000
3.0000
-4.0000
>> Z = X(2,:)
Z =
3.4000
3.1416
-4.0000
When the colon is given alone in the second position, as in X(2,:) above, it means "all
columns." If it were in the first position, e.g., X(:,2), it would mean "all rows."
A convenient notation is provided for telling Matlab that the subarray extends to the end
of a row or column:
>> X(1,2:end)
ans =
2
>> X(end,1)
ans =
3.4000
Chapter 3
28
The colon operator can be used on the left side of the equal sign as well to change
rectangular parts of the matrix. For example,
>> X(1:end,1) = -4.444
X =
-4.4440
-4.4440
2.0000
3.1416
3.0000
7.0000
Note that, although we referenced only the first column of X in the statement, the entire
matrix is printed (if we do not use the semicolon to suppress printing).
1
1
1
1
2
2
2
2
2
2
3
3
3
3
3
3
>> [A; B; C]
ans =
1
1
2
2
3
3
1
1
2
2
3
3
1
1
2
2
3
3
>> [A B C; B B A]
ans =
1
Chapter 3
1
2
2
1
2
2
2
2
2
2
2
2
29
2
2
2
3
1
1
3
1
1
3
1
1
2. Matrices that have the same number of rows can be placed on the same row. For
example, if A = [1;1], B = [2 2; 2 2], C = [3 3 3; 3 3 3] (all
have 2 rows), then the following combinations are legal:
>> [A B]
ans =
1
1
2
2
2
2
2
2
2
2
>> [A B C]
ans =
1
1
3
3
3
3
3
3
3. Matrices that have the same number of columns can be placed in the same column.
For example, if A = [1 1], B = [2 2 ; 2 2], C = [3 3; 3 3; 3
3] (all have 2 columns), then the following combinations are legal:
>> [A; B]
ans =
1
2
2
1
2
2
>> [A; B; C]
ans =
1
2
2
3
3
1
2
2
3
3
Chapter 3
30
2
2
4
4
4
2
2
5
5
5
3
3
5
5
5
3
3
5
5
5
3
3
5
5
5
The "orientation" of a matrix may be changed by transposing it, or taking its transpose,
which means to interchange all its elements so that X(m,n) is replaced by X(n,m). The
operator that transposes a matrix is the transposition operator ' (i.e., one single quote--the one leaning to the right, usually on the same key as the double quote). This operator,
which is also called the transpose operator, comes after the matrix that it operates on:
>> H = [1 2 3; 4 5 6]
H =
1
4
2
5
3
6
>> H'
ans =
1
2
3
4
5
6
The H in the expression H' is termed the operand on which the transposition operator
operates. In fact we use the term operand for any object on which an operation is
performed. (The term is, however, rarely used to refer to the arguments of a function.) An
operator, such as the transposition operator, that applies to only one operand is called a
unary operator. Another example is the unary minus, -H, which negates all elements of
its operand. When the symbol for the operation comes after the operand, as in H', the
Chapter 3
31
operator is said to be a postfix operator. When it comes before the operand as in -H, the
operator is said to be a prefix operator.
There is actually a bit more to the transposition operator. If any of the elements of the
original array are complex, meaning that they have a nonzero imaginary component,
then, during the transposition, each such element is replaced by its complex conjugate,
which means that the sign of the imaginary part is changed. Thus, for example, if we
change the example above slightly, as follows, then the transpose will reveal this
behavior:
>> H = [1 + 2i 2 3; 4 5 6]
H =
1.0000 + 2.0000i
4.0000
2.0000
5.0000
3.0000
6.0000
4.0000
5.0000
6.0000
To take the transpose without taking any complex conjugates, it is necessary to precede
the prime (') by a period (.), or dot, as follows:
>> H.'
ans =
1.0000 + 2.0000i
2.0000
3.0000
4.0000
5.0000
6.0000
Of course if all the elements are real, the two versions of the transpose do the same thing.
Chapter 3
32
Subtraction works similarly. Both + and operate on two operands. We call such
operators binary operators. In Matlab, as in ordinary algebraic notation and as in most
other programming languages, the symbol for a binary operator is placed between the two
operands (i.e., X+Y, instead of XY+ or +XY). Such operators are said to be infix
operators.
Multiplication
Other binary operators include multiplication and division. There are two types of
multiplication---array multiplication, which works like addition, and matrix
multiplication, which is the standard multiplication operation used in linear algebra.
Array multiplication is specified this way, Z = X.*Y. Note again the period, or dot,
before the *. (As we have mentioned before, Matlab, like almost all computer
languages, uses the asterisk to indicate multiplication.) As with addition and subtraction,
array multiplication requires that the two matrices be of the same size. The definition of
array multiplication is as follows:
Z = X.*Y means that for each m and n, Z(m,n) = X(m,n)*Y(m,n)
Array multiplication is useful for the sort of operations that occur in spreadsheets, where
the cells of a sheet correspond to the elements of the array.
Matrix multiplication is specified this way, Z = X*Y (no period this time). It requires
that the number of columns in X be equal to the number of rows in Y. The resulting
matrix, Z, has the same number of rows as X and the same number of columns as Y.
These relationships are illustrated in the equation that follows, where the arrows of the
same color show equal dimensions:
The blue arrows show the inner dimensions of X and Y in the multiplication. The inner
dimensions must be equal or multiplication is impossible. The red and blue arrows show
Chapter 3
33
the outer dimensions of X and Y in the multiplication. The outer dimensions determine
the dimensions of the result. The semantics of matrix multiplication in Matlab is the same
as the standard definition from linear algebra: If the inner dimensions are equal (so that
multiplication is possible), then the definition of matrix multiplication is as follows:
Z = X*Y means that for each m and n, Z(m,n) X(m,k)Y(k,n)
k
where the summation extends over all columns of X (and corresponding rows of Y).
An important special case is when Y is a vector. In that case, Y must be a column vector,
and its number of elements must be equal to the number of columns of X; Z will be a
column vector whose length is equal to the number of rows of X. This case will be
especially important when we take up problems in linear algebra in Chapter 4.
Division
Division in Matlab has four forms---two array forms and two matrix forms. For the array
forms, the sizes of the matrices must be the same. The syntax again includes a period:
Z = X./Y means that for each m and n, Z(m,n) = X(m,n)/Y(m,n)
Z = X.\Y means that for each m and n, Z(m,n) = Y(m,n)/X(m,n)
The two forms of matrix division involve the inverse (or pseudoinverse) of a matrix
and will be taken up in Chapter 4.
Exponentiation
Finally, there are exponentiation operations. Z = X.^Y requires that X and Y have the
same shape. It means that Z(m,n) = X(m,n)^Y(m,n), where the caret, ^, means
"raised to the power of". Z = X^p has several meanings depending on the shapes of Z
and p, but we will consider here only the case in which p is an integer (and a scalar), in
which case X must be square, which means that the number of rows equals the number of
columns. In this case Z is the result of multiplying X by itself p times, using matrix
multiplication. Thus,
Z = X^p means that Z = X*X*X...*X
Chapter 3
34
10
2
4
6
3
6
9
0
0
0
0
0
0
0
0
0
It is clear from our experience with algebra that in the first command above, a and b are
multiplied first. Their product is then added to c. The same sequence is followed for the
second command, even though the plus sign precedes the multiplication sign. On the
other hand, in the third command, because of the parentheses, b and c are added first,
and their sum is then multiplied by a.
We know intuitively what to expect because of our familiarity with these operations, but
Matlab has no intuition. It must follow a set of rules to determine which operation
follows which. It is clear from the first two commands that the order in which the
operations are carried out is not necessarily determined by the order in which they occur
Chapter 3
35
in the command. Instead, the operators are ranked so that some act before others,
regardless of the order in which they appear. From this example, it is clear that * ranks
above + because it acts before +. An operators ranking is called its precedence. Matlab
uses operator precedence to determine the order in which to apply operators in an
expression that includes more than one type of operator. The highest precedence belongs
to parentheses. The precedence of the arithmetic operators, transposition, and the colon
operator (well see other operators later) is given in the table below:
Table 1. Operator Precedence Table:
Precedence
1
2
3
4
5
6
Operator
Parentheses
Exponentiation and Transpose
Unary + and Unary Multiplication and Division
Addition and Subtraction
Colon operator
If more than one set of parentheses occur, then more deeply nested sets operate earlier
than less deeply nested sets, as in ordinary arithmetic expressions. If more than one
multiplication and/or division operator is involved, then the order is left-to-right. The
order in which operators of equal precedence act is called the associativity of the
operators. The associativity of exponentiation, multiplication, division, addition, and
subtraction is left-to-right. Thus, for example,
2^3^4 equals (2^3)^4
2/3*4 equals (2/3)*4
2-3+4 equals (2-3)+4
While left-to-right associativity is common in most languages for these operators, Fortran
employs right-to-left associativity for exponentiation. Its exponentiation operator is **.
Thus the first expression would be written in Fortran this way: 2**3**4, and it would be
equal to 2**(3**4). There is no exponentiation operation in C, C++, or Java. In these
languages x^y is achieved by calling a function: pow(x,y). Thus, for example, in C
and C++, the first expression above must be written as pow(pow(2,3),4). This
construction not only looks confusing but sounds dangerous. Matlabs syntax is much
more natural.
Associativity has another meaning as well. It is a property of some operators. If an
operator has associativity, then the order of application of operators does not change the
outcome. Consider multiplication, for example. (A*B)*C is equal to A*(B*C), and so
multiplication has this property of associativity. It is associative. Consider subtraction, on
the other hand, for which A-(B-C) is not equal to (A-B)-C). Subtraction is not
associative. It does not exhibit associativity.
Chapter 3
36
3.4 Functions
The operations that we have studied so far are based on operators. Another class of
operation is the function, which we defined above in Section 3.1. There we gave just two
examples, sqrt(x) and size(x). Matlab provides many more functionshundreds
of them in fact. The functions that Matlab provides are sometimes called built-in
functions. You will learn later how to write your own functions to add to the set of
functions that is available to you. Functions are always specified by means of their name,
which is an identifier such as sqrt. The rules for a legal function identifier are the same
as those for a legal variable identifier in Matlab, as in most programming languages. (The
rules for Matlab identifiers are given in Section 2.4 above.) The function name is almost
always followed by one or more arguments, separated by commas and enclosed in one
pair of parentheses: function_name(arg1, arg2, , argN). A few functions,
however, can be called with no arguments. In some programming languages, such as C,
C++, and Java, such function calls require that the function name be followed by an
empty set of parentheses, but in Matlab the parentheses are omitted. Here are two
examples of a no-argument call
>> rand
ans =
0.9501
>> rand
ans =
0.2311
The returned numbers here are random numbers uniformly distributed in the range
from zero to one. (The same series of numbers will be produced by this function each
time Matlab is started, so they are not truly random.) This function is useful for testing
programs on arbitrary inputs and for writing programs that simulate systems that behave
in some random way. The function rand serves also as an example of a function that
does not follow the mathematical definition, which requires that its output depends only
on its input. For rand the output depends on the number of times it has been called since
Matlab was started (other ways to alter its behavior are described by help rand.)
Most functions are designed to be used as part of an expression. The value that the
function returns is then used by the expression. For example,
>> x = 2 + sqrt(4 + 5);
Chapter 3
37
will cause the value 5 to be assigned to x. Here 4 + 5 gave 9, and sqrt, which gives
the positive square root of its argument, returned the value 3. That 3 was added to 2 to
give 5, which was assigned to x.
Before we continue discussing functions whose values are used in expressions, it is
helpful to describe some functions that are used to build special matrices. Table 3.1 lists
the most important ones.
Table 2. Matrix-Building Functions
Function
zeros(n,m)
ones(n,m)
eye(n,m)
rand(n,m)
Returns an n by m matrix of
Zeros
Ones
Zeros except that diagonal elements equal 1
Random numbers uniformly distributed in the range
from 0 to 1
randn(n,m) Random numbers normally distributed with mean
equal to 0 and variance equal to 1
For example, zeros(n,m) returns an n by m matrix, all of whose elements equal zero.
Similarly, ones(n,m), returns n by m ones. An interesting function is eye(n,m),
which returns an n by m matrix that has all zeros, except for those elements on the
diagonal, which are equal to one. The diagonal of a matrix is the set of elements whose
indices are equal to each other. Thus, in the matrix M, the diagonal elements are
M(1,1), M(2,2), . Why is it called eye? Well, thats because eye(n,n)
produces an identity matrix, whose symbol in mathematics is I (pronounced eye, get
it?). An n by n identity matrix can be multiplied by any other n by n matrix X, and the
result is X:
I = eye(3,3)
I =
1
0
0
0
1
0
0
0
1
2
5
8
3
6
9
Chapter 3
38
ans =
1
4
7
2
5
8
3
6
9
2
5
8
3
6
9
>> X*I
ans =
1
4
7
Polymorphism
In the example above, the argument to sqrt was a scalar, which is a 1-by-1 array (Note:
We will use the terms array and matrix interchangeably when referring to variables). We
could have given sqrt an array of any size and shape as an argument. Its behavior in
that case is to return an array of the same size and shape, such that each element of the
result is equal to the square root of the corresponding element of the argument. Thus, if X
is a 3x4 array, then Y = sqrt(X) results in Y(m,n) = sqrt(X(m,n)) for all
elements of X.
In the general study of programming languages, when the type of an argument used in a
function can vary (as for example, from a scalar to a vector to a matrix) from one call of
the function to the next, the function is said to be polymorphic. (The term polymorphic
means having multiple forms, which matches its definition, since it means that the
function call can have more than one form.) The characteristic of being polymorphic is
called polymorphism. (An alternate terminology is to say that the functions arguments
are polymorphic, but the idea is the same.) As can be seen from the sqrt example
above, Matlab's support for polymorphism is very powerful, and it makes it possible to
handle a huge variety of situations (e.g., a huge variety of different matrix shapes) with
relatively few functions. It makes it possible for Matlab to do a great deal of work very
efficiently (i.e., quickly) with very few statements. Polymorphism is not supported by the
most popular older languages, such as Fortran, C, Pascal, and Basic. Many modern
languages, on the other hand, such as Ada, C++, Java, and other so-called "objectoriented" languages (and even a few of the older languages, such as LISP) do provide
support for polymorphism. It is in fact a major feature of these languages, just as it is a
major feature of Matlab.
Unlike most of the other modern languages that support polymorphism, Matlabs typical
function returns an object that is the same shape as the argument that it is given. For
example, if f is a typical function, then for y = f(x), if the value of x is a scalar, then
a scalar value will be returned into y. If x contains a matrix of dimensions m by n, the
Chapter 3
39
value returned into y will also be an m by n matrix. When the function allows two or
more arguments of different types, the returned type will vary according to the function.
Returning an object whose shape is the same as the argument is not always appropriate,
however. For example, the function sum, when given a row or column vector, returns a
scalar that is equal to the sum of the elements of the vector:
>> v = [1 -3 5 10];
>> sum(v)
ans =
13
When sum is given a two-dimensional matrix, it calculates the sum for each column of
the matrix and returns a row vector of those elements;
>> M = [1 10 100; 2 20 200; 3 30 300]
M =
1
2
3
10
20
30
100
200
300
60
600
>> sum(M)
ans =
6
Chapter 3
40
The argument M in this call is the same matrix as used above, but this time the summation
is carried out along each row, and the resulting sums are put into a column vector. The
second argument tells sum which dimension it is to sum over and whether to return a row
vector (second argument equal to 1) or column vector (second argument equal to 2).
Since the second dimension is the row index, the call sum(M,2) means to sum across
the rows. The call sum(M,1) means to sum over the column index, so it returns the
same vector as that returned by sum(M) above. Thus, the second argument is optional,
and if it is omitted, the default dimension is 1. When we describe functions in this book,
we will not always list all the optional variables, but you can always learn whether there
are optional arguments and their meanings by using help.
In this example max returned one object, the number 4, which is the largest element, but
max can do more, as shown in the next example:
>> [a b] = max([1 4 -5 0])
a =
4
b =
2
In this example, max returned two objects. The first one is the maximum value; the
second one is the index of the element that contained the maximum value. The two
variables, a and b, in brackets on the left side of the equal sign in the call to max are
called output arguments in Matlab. This ability to return more than one object is an
important feature of Matlab, and that feature is lacking in the major general-purpose
languages: Ada, C, C++, Fortran, Java, and Pascal. Furthermore, the ability to call such a
function in different ways so that it returns different numbers of output arguments is a
third type of polymorphism, and Matlab is one of the very few languages that provides it.
Note that some Matlab functions return a vector that contains more than one object.
Returning a vector is not equivalent to returning more than one object. The size
function, which we encountered in Section 3.2, is such a function. It returns one object,
which is a two-element vector. The first element is the number of rows of the argument;
the second is the number of columns. When only one object is returned by a function, it is
possible to capture it in one variable, as in the following example, in an individual
variable. The syntax is obvious from the following example,
>> v = size([1 2 3; 4 5 6]);
Chapter 3
41
>> v
v =
2
As can be seen from the examples above, because max returns two objects, it is not
possible with max to capture both the maximum value and the index in a single
variable. Matlab does, on the other hand make it possible to capture the two elements of
the vector returned by size in two separate variables, as follows;
>> [m n] = size([1 2 3; 4 5 6])
m =
2
n =
3
The number of functions provided with a Matlab installation is huge, and many more are
available from the Internet. You have seen a few of them in these tutorials and in Table 2.
In Table 3 through Table 8 below you will find a few more of them. (Soon you will learn
how to write your own functions.) To learn more about them and to learn the names of
many more functions use Matlabs help facility.
Table 3. Trigonometric Functions
Function
acos(x)
acot(x)
asin(x)
atan(x)
atan2(x,y)
cos(x)
cot(x)
sin(x)
tan(x)
Returns
Angle in radians whose cosine equals x
Angle in radians whose cotangent equals x
Angle in radians whose sine equals x
Angle in radians whose tangent equals x
Four-quadrant inverse tangent of x
Cosine of x (x in radians)
Cotangent of x (x in radians)
Sine of x (x in radians)
Tangent of x (x in radians)
Table 4. Exponential Functions
Function
exp(x)
log(x)
log2(x)
log10(x)
sqrt(x)
Returns
e raised to the x power
Natural logarithm x
Base-2 logarithm of x
Base-10 logarithm of x
Square root of x
Function Returns
abs(z) Absolute value of z
Chapter 3
Phase angle of z
Complex conjugate of z
Imaginary part of z
Real part of z
Table 6. Rounding and Remainder Functions
Function
fix(x)
floor(x)
ceil(x)
round(x)
rem(x,n)
sign(x)
Returns
Round x towards zero
Round x towards minus infinity
Round x towards plus infinity
Round x towards nearest integer
Remainder of x/n (see help for case of noninteger n)
1 if x>0; 0 if x equals 0; -1 if x<0
Function
length(v)
max(v)
min(v)
mean(v)
median(v)
sort(v)
std(v)
sum(v)
Returns
Number of elements of v
Largest element of v
Smallest element of v
Mean of v
Median element of v
Sorted version of v in ascending order
Standard deviation of v
Sum of the elements of v
Function
max(M)
min(M)
mean(M)
median(M)
size(M)
sort(M)
std(M)
sum(M)
42
Chapter 3
43
that Matlabs command window uses a very simple prompt: >>. In the programs that you
will write, a prompt may be more like a sentence, but regardless of the form of the
prompt, the user must respond to it by typing something and hitting the Enter key. All
this is accomplished in a Matlab program by means of the input function. For example,
if the M-file containing a Matlab program includes the command,
fave = input('Please type your favorite vector: ');
When this command is reached, the program will print in the command window,
Please type your favorite vector:
and will wait until the user types in something. Note that there must be single quotes
around the prompt. Characters inside single quotes in Matlab make up a string. The term
string is used in programming languages in general to mean a sequence of characters. A
string is useful anytime Matlab, or any other programming language, needs to store or
display meaningful words, phrases, or sentences in a spoken language. (We will see later
that Matlab provides many special purpose operations for strings. It stores a string as a
one-dimensional array of characters.)
While Matlab is waiting for input, a vertical bar (|) will blink on and off just to the left of
the space into which the user is about to type a response. Note that the prompt above
ended with a blank character (the space between the colon and the single quote). This
blank is "printed" after the colon, meaning that when the user types in a response, there
will be one space between the colon and the first character of the response. If that space is
omitted, Matlab will not include it for you.
Suppose the user types, not a vector, but the matrix [1 2; 3 4]. Then the interaction
would look like this:
Please type your favorite vector: [1 2; 3 4]
The result is that fave would be given the value [1 2; 3 4]. Note that Matlab pays
no attention to what is written in the prompt string. Regardless of the type of the object
that the user types in---a scalar, a complex number, a vector, a matrix, or even a string---it
will be accepted. The fact that the prompt specifies a vector is of no consequence.
Chapter 3
44
This method of communication is workable for simple programs, but Matlab provides a
far more sophisticated means for printing information by means of a function, borrowed
from the languages C and C++, called fprintf. Its name stands roughly for formatted
printing to a file, and the function is versatile enough to allow us to print either to the
Command Window or, as we will see later, to a file. It requires at least one argument. Its
first argument (when it is being used to print to a file, it is the second argument) is a
string that specifies the format, such as the number of decimal places, of its output to the
command window. A string is simply a sequence of characters. To indicate to Matlab
that a sequence of characters is not to be interpreted as the name of a variable or function,
it is started and terminated with the single quote symbol ('). In that format string, the
format of each value that is to be printed is specified individually. So, for example, one
value may be printed with 4 decimal places and another with 9. Additionally, any text
that is to be printed along with the values is included in that format string. Values that are
to be printed are given as arguments, in the order that they are to be printed, following the
format. For example,
>> fprintf('No.: %d, cost= %5.2f.\nTotal is %7.3f\n', 4, 3.1, 4*3.1);
No.: 4, cost= 3.10.
Total is 12.400
The meaningful sequence of characters that begins with an escape character is called an
escape sequence. Another escape sequence is \n, which means "go to a new line". The
backslash, which we identified earlier as one of the division operators, has a different
meaning when it occurs inside a string. Here is an escape character. The special meaning
of n is "newline". To print a backslash use two of them: \\. To print a single quote, use
two of them: .
Chapter 3
45
Format Specifier
c
d
e
E
f
g
G
o
s
u
x
X
Description
single character
decimal notation (but no decimal if integral)
exponential notation
exponential notation with an upper case E
fixed-point notation
shorter of e or f
shorter of e or f but with an upper case E
unsigned octal notation
string
unsigned decimal notation
hexadecimal notation
hexadecimal notation with uppercase
Partial use and recycling of the format string and matrix arguments
If the number of arguments to be printed (i.e., those after the format string) is smaller
than the number of percent signs in the format string, then the printing will stop just
before the first unused percent sign is encountered. If there are more arguments to be
printed than percent signs, the format string will be recycled repeatedly until all of the
arguments are printed. If any or all of the arguments is a matrix, then the printing will
behave as if the matrix were replaced by its elements written as separate arguments in
column-major order.
Imaginary parts ignored
A strange limitation to fprintf is that it cannot be used to print complex numbers
properly. If a complex argument is given to it, fprintf will ignore the imaginary part!
To print complex numbers, you may use another function called disp. For example,
>> z = 2 + 3i;
fprintf('z = '); disp(z);
z =
2.0000 + 3.0000i
Alternatively, you can extract the real and imaginary parts of a complex number by using
the functions real and imag. The following example reveals how it can be done:
>> fprintf('z = %.2f + %.2fi',real(z),imag(z))
z = 2.00 + 3.00i
Chapter 3
46
3.7 Plotting
Matlab has an extremely powerful plotting facility, which is supported by functions,
including plot, title, xlabel, ylabel, grid, semilogx, semilogy,
loglog, and many others. With these functions it is possible to (a) plot more than one
function at a time on a given plot, (b) select distinct symbols, called "markers", for
distinct plots, (c) select distinct colors for distinct plots, (d) print a title with a plot, (e)
label the axes, (f) provide a "graph-paper" grid, (g) change one or both axes to be scaled
according to the logarithms of the values. Many other options are available, including
three-dimensional plotting.
You have already seen the basic approach to plotting. The idea is to create two vectors of
the same length and give them as arguments to plot. Thus, if x and y are two vectors
of length N, then plot(x,y) produces a plot of N points with x giving the horizontal
positions and y giving the vertical positions. It is easy to extend this idea to put more
than one plot in a figure because plot is polymorphic. It accepts a varying number of
arguments. For example,
>> x1 = 0:0.1:2*pi;
y1 = sin(x1);
>> x2 = pi/2:0.1:3*pi; y2 = cos(x2);
>> plot(x1,y1,x2,y2)
Chapter 3
47
The vector y1 is plotted versus the vector x1 and the vector y2 is plotted versus the vector
x2, separately on the same set of axes. The ranges of the x and y axes are automatically
chosen to encompass all the values in the vectors. Any number of pairs of vectors may be
given to plot. It will plot them all on the same set of axes.
It can be seen from the figure that the color blue is used for the first plot and the color
green for the second plot. It is possible to alter the appearance of the plots by using
additional arguments in the form of strings. For example, the command
>> plot(x1,y1,'r',x2,y2,'k:')
The string r means red. The string k: means black, dotted (k means black; the
colon means dotted). One, two, or three character strings can be included optionally for
every pair of vectors to be plotted. Table 10 gives a list of possible symbols and their
meanings. A few additional line styles can be found by using help plot.
It is also possible to plot more than one function on the same axes by means of
sequential plot functions by means of the command hold. Once the command hold on
has been issued all subsequent plots will be made on the same axes with the ranges of the
axes being adjusted accordingly. When the command hold off is issued, all
Chapter 3
48
subsequent calls to plot will employ a new figure. The command hold (not followed by
on or off) can be used as a toggle to turn plot holding on or off. Thus, the following
commands could be used to produce the same plot:
>>
>>
>>
>>
hold on
plot(x1,y1,'r')
plot(x2,y2,'k:')
hold off
There are additional options, not reachable through the plot command that will enhance
the visual quality of a plot. The command grid turns on a graph-paper like grid.
Repeating the command turns it off. The grid command affects only the currently active
figure. (The active figure is the one most recently created or the one which has received
the most recent mouse click, whichever happens last.)
Table 10. Symbols Used to Alter plot Format
Symbol
b
c
g
k
m
r
y
w
Color
blue
cyan
green
black
magenta
red
yellow
white
Symbol
.
o
x
+
*
s
d
:
-.
--
Line Style
point
circle
cross
plus
star
square
diamond
solid (default)
dotted
dashdot
dashed
A plot can be adorned with a title at the top and labels along the x and y axes by means of
the functions,
>> title(string)
>> xlabel(string)
>> ylabel(string)
each of which takes a single string (the label) as an argument. So, for example, string
might be My nifty title, or it might be the name of a variable that contains a
string as its value. It is also possible to change the ranges of the axes with the function
axis, which accepts a single four-element vector as its argument:
>> axis([xmin xmax ymin ymax])
Chapter 3
49
can be used. Notice that this command does not have the form of the normal function
with arguments in parenthesis. Another use of the axis command is to alter the relative
lengths of the x and y axes match. The command
>> axis square
will make the length of the axes be equal, resulting in a square plot area. The command
>> axis equal
will adjust the axes so that equal tick mark increments on the x-,y- and z-axis are equal
in for x and y. To see other uses of the command, use help axis.
Here is an example of the use of all these functions after the previous plot has been
displayed:
>>
>>
>>
>>
>>
grid
title('A Sine Plot and a Cosine Plot');
xlabel('The argument of sine and cosine');
ylabel('The value of the sine or cosine');
axis([-2 12 -1.5 1.5])
Chapter 3
50
Finally, here is fancy plot that uses all these options. Six plots are done simultaneously,
each in a different color:
Chapter 3
51
Chapter 3
Matlab:
o matrix
o scalar
o function
o argument
o vector
column vector
row vector
o complex numbers
o colon operator
o subarray operations
o combining matrices
o transposition
o matrix operations and array operations
o operator precedence and associativity
o important functions
building matrices
trigonometric
exponential
complex number analysis
rounding and remainder
descriptive
o polymorphism
o returning more than one object with output arguments
52
Chapter 3
53
Chapter 4
Linear Algebra in Matlab
Mathematical problems involving equations of the form Ax=b, where A is a matrix and x
and b are both column vectors are problems in linear algebra, sometimes also called
matrix algebra. Engineering and scientific and disciplines are rife with such problems.
Thus, an understanding of their set-up and solution is a crucial part of the education of
many engineers and scientists. As we will see in this brief introduction, Matlab provides a
powerful and convenient means for finding solutions these problems, but, as we will also
see, the solution is not always what it appears to be.
Chapter 4
55
A11 x1
A21 x1
AM 1 x1
A12 x2 ...
A22 x2 ...
AM 2 x2 ...
A1N xN b1
A2 N xN b2
AMN xN bM
(4.1)
where the Aij are the elements of the M-by-N matrix A, the x j are the elements of the Nby-1 column vector x, and the bi are the elements of the M-by-1 column vector b. This
set of equations is sometimes written in tableau form to indicate more clearly the
relationship between the matrix form and the equation forms and to show shapes of the
arrays:
A11 A12
A
21 A22
A
M 1 AM 2
...
...
...
...
...
...
A1N
b1
b
A2 N
2
x1
x2
x
N
b
AMN
M
(4.2)
Note that, despite the row-like arrangement of the x j in Eq. (4.1), x is in fact a column
vector. Note also that the length of x is N, which is always equal to the width (not the
height) of A. The length of b is M, which is always equal to the height of A. We have
formed this tableau to indicate clearly that it is a case in which there are more equations
than unknowns. In other words M>N. While it is more common to have M=N, in which
case the height of the x vector in Eq. (4.2) is the same height as A and b, in many
situations M is in fact larger than N. The third situation, in which N<M, is far less
common.
Typically the Aij and bi are given, and the x j are unknown. The equations are
simultaneous because one set of xi must satisfy all M equations simultaneously. They
are linear because none of the xi is raised to any power other than 1 (or 0) and there
are no products xi y j of unknowns. When A and x are given, the problem is relatively
easy, because finding b requires only matrix multiplication. The number of unknowns
Chapter 4
56
(i.e., the length of b) is always equal to the number of equations (otherwise Ax cannot
equal b), and typically the elements of b are not highly sensitive to small errors in A or x.
More often, however, the problem confronting us is to find x when A and b are given.
This problem is much more difficult and is the subject of many books and many courses.
5
-2
(1.3)
Chapter 4
57
3.5652
-1.6522
Note that, as always, the number of rows of A is equal to the number of rows of b. (The
number of columns of A is also equal to the number of rows of b, but that equality is not
necessary).
We can check the result to make sure that it solves the equation:
>> A*x
ans =
6
14
Since the elements are the same as those of the vector b, we can see that Eqs. (1.3) have
both been solved simultaneously by the two values x1 3.5652 and x2 1.6522 .
Another way to check is to look at the difference between A*x and b:
>> A*x - b
ans =
0
0
Since the difference between each element of A*x and the corresponding element of b is
zero, we see again that Matlab has given us the solution.
As we mentioned at the beginning of this chapter, we will soon see that there are some
situations in which the result given by A\b does not solve the equations or, while it
solves the equations, the solution is not trustworthy. In those cases, Matlab may warn
you, but not always. Such situations can cause serious trouble if the user does not know
what is going on. The trouble is not the fault of Matlab. It is the fault of the user who is
solving problems in linear algebra without knowing enough about linear algebra, or
perhaps the fault of the instructor who failed to teach the user enough about linear
algebra! We will learn below when this will happen and why it happens, and we will
learn the meaning of the result that Matlab gives us in these situation.
In the problem above there were two equations in two unknowns. Because there were two
equations, there were also two rows in both A and b. Because there were two unknowns,
the number of columns of A was also 2 and the resultant answer x had a length of two.
Problems such as this one, in which there are N equations and also N unknowns, are the
most common linear algebraic problems that occur in all of engineering and science.
Chapter 4
58
5 x2
5 x2
6
12
(1.4)
Clearly this pair of equations is inconsistent. A plot of the lines represented by each of
the equations will reveal that they are parallel. Thus, they never intersect. If we try to
solve this pair of equations using Matlab, it will issue a warning that the matrix is
singular and will give as its answer Inf for each element of x. Inf is a special value
that means infinity and is simply a sign to the user in this case that the solution is
meaningless.4
(1.5)
Here we have given only the first equation from Eqs. (1.3), so M = 1 and N = 2. If we
solve this equation for x2 , we get x2 (4 x1 6) / 5 . This relationship shows us that we
can choose an infinite set of values of x1 from to , as long as we choose the right
x2 to go with it. If Matlab is asked to solve for x in this situation, it will find one, and
only one, of the infinite solutions5:
>> A = [4 5]; b = 6;
4
This situation and many other special situations are discussed in books on the subject of numerical
analysis, such as, Numerical Analysis by R. L. Burden and J. D. Faiers, Brooks/Cole, 1997.
5
How does Matlab decide which of the infinite choices to give you? It chooses one for which as many of
the elements as possible are equal to zero. If there is still more than choice, it chooses the one for which the
norm of the solution vector is minimal.
Chapter 4
59
>> x = A\b
x =
0
1.2000
Inadequate information can sometimes occur when M=N and even when M>N. This
happens when the information in some of the equations is redundant. For example, it
happens for these three equations:
4 x1
5 x2
8 x1
10 x2
12
5
x2
2
2 x1
(1.6)
There is no more information in Eqs. (1.6) than there is in Eq.(1.5). That reason is that
each of the second and third equations can be obtained from the first by multiplying all
terms by the same number (2 for the second equation and -1/2 for the second). Thus, any
two of these equations are redundant relative to the third. The set of solutions to these
three equations is the same infinite set of solutions that solve Eq. (1.5).
Chapter 4
>>
>>
>>
>>
>>
>>
60
x2b = (3*x1-14)/2;
plot(x1,x2a,x1,x2b)
grid on
xlabel('x1')
ylabel('x2')
legend('x2a','x2b')
The resulting plot is shown below. It can be seen that the two lines cross at approximately
the point (3.6, -1.7). Their intersection is the lone point at which both equations are
satisfied. In other words, it is the solution of the simultaneous equations. We solved these
equations when we encountered them before by using x = A\b. We found that x(1),
which corresponds to x1 , equals 3.5652, and x(2), which corresponds to x2 , equals
1.6522 . These values can be seen to agree with the intersection point in the plot.
Thus, for the case of two equations in two unknowns, Matlab gives us the exact (to within
some small round-off error) solution. We can study a case in which there are more
equations than unknowns by considering the following set of equations:
4 x1 5 x2 6
3 x1 2 x2 14
7 x1 x2 25
(1.7)
Chapter 4
61
which are the same equations as Eqs. (1.3) plus one more. We can plot these three
equations using the commands above plus these additional commands:
>> x2c = 7*x1 -25;
>> hold on
>> plot(x1,x2a,x1,x2b,x1,x2c)
While it appears that the three lines cross at a point, in fact they do not. To get a better
look, we can click on the magnifying-glass icon (just below the word Help at the top of
the figure window) and then click a few times near the area where the lines appear to
cross. Under magnification we will see that the lines do not in fact all cross at the same
point, which means that there is no solution to Eqs (1.7). Nevertheless, can ask Matlab to
try to solve them as follows:
>> A = [4 5; 3 -2; 7 -1]
A =
4
3
7
5
-2
-1
Chapter 4
62
=
6
14
25
>>
x = A\b
=
3.4044
-1.5610
The
resulting
solution
point can
plotted on
same
graph
be
the
>>
>>
plot(x(1),x(2),'k*')
hold on
The resulting plot (after magnification) shows that Matlab has chosen a point that comes
close to all three lines.
The errors in the solution can be seen by comparing A*x to b:
>> error = A*x-b
error =
-0.1875
-0.6647
0.3920
If the solution were exact, all three elements of error would be zero. If an exact
solution did exist (i.e., if all three lines crossed at the same point), Matlab would have
given us that solution. In all other cases, Matlab gives that solution for which the sum of
the squares of the elements of error is as small as possible. This value can be
Chapter 4
63
calculated using Matlabs built-in function norm(x) which gives the square root of the
sum of the squares of the elements of x:
norm(x)
2
i
There are other norms, each of which measures the size of the vector in some sense (try
help norm), but this is the most common and most useful one. In this case we find that
norm(error) gives the value 0.7941. We can try other values for x. Each of them will
produce a nonzero error, and the norm of the error will always be greater than 0.7941. A
solution for which norm(error) is as small as possible is called the optimum solution
in the least-squares sense.
Chapter 4
64
conditioning depends on both A and b, but it is possible to have a matrix A for which the
problem is well behaved for any b.
To study the phenomenon of ill conditioning, we will consider the following two
equations:
24 x 32 y 40
31x 41y 53
We calculate a solution to these equations using x = A\b as usual and we find that x =
7 and y = 4. If we perturb the values of b slightly to 40 and 53.1, we find that x = 7.4 and
y = 4.3. While these may not seem to be significant changes it is interesting to make
some relative comparisons. Lets define the following convenient quantities:
We will use the norm as a measure of the size of some of these vectors, and we will
examine the ratio of some of them. In particular, we find that
rel_input_error
norm(db)
0.0015
norm(b)
rel_output_error
norm(dx)
0.0620
norm(x)
and
These two quantities represent the fractional change, respectively, in the sizes of b and x
resulting from the addition of db to b. This addition represents a possible imprecision or
error in the measurement. Because b is given, we call it the input (A is input as well, but,
as we mentioned above, we are not considering the effects of errors in its determination.)
Because x is calculated, we call it the output. This is the situation that would arise if
errors in the measured values of the elements of b were to change by the amounts in db.
These errors would result in the changes in x represented by dx. The fractional changes
represent the seriousness of the changes in comparison to the quantities that are changing.
In this case a 0.15% change in b results in a 6.2% change in x. Neither of these changes
seems impressive, but their ratio is. The relative change in x is 6.2/0.15, or 41 times
larger than the change in b. Thus the percent error is increased by over four thousand
percent! By comparison, if we perturb b for the first set of equations that we studied in
this section from 6 and 4 to 6 and 4.1 and do a similar calculation, we find that the
percent error is increased by a factor of only 1.1. This second situation is far more stable
then the former one.
Chapter 4
65
Matlab provides a function to help you detect ill-conditioned problems. The function is
called cond. To use it, one simply calls cond on the matrix A. If cond(A) returns a
large value, then A is ill-conditioned; otherwise it is not. The number returned by cond is
called the condition number of A. Its precise definition is as follows: For any input vector
b and any perturbed input vector bp:
Matlab:
o b = A*x
o x = A\b
o Inf
o norm(x)
o cond(A)
Chapter 4
66
Chapter 5
Top-down Design and Branching Statements
This chapter introduces a systematic method for designing programs called top-down
design, and it also introduces a new class of programming statements, called
branching statements. The two are related because branching statements are often used
in the design method. We begin by considering the design method. It is one of many
methods developed by the researchers in program design who deal with large and
complex problems. Their discipline is called Software Engineering.
Chapter 5
67
time, money, and even lives. One of the design techniques developed by software
engineers is called top-down design. It is that technique that we present in this chapter.
Chapter 5
68
reducing the required number of steps or the required amount of computer memory to
solve the problem can be accomplished much more efficiently at this stage than during
the coding stage. For that reason, skill in algorithm design is often considered to be the
most important skill in computer science. It can be seen also from the five-step approach
above that both decomposition and stepwise refinement, which are the essential aspects
of top-down design involve only algorithm design. They are not part of the conversion to
a program.
Pseudocode
Thus, the top-down design phase comprises steps 1-3. If this phase is done well, then the
actual writing of the code, which is done in step 4, is relatively straight-forward. It is
especially easy if the designer is skilled in the writing of pseudocode, which is a
combination of English (or French, German, Chinese, or whatever your native language)
and Matlab (or C, C++, Java, Fortran, or whatever target programming language is to be
used for the programming). The first two steps are often said to describe a black box,
which is any system whose inner workings are unknown but whose inputs and outputs are
known. The overall process, which starts with inputs and produces outputs, is known too,
but the manner in which it is implemented (e.g., by a Matlab program) is not. In fact
State the problem, is equivalent to describe the overall process that is to be
implemented. There is rarely any pseudocode used in that description. The pseudocode
is used primarily in step 3, and it becomes more Matlab-like (assuming now that we are
programming in Matlab) with each refinement.
An iterative process
While it is not explicit in the five-step approach shown above, top-down design is an
iterative process. (In fact any design technique is iterative.) In step 3b above,
refinement implies that this step is iterated (repeated) until the subproblems reach the
elementary stage described above, in which further refinement is no longer necessary.
This iteration may involve only two or three steps, or for more complex problems it may
involve dozens of steps. We will see below that there is another need for iteration, a need
caused by errors that the designer makes during the design process. What follows is a
very simple example of an application of the five-step approach to top-down design.
Chapter 5
Matlab
M = input('Please give a 3x3 matrix ');
code
x = input('Please give a 3x1 vector ');
y = M*x;
output = y(1) + y(2) + y(3);
fprintf('\nThe sum of the elements is %f\n',
output);
69
Chapter 5
70
Design Errors
One major difference between the example shown above and actual experience is that the
example is perfect: The designer made no mistakes in steps 1-4, nor did the programmer
(the same person in this case) make any mistakes in step 4. Thus, step 5 revealed no
errors. A more typical situation would find errors in all steps! Syntax errors, which are
made in step 4, will be caught by Matlabs interpreter during step 5. An example might
be writing y = Mx instead of y = M*x. These errors are easy to correct. The more
difficult problems are those caused by semantic errors in steps 3 and 4. Such errors will
cause the program to produce incorrect errors, but are not noticed by the interpreter. In
other words, the program will run, but it produces incorrect results. An example might be
writing output = y(1) + y(1) + y(3). Semantical errors must be caught
during step 5. When such errors are noticed, it is necessary to return to the step where
they first appeared, correct them there, and retrace the design from that point. An
important aspect of step 5 is the test data used as input. That input must be chosen
carefully so as to catch as many errors as possible. For example, the input given above
would not catch the semantical error given here because y(1), y(2), and y(3) are all
equal.
Thus, as mentioned above, the design process is an iterative one for two reasons. Within
step 3, stepwise refinement requires that problems be repeatedly broken into simpler
subproblems. That makes the process iterative, but, in addition, when errors are made
during the design process, some of the steps must be repeated to correct the errors. Most
of the time the repeated steps are 3 and/or 4.
Chapter 5
71
fprintf('Nice choice!\n');
end
These lines will cause Thanks for your positive response! to be printed if the user
inputs a positive number. If the user types 0, then x will be immediately changed to 2 and
the program will print, Zero is not allowed. I changed it to 1. (Some programs tell
lies! There is a bug in this program.) If the user types a negative number, the message
Nice choice will be printed instead. The following diagram, called a flow chart,
depicts schematically the flow of control through these statements:
if
x > 0
True
False
elseif
x == 0 True
x = 2;
False
'Zero is not
allowed. I changed
it to 1.\n'
else
'Nice
choice!\n'
Chapter 5
72
defined by the language to have special meaning. By default the Matlab editor highlights
its keywords in blue. We have also done that below to make the statement structure a bit
clearer. The elseif clause and/or the else clause may be omitted, leaving
if
conditional
or
if conditional
or
if conditional
block
else
block
end,
block
elseif
conditional
block
end.
block
end,
Furthermore, additional elseif clauses may be added (no limit). In all cases, no more
than one block will be executed by an if construct. If there is no else clause, then, if
none of the conditionals are satisfied, all of the blocks will be skipped and the if
statement will do nothing. If there is an else clause, however, it is guaranteed that one
block will be executed. Each part of the if construct must begin on a new line or be
separated from the previous part by a comma or semicolon. The semicolon suppresses
printing as usual.
Matlab has a second form of the selection statement called the switch statement, or
switch construct:
switch switch_expression
case case_expression,
block
case case_expression,
block
. . .
otherwise
block
end
Here switch_expression is any scalar or string and case_expression is any Matlab
expression. The flow of the switch construct is the same as that of the if-statement
depicted above. Exactly one block will be executed by the code above. It will be either
the first block whose case expression equals the result of the switch expression or, if none
of the case expressions equal the switch expression, then the block between otherwise
and end will be executed, much like the else clause at the end of the if-statement. The
otherwise clause may be omitted. If so, then it may be that no block is executed, so,
as for the similar case with the if-statement, the switch-statement will do nothing. The
commas may be replaced by semicolons. If the block starts on a new line, as in the layout
above, neither a comma nor a semicolon is required.
The switch-statement and the if-statement are equally powerful (each can do what the
other can do), but the switch-statement is especially well suited to handle cases with only
a finite set of choices For example, the following two pieces of Matlab code below are
equivalent, but the switch statement is easier to read and matches the task better:
Chapter 5
73
if x == 1
fprintf('One');
elseif x == 2
fprintf('Two');
elseif x == 3
fprintf('Three');
else
fprintf('%d', x);
end
switch x
case 1
fprintf('One');
case 2
fprintf('Two');
case 3
fprintf('Three');
otherwise
fprintf('%d', x);
end
There is one alternative method of specifying cases in the switch construct. Any
case_expression may be replaced by a list of case expressions in braces:
case {case_expression_1,case_expression_2,},
block
The meaning is that if the switch expression matches any of the case expressions in the
list, the block will be executed.
Operator Meaning
Chapter 5
74
is equal to
is not equal to
is greater than
is less than
is greater than or equal to
is less than or equal to
==
~=
>
<
>=
<=
that does not equal zero will be treated as true by the if construct (i.e., it does not have
to be 1). Thus the statement
if 14; x = 5; end;
will cause x to be assigned the value 5 because the conditional evaluated to non-zero (-14
is non-zero), which means true.
Expressions involving relational operators can appear anywhere. So for example,
fprintf('The value of 1 > 0 is %f \n', 1 > 0);
fprintf('The value of 1 < 0 is %f \n', 1 < 0);
Conditionals may also involve the so-called logical operators. These operators are given
in Table 12
Table 12. Logical Operators
Operator Meaning
&&
and
||
or
~
not
The not operator is a unary prefix operator, which means that it takes only one operand
and it comes before its operand. If its operand equals zero, which represents falsehood, its
output is 1, which, since it is nonzero, represents truth. Thus ~0 equals 1 and ~1 equals
0. The other two logical operators are binary infix operators, which means that, like +, -,
*, /, and \, they each take two operands and they come between their operands. For
example, x && y and x || y are logical expressions involving these two operators.
Expressions involving these operators always return 1 for truth and 0 for falseness,
exactly as do the relational operators. The outputs of these two logical operators and
Chapter 5
75
those of the related function xor (exclusive or) are given for all possible inputs in
Table 13.
Table 13. Logical Operators
&& || xor
Inputs
0
0
0
0
0
0
non-zero 0
1
1
non-zero
0
0
1
1
non-zero non-zero 1
1
0
Here are some examples of both the relational operators and logical operators in action.
The following statements:
fprintf('The
fprintf('The
fprintf('The
fprintf('The
fprintf('The
value
value
value
value
value
of
of
of
of
of
(1>0) &&
(1>0) &&
(1>0) ||
(1<0) ||
~(1>0)
(2>1)
(2<1)
(2<1)
(2<1)
is
is
is
is
is
%d
%d
%d
%d
%d
\n',
\n',
\n',
\n',
\n',
(1>0) &&
(1>0) &&
(1>0) ||
(1<0) ||
~(1>0)
(2>1)
(2<1)
(2<1)
(2<1)
);
);
);
);
);
value
value
value
value
value
of
of
of
of
of
(1>0) &&
(1>0) &&
(1>0) ||
(1<0) ||
~(1>0)
(2>1)
(2<1)
(2<1)
(2<1)
is
is
is
is
is
1
0
1
0
0
If one thinks of 1 and 0 as true and false, all these answers make sense. The three logical
operators and xor() each treat their arguments as if zero represents falsehood and
anything else (i.e., nonzero) represents truth. Thus,
fprintf('The
fprintf('The
fprintf('The
fprintf('The
value
value
value
value
of
of
of
of
~0
~14
3 && -1
sqrt(11) | 0
value
value
value
value
of
of
of
of
~0
~14
3 && -1
sqrt(11) || 0
is
is
is
is
1
0
1
1
is
is
is
is
%d
%d
%d
%d
\n',
\n',
\n',
\n',
~0
~14
3 && -1
sqrt(11) || 0
);
);
);
);
Chapter 5
76
Chapter 5
77
Chapter 6
Loops
In the last chapter, we introduced the idea of a control construct, a method by which
Matlab will depart from its customary sequential processing. Initially, we accomplished
this task through the use selection. That is, we used either an if or a switch statement
to choose among a series of alternative commands to be executed. In this chapter, you
will be introduced to another control construct: loops.
6.1 Repetition
Imagine that you have just walked up to a large breakfast buffet. As you survey the
offerings, you are reminded that you do not like green eggs or ham. Seeking to avoid
digestive discomfort, you begin walking down the buffet line checking each dish in turn
to ensure it does not include the offending foods. If we were to write this process as a
program, you might create a long series of if statements to evaluate each dish for the
presence of green eggs or ham. In programming, we often need to do something more
than once. Add 10 to a series of numbers. Perform an element-by-element operation.
Search through a set of numbers to find its maximum value. Review a data set to ensure
no values fall below a specified safety limit. Each of these operations involves
performing a single set of actions repetitively, though with small variations. In sequential
processing, we would have to write a lengthy program that repeated those actions for
each element.. It would be much more efficient if we could write the code for those
actions once and then simply repeat them. A loop is a control construct that does just that.
Matlab supports two types of formal loops: the for loop and the while loop.
variable = expression
statements
end
The variable above is known as an index and may be referenced like a variable by your
Matlab program. The most basic function of an index is to keep track of how many times
your loop has been executed. Traditionally, most programmers use the letter i for the
index. In Matlab, however, i is used to represent imaginary numbers. To avoid
Chapter 6
Loops
81
confusion, well use ii as our index variable. As a Matlab programmer, youre free to use
any valid Matlab variable name for your index.
The expression is used to determine how many times the loop should be executed. The
expression takes the form of a vector. Usually this is created in shorthand form by means
of the colon operator.
The statements are the set of commands Matlab is expected to execute each time the loop
is repeated.
Finally, every loop is concluded with the word end.
To understand how loops function, consider the following commands:
for ii = 1:10
fprintf(\n Loop Count: %d, ii);
end
When Matlab reaches the loop initially, a control structure is created. In this example,
that structure is an array from 1 to 10: [1 2 3 4 5 6 7 8 9 10] as
specified in the expression. Being the first time through the loop, our index variable, ii
is set to the first element in our control structure: 1. Now, our statements in the body of
the loop are executed, so the phrase Loop Count: 1 is printed on a new line. Once
Matlab reaches the word end, representing the end of the loop, our index variable is
assigned to the next number in our control structure, 2. At this point, the statements in
the body of the loop are executed, so the phrase Loop Count: 2 is printed on a new
line. When we reach the word end, our index variable is assigned the next number in
our control structure, 3. This process will repeat until we reach the end of our control
structure. When our index variable is equal to 10 and we reach the end statement, the
loop will terminate and our program will continue on to whatever code might exist after
the loop. Its worth noting that our index variable, ii, will continue to exist and will
keep a value of 10 unless modified later.
6.2.1 Modifying the Control Expression
For loops are extremely easy to write because Matlab does most of the hard work for you:
it keeps track of how many times youve executed the loop. For loops do have one
limitation, however: a for loop will only execute a finite number of times. The required
values of your index variable must be known before the loop begins. This means that
creating the control expression is often the most difficult or most important part of the
loop.
Consider our previous example of counting from 1 to 10. Suppose instead that we
wanted to count from 1 to 100. The obvious solution is to modify our control expression
to read:
for ii = 1:100
Chapter 6
Loops
82
Now suppose that we only want to count the even numbers. We certainly know enough
about conditionals to write an if statement to determine whether or not a particular
index value is even or odd. But we can greatly simplify this process by modifying the
control expression instead to only generate even numbers in our control array. The colon
operator makes this easy:
for ii = 2:2:100
The colon operators ability to increment values allows us to create control arrays that
feature fractions, even or odd numbers, multiples or even arrays that decrease in number.
Sometimes, however a standard increment value can be impossible to define. In that
case, Matlab allows you to define your control array directly.
Example 6.1 Filtering Data
Suppose you have been given a set of data in an array, x.
x = [-2
-7
-45
-0.5
2.6]
You have been asked to write a program that will print the positive numbers in x. A
solution is to write a simple for loop. Examining array x, however, we find it
impossible to describe its values using the colon operator, so we will manually
define our control array instead.
for ii = [-2 4 6 -7 3 5 -45
if ii > 0
fprintf(%f \n, ii);
end
end
-0.5
2.6]
In the solution above, each time Matlab completes an iteration of the loop, the index
value will move to the next element in the array. So the first time through the array,
ii=-2, the second time through the loop, ii=4. The third time through the loop, ii=6
and so forth.
Performing iteration on an array (that is to say, repeating a task on a series of values) is
one of the most common applications of loops in Matlab. Because we can access
individual elements in a matrix numerically (for example, A(3,2) or x(4), etc.), a welldefined control expression allows us to use our index to cycle through a Matlab array of
values. This is an important concept. Recall that because for loops are only executed a
finite number of times, the control array (the values of our index variable) must be known
beforehand. But that only means the values must be known at the time the loop is first
executed, not necessarily at the time the program is written!
Chapter 6
Loops
83
To this point, we have used our control expressions to generate a one dimensional array
of values for our index variable to cycle through. An important consideration, however,
is that in Matlab, our index variable can be a vector instead. Consider the following
control expression:
for ii = [4 7 9;
2 3 4;
1 7 8]
In this example, the loop will execute three times, once for each column. Each time
through the loop, our index variable, ii, will be set equal to one of the column vectors. So
4
7
the first time through the loop, ii = 2 , the second time through the loop, ii = 3 ,
1
7
9
and the last time through the loop, ii = 4 .
8
Chapter 6
Loops
84
end
Unlike a for loop, the expression in a while statement consists of a logical or relational
test. As long as that expression evaluates to true (non-zero), the loop will repeat. When
the expression evaluates to false (zero), the loop will terminate.
The statements are the series of commands to be executed each time through the loop.
Again, the loop construct is concluded with the end statement.
Perhaps the most obvious difference between for and while loops is that the while loop
lacks an index variable. Indeed there is no built-in index functionality in a while loop.
You can achieve the same functionality, but youll have to define and increment an index
yourself. In fact, there is no problem you can solve with a for loop that cant also be
solved using a while loop. However, youll find that its often more complicated to do so
in a while loop.
6.3.1 Working With while Loop Control Expressions
The control expression in a while loop is the most important and usually one of the most
challenging aspects to write. More programming errors occur because of the control
expression than in any other part of a while loop. Consider the following example:
while 1
fprintf(Hello World! \n);
end
The control expression is simply 1. In a while loop, as long as the control expression
evaluates to true (in Matlab, any non-zero value) the loop will continue to run. So in this
example, the phrase Hello World will be printed on the screen forever. This is an
example of an infinite loop. In programming, infinite loops are generally considered to
be something to avoid. Note: if you find yourself caught in an infinite loop, try hitting
cntl-c (the control and c keys pressed simultaneously).
The above example was fairly obvious. However, infinite loops are common problem.
One of the most frequent causes of an infinite loop is the failure to update a counter. For
example, suppose we wanted to sum the first ten numbers and we wrote the following
code:
n = 1;
total = 0;
while n <= 10
total = total + n;
end
This potential solution causes an infinite loop! Our programmer-created index, n, begins
with the value of 1. When we reach the while loop for the first time it asks whether n is
less than or equal to 10. Since 1 meets this criteria, the expression evaluates to true and
Chapter 6
Loops
85
the statements within the loop are executed. The value of total then is set to 1. We
reach the end statement, and control returns to the top of the while loop. Again, Matlab
evaluates whether n is less than or equal to 10. The value of n, however, hasnt changed.
1 is still less than or equal to 10, so the loop will execute again and again and again.
Indeed, the loop will never end because the value of n will always be 1 and will always
be less than or equal to 10. As for the solution to our original problem, our grand total
will well exceed its task of finding the sum of the first 10 numbers as it heads toward
infinity.
Updating our created index will solve this problem.
n = 1;
total =
while n
total
n = n
end
0;
<= 10
= total + n;
+ 1;
Now, each time through the loop, n will be incremented. The last time through the loop,
n will have a value of 10. The variable total will be recalculated, then n will be
incremented and set to 11. The end statement is reached and control returns to the top of
the while loop. The expression is evaluated. This time, when Matlab asks whether n is
less than or equal to 10, the expression evaluates to false. The loop terminates and
control is shifted to the next line in the program immediately after the end of the while
loop.
You may have noticed that the logical expression in the example above evaluated to true
as long as n was less than or equal to 10. Another common error in writing control
expressions is to terminate the loop too quickly. Consider what would have happened if
the control expression had been written as:
n = 1;
total = 0;
while n < 10
total = total + n;
n = n + 1;
end
The last time through the loop would be when n = 9. At that time, the variable total is
adjusted, n is incremented and set equal to 10. When control returns to the top of the
while statement, the expression evaluates to false because (with a value of 10) is not
less than 10. The error here is one of logic rather than syntax. The loop will run and
terminate normally, but does it solve the original problem which was to sum the first ten
numbers? It does not. In many ways this is a more insidious type of error than an infinite
loop. When an infinite loop occurs, you know there is a problem and roughly where you
need to look to fix it. In this case, the program will run normally and you might never
detect that there is an error unless you are checking the output very carefully and
recognize that the numeric solution Matlab returns is incorrect.
Chapter 6
Loops
86
This problem can be solved using a while loop, though its slightly more
complicated because were forced to use an array referencing structure rather than
simply using the array itself as we could in a for loop. This means we have to define
and increment our own index.
Again, to avoid early termination, we set our control structure to the format:
while n <= length(x)
However, there are several other alternatives that will produce the same result. For
example:
while n < length(x)+1
n = 0;
n = n + 1;
if x(n) > 0
fprintf(%f \n, x(n));
end
end
n = n + 1;
if x(n) > 0
fprintf(%f \n, x(n));
end
end
Chapter 6
Loops
87
The point is that you must be aware of how your loop will treat the beginning and end of
your loop. There are several potential methods for addressing these endpoints. The
method of choice is up to you.
In all the previous examples, the loops were written across multiple lines and with
indented spaces. This isnt required for Matlab, of course, as long as each command is
separated by a semicolon. For humans however, this type of spacing makes your code
much more readable and easier to debug.
When writing loops, it is considered good programming practice to always indent the
statements in the body of your loop by 2 5 spaces. Additionally, you should consider
placing each command on its own line as this makes it easier to read overall and usually
much easier to debug errors.
Another consideration involves modifying the index variable. A while loop, of course,
requires you to increment or make any other changes to an index. A for loop, however,
handles that automatically. It is considered good programming practice to avoid
modifying the value of a loop index variable inside the body of a for loop. Consider the
following code:
total = 0;
for ii = 1:10
ii = ii * 2;
total = total + ii;
end
The first time through the loop, ii is initially set equal to 1. Then in the first statement
in the body of the loop, ii is set equal to 2 (1 * 2). At the end of the loop, what should
happen? Will ii now be equal to 2 or 3? In Matlab, ii will automatically be set equal to
the second element in the control array, in this case 2. But you can see why this might be
confusing. During debugging, keeping track of ii and how many times youve executed a
loop becomes extremely difficult if you modify the index yourself. Syntactically, there
Chapter 6
Loops
88
Finally, its worth noting that in many other programming languages, modifying the
index in a for loop will cause that loop to skip ahead (or backward) as though it had been
executed the exact number of times as indicated by the value of your index variable.
6.4.2 Choosing Between for and while Loops
For most problems you will have a choice between using a for or a while loop. The
primary differences may be summarized as:
For Loops
While Loops
Finite
Indefinite
Built-In Index
User-Defined Index
In practical terms, youll likely find that for applications involving an array of numbers to
be manipulated, a for loop is far easier to program. The while loop is most often used
when you simply dont have the option of using a for loop: when theres no way to
determine how many times a loop should run.
The classic example of this situation involves data validation. Suppose we ask a user to
enter a number between 1 and 10. Invalid entries, such as numbers outside the range or
text should be rejected. A simple conditional statement can be used to implement this
process. But suppose we want the program to keep prompting the user for an entry until
a valid response is given? How many times will that loop run? Theres no way to tell for
certain. The simple answer is that it will run until the user gives a valid response. A
while loop is the perfect solution to this problem.
valid_response = 1;
while valid_response
choice = input(Please enter a number between 1 and 10);
if 1 <= choice && choice <= 10
valid_response = 0;
end
end
Chapter 6
Loops
89
This loop will run continually until the value of choice falls between 1 and 10, at
which point the value of valid_response will be set to 0, the logic of the while loop
expression will evaluate to false and the loop ends.
You may have noticed what seems to be a logical discrepancy in the example above. The
variable valid_response maintains the value true until what is actually a valid
choice by the user occurs, at which time valid_response is set to false. Doesnt
that seem backward? Remember that the test occurs in the expression of the while loop.
As long as the expression evaluates to true, the loop will run. In order to avoid this
apparent inconsistency, however, youll often see the following modification to the error
validation code:
valid_response = 0;
while ~valid_response
choice = input(Please enter a number between 1 and 10);
if 1 <= choice && choice <= 10
valid _response = 1;
end
end
Placing the ~ (not) in the expression means that as long as valid_response is not
true, the loop will repeat.
6.4.3 Nested Loops
A control construct may be placed inside the body (often referred to as the block) of any
other construct. This is called nesting. The ability to nest loops inside one another
allows for the creation of particularly powerful applications. Lets consider a simple
example of a multiplication table. Suppose we wanted to print a 12x12 table of
multiplied values. Nested loops allow us to solve this problem with minimal
programming:
for j = 1:12
for k = 1:12
fprintf(%d
end
fprintf(\n);
end
, j*k);
When the first loop (with index j) occurs, j is assigned the value 1. The first statement
in the that loop (called the outer loop) is a nested for loop (with index k). This new loop
is called the inner loop. The initial value of k is also 1. At this point, Matlab will begin
to execute the inner loop block, meaning the statements within the loop with index k.
The first end statement signifies the conclusion of the inner loop. At this point, Matlab
will return control to the top of the inner loop. The index k will now be assigned the
value 2. However, the index j will still have the value 1. This will continue until k is
equal to 12. After the inner loop ends, a new line is created and the conclusion of the
first iteration of the outer loop occurs. Now, j is assigned the value 2. The statements
Chapter 6
Loops
90
for the outer loop will be executed a second time, which means a brand new inner loop
with index k begins. Because this is a new loop, k will be assigned the value 1 and will
run through a complete cycle up to 12 again before j is incremented a second time.
A few programming tips to remember:
An end statement is always associated with the innermost currently open control
construct, no matter whether that is a loop or a conditional. The closest parallel to
this idea is parentheses. You always have the same number of open and closed
parentheses and they are grouped such that the closed parentheses associates with
the last open parentheses that hasnt already been closed. The same logic applies
to control constructs and their end statements
Previously, we were concerned with writing control expressions that avoided early
termination of our loops. Sometimes, however, we want a loop to end early. This
process is known as breaking out of a loop. In Matlab, breaking out of a loop is
accomplished with the break statement.
The break statement causes the execution of a loop to terminate and control is passed to
the first executable statement after the loop.
Suppose we have a large data set, but to be valid, all the values in that set must be
positive. One possible solution would be:
x = load(sample_data.dat);
for ii = 1:length(x)
if x(ii) <= 0
fprintf(The data contains invalid values.)
break;
end
end
This solution will examine every data point in x. If a negative value is found, the error
message is printed and the loop terminates. No further action is taken by the loop,
meaning no other elements in x are evaluated.
Note that if a break statement is executed inside a set of nested loops, then the break
statement applies only to the innermost loop that contains it. Any outside loops would
continue to run normally.
Chapter 6
Loops
91
6.4.5 Preallocation
Now suppose instead of simply providing the value of N! as output, we wish to create an
array of factorial values from 1 to N. With a slight modification to our program above,
we can create this array:
n = input(To calculate N!, what is N?);
factorial(1) = 1;
for ii = 2:n
factorial(ii) = factorial(ii-1)*ii;
end
The above example certainly seems to work. But what happens if you try to calculate the
factorial for 30,000? You find that the answer is infinity, or at least large enough that the
student edition of Matlab wont calculate it. You may also notice that it takes quite a few
seconds for Matlab to reach this calculation. Without clearing your variables, try running
the program again, this time for 29,999. The value is still infinity, but did you notice that
the answer popped up almost immediately? Could one fewer calculation make that
significant a difference in processing time? No, but whats happening behind the scenes
accounts for this unusual behavior.
Every iteration through the loop, the variable array factorial is growing larger in
size. Each iteration, your computer is going to memory and allocating additional RAM
storage space for this variable. That takes time. In fact, it takes more time for your
computer to interact with RAM to gain additional space than it does to actually make the
calculation. With small arrays, this process is virtually invisible. With larger arrays
(greater than 2000, for example) you may find a delay in Matlabs response.
Chapter 6
Loops
92
So why did this problem disappear the second time? After the first run through, the
variable factorial was already defined in memory as a 1x30000 array. Your
computer didnt have to keep asking RAM for more space, thus the speed was
significantly increased. You can test this yourself by clearing your variables and running
the program again. This time if you only ask for a factorial of 25,000, youll still notice a
time delay.
This process of claiming the variable space beforehand is called preallocation. It is
considered good programming practice to always preallocate your array variables in
Matlab before beginning a loop. This is particularly important for large arrays. We
commonly use the zeros() function in Matlab to preallocate our arrays.
The example below uses a preallocated array. Try it in Matlab and notice the significant
improvement in speed with really large factorials, such as 100,000.
n = input(To calculate N!, what is N?);
factorial = zeros(1,n)
factorial(1) = 1;
for ii = 2:n
factorial(ii) = factorial(ii-1)*ii;
end
93
45
Matlab has returned a vector, [a(1), a(3)], made up of the elements of a that are in
the positions of the nonzero elements of b. The length of b must be the same as the
length of a, but note that the length of the result may be shorter than the length of a. This
feature is called logical indexing. It works only if b is a logical vector.
There are other ways to create logical arrays. The most important method is the use of the
relational operators, <, >, ==, <=, >=, and the element-wise logical operators, &, | and
~. For example: c = [2>1, 2<1, ~(3>2 & 4>5)] makes c a logical vector with
the value [1, 0 1]. This happens because the relational and logical operators return
values whose type is logical. (To determine a variables type use the function named
class, as, for example, class(c).) The operators & and && each signify the and
operation. There are, however, two differences: (1) & is the array operator, meaning that
its operands, unlike those of && are not required to be scalars. The two operands are
required only to have the same dimensions. The operator acts on each corresponding pair
of elements in the two operands and returns an array of the same dimensions. For
example, [1 0 -3] & [0 0 1] returns [0 0 1]. (1) The operator &, unlike &&,
does not short-circuit. The operators | and || have a similar relationship.
A common use of logical indexing is illustrated by this example. We have the vector a
above whose elements are 12, 3, and 45. We wish to form a new vector consisting of
those elements of a that are greater than 10. We do it as follows:
>> c = a(a>10)
c =
12
45
What has happened is that a new vector is formed by the operation a>10. That vector
looks like this [1, 0, 1] and it is a logical vector. That vector then provides logical
indexing into a, and the result is that a new vector is formed (as in the example a(b)
above) consisting of the two elements of a that appear at the indices where the values of
94
the logical vector are nonzero (positions 1 and 3). The result, c is not a logical vector. It
is of the same type as a, which in this case is double.
It can be seen from this example how logical indexing can simplify the code. Here is a
loop version of c = a(a>10):
jj = 0;
for ii = 1:length(x)
if x(ii) > 10
jj = jj + 1;
y(jj) = x(ii);
end
end
Logical indexing can be used on the left side of the equal sign as well. We will introduce
left-side logical indexing with a simple example. Once again, we let a = [12, 3,
45]. Now we execute the following command:
>> a(a>10) = 99
a =
99
3
99
The meaning here is that all elements of a that are greater than 10 are set to 99. Once
again logical indexing is much simpler in comparison to explicit looping, as can be seen
by comparing a(a>10) = 99 with the following semantically equivalent loop:
for ii = 1:length(a)
if a(ii) > 10
a(ii) = 99;
end
end
In each of the last two examplesone with logical indexing on the right and one with
logical indexing on the left of an assignment statement, this explicit loop reveals
something that is hidden by the far more succinct form of logical indexing: namely, that
each element of the vector must be accessed and operated on. With the syntax of logical
indexing, it appears that an entire vector is being operated on at once. That is not true. It
is not even possible with conventional computers, such as the ones that Matlab typically
runs on. Matlab commands may appear to operate on entire vectors, but in fact they cause
hidden loops to be activated by the Matlab interpreter behind the scenes.
So far, we have used logical indexing only with vectors. Here is an example of logical
indexing with an array. Our task is to finds the elements in the matrix M that are greater
than 0.1 and replace each one with its square root. First we give a version employing
explicit looping:
95
[m,n] = size(M);
for ii = 1:m
for jj = 1:n
if M(ii,jj) > 0.1
M(ii,jj) = sqrt(M(ii,jj));
end
end
end
Here is a version using logical indexing:
M(M > 0.1) = sqrt(M(M > 0.1));
This example shows both that logical indexing works with arrays and that logical
indexing can be used on both sides of the equal sign in the same command.
At this point it may seem that the difference between vectors an arrays is minor with
logical indexing. It is not. The situation with arrays is more complex, as can be seen with
the following example:
>> A = [1 2 3; 4 5 6]
A =
1
2
3
4
5
6
>> B = A(A>2)
B =
4
5
3
6
As expected, only those elements of A that are greater than 2 made it into B, but
surprisingly, we find that B is a column vector! What is the reason for this change of
shape, and how did Matlab choose the order of the elements in B? The answers have to
do with the requirement that arrays must be rectangular. In other words each row must
have the same length. If that were not required, then we might well have seen something
like this:
>> B = A(A>2)
B =
4
3
6
In this fictitious output, the first row of B has only one element and it is sitting at the
far right (whatever that means!), and the second row of B has three elements. This
96
scenario cannot work because later operations with B would be poorly defined, so Matlab
does not behave this way. Instead, when logical indexing is applied to an array on the
right side of the equal sign, if the array is not a vector, then that array is replaced by a
column vector in which the elements are placed in column-major order. Column major
order means that, if the successive indices are written out, then the column index changes
fastest. For an M-by-N matrix X, the order would be as follows:
(1,1), (2,1), (3,1), ..., (M,1), (1,2), (2,2), (3,2), ...,
(M,2), (1,3), (2,3), (3,3), ..., (M,3),..., (1,N), (2,N),
(3,N), ..., (M,N), as is illustrated below:
1,1
1,2
1,3
...
1,N
2,1
2,2
2,3
...
2,N
3,1
3,2
3,3
...
3,N
...
...
...
...
...
M,1
M,2
M,3
...
M,N
97
3
6
A.*B loops through all the elements of A and B, and returns an array of the products
of their elements (if A and B are not vectors, there will be nested loops)
A*B loops through the rows of A and the columns of B, forming an array of dot
products (unless A and B are scalars, there will be nested loops)
Commands that operate on entire vectors or entire arrays are said to be vector
commands (the more general term array commands is rarely used), and the translation
of Matlab code from a version that uses a loop into one that uses a vector command is
called vectorization. In every case of vectorization, an explicit loop is avoided. Looping
is however implicit, because the programmer knows that (for the typical computer), only
one element of the vector can be accessed by the CPU at a time. There are many
instances in which vectorization results in a significant simplification in the code required
to accomplish a task. Furthermore, the vectorized version typically runs faster than the
loop version, because the vectorized version runs more efficiently. Because of the
simplification in code and the improved execution efficiency, implicit looping represents
a major advantage over most other languages provided by Matlab in numerical
applications, and vectorization is an important way to exploit this advantage. Skill at
writing vectorized code is essential for large numerical applications in Matlab, and that
skill comes both with practice and by observation of experienced Matlab programmers.
98
Matlab:
o for loop
o while loop
o break statement
o logical arrays
logical
o logical indexing
o A(:)
Chapter 7
User Defined Functions
To this point, the programs you have written have relied almost exclusively on sequential
control. And while you have used control constructs such as loops and conditional
statements to alter that sequential processing, there has been one constant in your
programming: you have written single m-files to accomplish your task. For small
programs, this is not an issue. But imagine youre writing a program that contains
thousands of lines of code or that youre working on this program with several people. In
this scenario, several problems arise. You find that you cant work on the same m-file
simultaneously. Your group members tend to use the same common variable names, so
important data is overwritten and lost in the program. Common tasks are programmed
repeatedly. In short, you find that using a single m-file creates an inefficient and
confusing jumble of code.
Thankfully, there is a more efficient way to organize your programming. That method is
to use functions. From the moment you started working with Matlab, you have been
using functions. Matlab has hundreds of pre-programmed functions to perform common
tasks. This chapter will introduce you to a number of concepts geared toward the
creation of your own unique functions.
A function is nothing but a small program that performs a specific task. Recall that in
top-down design, algorithm creation is a two-step process. First, you decompose your
task into a series of sub-problems and then you perform stepwise refinement to break
those sub-problems down even further. Software engineers will typically create a
function for every sub-problem in their algorithm. This organization provides a number
of advantages:
Perhaps more important than the time savings offered by the division of labor is
the independence of variables. An important side effect of using functions is that
because each function acts as a stand-alone program, variables are kept separate
and independent. This means that identical variable names can be used in more
Chapter 7
100
than one function, but their values wont be confused or overwritten. This is an
extremely important computer science concept known as variable scope, and will
be discussed at length later in the chapter.
Thanks to Matlabs pre-defined functions, you are already very accomplished at using
functions. When we command Matlab to execute a function, we say that we are calling a
function. As you know, some functions require you to provide data or variables to
perform its task. Similarly, some functions will return one or more variables as output.
These variables, whether input or output, are called arguments when associated with a
function. We say that we are passing an argument when they are being sent to or from
a function. It should be noted that the words argument, variable and parameter are often
used interchangeably when we speak of passing arguments to and from functions.
Technically, there are distinctions between the three, but those distinctions are best left
for computer science theorists to debate.
The basic syntax for both calling and defining (writing) a function varies depending on
how many arguments are used for input and output.
7.2.1 Calling Functions
Multiple input and output arguments are placed in lists, with the output arguments listed
inside square brackets and set equal to the function name with the input argument list
passed inside parentheses.
Variations in this syntax abound depending on the combination of input and output
arguments required:
function_name
Chapter 7
101
function_name(input_arguments)
output_argument = function_name
[output_arguments] =
function_name(input_arguments)
Because variables are treated independently by functions, there is often a great deal of
confusion between the arguments we use to call a function and those that exist inside the
function. To help keep them separate in our minds, its helpful to describe the arguments
(or variables or parameters) we use in our function call as actual arguments. We call
them this because these are the actual variables used in our main program as opposed to
the values which are passed to the function.
7.2.2 Defining Functions
Because functions act like independent programs, they are written in their own m-files.
Creating a function is actually quite simple, but there are three important rules that must
be followed:
1. Your function declaration must appear in the first line.
2. All possible input and output arguments must be defined in the function
declaration.
3. The name of your function should match the name of the m-file you save.
The generalized form of a function declaration is as follows:
function [output_argument1, output_argument2, ] =
function_name(input_argument1, input_argument2, )
You may have noticed that the only difference in syntax between the generalized form of
a function declaration and a function call is the word function which appears as the first
word in the declaration. Just like a function call, the syntax of a function declaration will
vary slightly depending on the input and output arguments required.
function
function name
function
function
Chapter 7
102
The arguments we define inside a function are called dummy arguments. You can think
of these as temporary variables for the values of the actual arguments passed to the
function.
At this point, its instructive to see a function in action. Recall from Chapter 6 the
multiplication table problem. We created a simple program that printed a 12x12
multiplication table.
for j = 1:12
for k = 1:12
fprintf(%d
end
fprintf(\n);
end
, j*k);
Lets modify this program to act as a function. Instead of always printing a 12x12 table,
well allow the user to determine our table size. Recall our rules for writing functions.
The first rule says our function declaration must appear in the first line. The second rule
says that all possible input and output arguments must appear in that declaration. This
function will require two input arguments, M and N, representing the MxN table that our
user wishes our function to calculate. Will there be any output arguments? You might
think so because the function will print out a multiplication table for the user, but this is
output that appears on the screen rather than output that will be returned as an output
variable, so there are no output arguments in this function.
Our new function might appear as follows:
function multiply(M, N)
%MULTIPLY Produces an MxN multiplication table
for j = 1:M
for k = 1:N
fprintf(%d , j*k);
end
fprintf(\n);
end
To use our function, we must apply the third rule of writing functions. That is, when we
save this m-file, we must save it with the same name as our function. So this m-file
should be saved with the name multiply.m.
The first comment line beneath the function declaration serves a special purpose. This
line is searched and displayed by the lookfor command in Matlab. Therefore it should
always contain a one-line summary of the function. All comments placed immediately
beneath the function declaration will appear in the help command and help window up
until the first blank line or non-comment line.
A couple quick notes about saving functions:
Chapter 7
103
The location where you save your function is actually rather important. To be
useable, the m-file containing your function must be saved either in the current
directory (presumably where your main program or script file is saved) or
somewhere in the path. If the function you write is intended for use with a single
program, you will typically save it in the same directory as that program.
However, if the function is intended to be used over and over again by many
different programs, it is not uncommon to create a separate directory for those
commonly used functions and then place that directory in Matlabs path.
The rule requiring your function name to be identical to the name of the m-file is
actually more of a guideline than a hard and fast rule. But its a guideline meant
to help your organization. When a function is called, Matlab will actually search
the current directory (and then later the path) for an m-file with the same name as
the function you call. Matlab will execute the code in that m-file regardless of the
function name in the declaration.
Example 7.1 -- Finding Prime Numbers
Write a function that will return a 1xN vector containing all the prime numbers between
1 and N.
function
list_of_primes = myprimes(N)
EDU>> myprimes(25)
ans =
2
11
13
17
19
23
Chapter 7
104
Using functions means that control will shift from one program to another. This can
make run-time debugging more difficult. Testing each function independently of a main
program or script file is important to avoid conflicts later. The following example
illustrates how control shifts between a script and various functions.
Matlabs pre-defined
function sum()
t = sum(x);
multiply(a, b)
Matlabs pre-defined
function input()
function multiply(M, N)
%MULTIPLY Produces an MxN
multiplication table
for j = 1:M
for k = 1:N
fprintf(%d , j*k);
end
fprintf(\n);
end
At each stage, sequential processing operates. When a function is called, control shifts to
the new function along with the value of the actual argument. The function is then
executed as though it were a program all by itself, meaning sequential processing is again
the norm. If the function should call another function, control would shift yet again.
At the conclusion of a function, control returns to wherever the function was called. This
might be the main program or script file, another function or the command window. If an
output argument was defined in the function, its value will be returned as well.
Chapter 7
105
A function terminates when it reaches the end of its code or encounters a return
statement. Recall that return will end a program. In the case of a function, return
acts to end that function and control is reassigned to the location where the function was
called. It is not necessary to end your functions in Matlab with the return statement.
However, many other programming languages require such a concluding statement to end
their functions.
By default, variables are considered to have local scope. Local scope means that the
variable only exists for that function (or program) and no other function (or program)
knows its there. In practical terms, this means two things:
1. Arguments and variables are only viewable, readable and able to be changed
by the program or function that created them. To everything else, its as
Chapter 7
106
% Main Program
A = 13
B = my_function(A)
B = sqrt(A);
A
A
B
Your Computers Memory
In this example, the main program has two actual arguments, A and B, each of which
refer to their own locations in memory (represented in blue). The value stored in A is
passed to the function my_function when its called. The function creates two dummy
arguments, A and B (represented in yellow). Although they have the same name as the
actual arguments, you can see that they point to completely different memory locations.
In this way, theyre treated as totally separate variables and may contain different values.
When the function ends, the value stored in dummy argument Bs memory location is
passed back to the main program, and that value is then assigned to the memory location
B (in blue). When the function ends, the dummy arguments A and B (yellow) are wiped
from memory.
Should you have identical variable names in your main program and functions? Thats
entirely up to you. Some programmers like to keep it that way for consistency. Others
try very hard to avoid duplicating variable names to avoid confusion. The choice is
yours, but the advantages of local variables are clear. When you have several people
working on a program using functions, you no longer have to worry about your
programmers duplicating variable names because Matlab will keep the local variables
separate for you.
7.3.2 Global Variables
By default, every variable created in Matlab is local in scope. However, there are two
notable exceptions. The first is variables that are global in scope. Global variables are
Chapter 7
107
those that can be used by a Matlab program and any or all of its functions. This is
accomplished by having your main program and functions reference the same memory
location. To become a global variable, you must first declare that variable to have global
scope in the main program and all functions that use that variable. The syntax for a
global declaration is straightforward:
global
variable_name
Again, this declaration must appear everywhere that the global variable is to be used.
Lets modify our previous example:
% Main Program
global x
x = 15;
A = 13;
B = my_function(A);
A
A
B
Your Computers Memory
In this modified example, A and B are still local variables in the function and the main
program. However, the global declarations indicate that the variable x referred to in both
the main program and the function point to the same memory location. Thus, any change
to the variable x will carry over. So if we were to execute the main program, it would
begin by declaring the variable x to be global in scope. x is assigned the value 15. A is
assigned the value 13 and then my_function is called, with the value of variable A (13)
passed to the function.
Control is now shifted to the function. The value 13 is assigned to the dummy argument
A. Next, the variable x is declared to be global. Matlab recognizes that this is the same x
as was defined in the main program and has the value 15. Dummy argument B is now
assigned the value of the sqrt(13). Finally, the value in x is now changed to be 10. The
function ends and control is returned to the main program. The variable B in the main
program is now assigned the value that the function returns. The function is defined in
such a way that it returns the value in dummy argument B. That is, it returns the square
root of 13.
There are no more commands in the main program, so the program terminates. Dummy
arguments A and B no longer exist in memory. However, local variables A and B in the
Chapter 7
108
main program persist. A still has the value of 13. B is now equal to the square root of
13. And x? Its value was changed in the function, and because its global, that changed
value persists even when weve returned to the main program. Thus, the value of x is 10.
In this way, global variables are a way of exchanging information between the main
program and its functions (or function to function for that matter) without having to pass
the data as arguments in a function call. Global variables, therefore, should never be used
as arguments passed to a function. You might be asking yourself why shouldnt all
variables be made global? While there are many times when global variables are
appropriate, their use is generally discouraged. Their very nature causes a function to
lose its independence. A global variable will usually be global over an entire program
and all its functions, restricting the ability to duplicate variable names. It also raises the
risk of accidental overwriting of its value in other functions. Finally, global variables are
not a particularly efficient means of managing memory. When in doubt, try to use local
variables instead.
7.3.3 Persistent Variables
A second exception to the local variable rule are those that are persistent in scope.
Persistent variables are those that remain local to a particular function, but whose values
are maintained between function calls. What does that mean? You can think of
persistent variables as a hybrid or offshoot of local variables. Persistent variables only
exist in functions, and like local variables, they can only be viewed, read and changed by
the function that created them. Unlike local variables, however, their values arent
deleted after the function ends. Their values persist in memory until the next time the
function is called, at which point that previously saved value may be accessed.
A persistent variable must be declared as such within a function. The syntax is similar to
that of a global variable:
persistent
variable_name
Chapter 7
109
Try running this program a few times. You should receive results similar to the ones
total
below. = total + x;
count = total;
EDU>> running_total(2)
ans =
2
EDU>> running_total(6)
ans =
8
EDU>> running_total(10)
ans =
18
EDU>> running_total(-4)
ans =
14
EDU>> total
??? Undefined function or variable total
The value in total is kept in memory and used on each successive call of the function.
However, that variable is not accessible outside the function.
A few words should be said about passing values to and from functions. Arguments
passed to a function are assigned in the order in which they appear. For example, given
the following function call and definition:
Chapter 7
110
sample_function(50, 25, x)
function
sample_function(a, b, c)
function
sample_function2(a, b, c, d)
Like the previous example, the values of our actual arguments are assigned in order to the
dummy arguments. Thus, a = 50, b = 25 and c = 30. But what about d? If a fourth actual
argument is not passed, the function will be called but d will be an undefined variable.
There is, in fact, nothing wrong with that. The problem arises when the code in your
function depends on having a value for argument d. Robust programming requires you to
write functions that can handle function calls with fewer arguments than you might
expect.
It should be noted that although Matlab will allow you to call a function with fewer
arguments than are defined, you can never call a function and attempt to pass more
arguments than are defined. In that case, Matlab will simply return an error without
calling the function.
Returning arguments from a function is perhaps an even simpler model. Consider the
following function definition:
function [a, b, c, d] = test_function(x, y)
The function above has four arguments that may be returned: a, b, c, and d. To pass
these values back, the dummy arguments must have values at the time the function ends.
At that point, whatever values are assigned to the dummy arguments will be passed back
in order. For example:
Chapter 7
111
[A, B, C] = test_function(x, y)
Should a dummy argument not be defined at the time the function ends, it will not be
passed back.
Perhaps the biggest trick in dealing with returning values to the function call is in writing
the function call itself. What would happen if the function call and function definition
above were modified slightly?
test_function2(x, y)
function
[s, t, v] = test_function2(a, b)
What happens to the values of s, t, and v? By default, the first output argument in the
function declaration will always be returned. If no actual output argument is defined in
the function call, then that value will be placed in the ans variable. The values of t and v
might be returned, but having no place to go, they will be immediately discarded.
Defining more output arguments than are actually called is not necessarily a bad thing.
But a robust programmer will write their functions in such a way that the function doesnt
calculate and return more data than is actually called for.
7.4
Programming Functions
Robust programming requires that your functions be able to handle function calls with
varying input and output arguments. Sometimes, that simply means returning an error
message to the user informing them that you need additional arguments. Other times, it
might completely change what your function does. Matlab has a series of built-in
functions that will help you determine how your function has been called. The three most
important of these functions are:
nargin
nargout
nargchk(min,max,
nargin-or-nargout)
Chapter 7
112
These functions should be used to determine how many arguments have been passed to
the function in the function call and then how many arguments have been requested as
output. The function you write should be able to accommodate the varying possibilities.
The following example problem illustrates the use of nargin and nargout to write robust
functions.
Example 7.2 Finding Prime Numbers (Revisted)
Modify the prior function to find the prime numbers between M and N. If only one
argument is passed when the function is called, then the function should return an array
of prime numbers between 1 and N. If requested, the function should also return as
output the average of the prime numbers found.
function [list_of_primes, avg] = ourprimes(M,N)
% OURPRIMES Returns a 1xN vector of all the primes from 1 to N
% OURPRIMES(M,N) Returns a 1x(N-M+1) vector of all the primes from
%
M to N
% Method: Sieve of Eratosthenes (ca 240 BC)
% Variables:
% prime 1xN, prime(n) = 1 if n is prime, 0 if n is not prime
% Check to see whether we have enough arguments.
% No need to check if we have too many because Matlab will not call
% a function with too many arguments.
if nargin == 0
error(ourprimes requires 1 or 2 arguments);
end
% If only one argument, then we want to go from 1 to N.
if nargin == 1
N = M;
end
% (1) Assume that all the integers from 2 to N are prime
prime = ones(1,N);
prime(1) = 0;
% (2) Mark all the numbers that are multiples of a number:
for n = 2:sqrt(N) % No factor can be larger than sqrt(N)
if prime(n) % Multiples of primes include all multiples
prime(n+n:n:N) = 0;
end
end
(continued below)
Chapter 7
113
EDU>> ourprimes(25)
ans =
2
11
13
17
19
23
29
31
37
EDU>> ourprimes(10,50)
ans =
11
13
17
19
23
41
avg =
4.2500
EDU>> [list, avg] = ourprimes(5, 35)
list =
5
11
avg =
17.2222
13
17
19
23
29
31
43
47
Chapter 7
114
Robust programming doesnt just mean that your functions need to be able to handle
varying numbers of input and output arguments, it also means it needs to be able to
handle outputs of varying type. What happens if your function is expecting a number and
it receives a text string instead? What happens if it receives an imaginary number instead
of an array? There will be many occasions when youll wish for your function to perform
a different operation depending on the type of your input arguments.
Example 7.3 -- Determining Complex Numbers
Write a function that will determine whether a given input is a complex number.
function out = iscomplex(input)
% ISCOMPLEX Determines whether the input argument is complex
% The function will return 1 if the input is a complex number and
% will return 0 if the input is not complex.
if imag(input) > eps
out = 1;
else
out = 0;
end
EDU>> iscomplex(14)
ans =
0
EDU>> iscomplex(-4)
ans =
0
EDU>> iscomplex(3 + i)
ans =
1
The output of the example above is entirely dependent on the type of the input (whether
its complex or real). Dynamic Polymorphism is a property of some functions. It exists
in a function where the output is determined during the execution of the function by the
type of the input arguments. Matlab subscribes to loose data typing. This means that
variables in Matlab can change data types at will. A variable can go from holding an
integer to a matrix to a text string to a decimal all in a few lines of code. This makes
creating functions with dynamic polymorphism very easy in Matlab. However, most
programming languages are not that way. They exhibit strong data typing, which means
Chapter 7
115
once a variable is declared to be of a certain type, its very difficult (and sometimes
impossible) to change that type. In those languages, dynamic polymorphism is difficult
to accomplish, but is often a very lofty goal. The most common examples of dynamic
polymorphism youre likely to see might be found in data validation. Your function
might evaluate the input arguments to ensure they are of the proper data type. If not, they
will return a specific error message. In this way, the output (whether an error message or
an actual result) may be determined by the type of input.
The example also illustrates another type of special function: a predicate. A predicate is
a Boolean function that returns one of two values: true or false. In Matlab, this is
represented by 0 for false and any non-zero value for true. Again, we often think of this
as 1.
Matlab:
o defining a function
input arguments
output arguments
o scope
local variables
global variables
o persistant variables
o passing arguments
Chapter 7
116
Chapter 8
Data Types
Every modern programming language provides means for storing numbers in variables,
operating on them, and printing them. Matlab is no exception, and we have seen
countless examples of numbers being stored, operated on, and printed. The examples
suggest that these numbers are the same as the real numbers and complex numbers of
mathematics, where there is no upper limit to absolute value of a number and no lower
limit to the absolute difference between two numbers. On the other hand, since the space
of mathematical numbers is infinite, while the memory of a computer is finite, it is clear
that the use of a computer must impose some limits. It does. There is an upper limit to the
size of a number on the computer, and there is a lower limit to the absolute difference
between two numbers.
The set of numbers that can be represented by a Matlab variable is, therefore, finite. We
are about to learn that that there is more than one type of number in Matlab, and that each
type provides a different set of allowed numbers. Furthermore, we will learn that there
are types other than numeric types that hold other data. These other types cannot be used
in arithmetic operations, but do allow other operations. A data type is in fact completely
determined by the set of all possible values it can have and the set of operations that can
be performed on it. Indeed, in the formalism of computer science, a data type, or simply,
type, is defined as a set values and a set of operations that can be performed on those
values.
It is common to employ variables of several different types in a single function. It is even
possible to use variables of different types in the same operations. Matlab does, however,
enforce one rule of uniformity: All elements of a given array must be of the same type.
We call the types of these elements elementary types. Thus, when we speak of the type of
a variable that is not a scalar, it is not necessary to specify the type of each element in the
array. We need specify only one elementary type. A complete description of the type of
an array will include: the number of dimensions, the size in each dimension, and the type
of the elements. In Matlab there are always two or more sizes because the number of
dimensions is always 2 or more (even a scalar is a one by one matrix!) Example
descriptions of types are
Chapter 8
Data Types
117
i 1 ,
Chapter 8
Data Types
118
Data Type
int8
int16
int32
int64
uint8
uint16
uint32
uint64
single
double
Range of values
-27 to 27-1
-215 to 215-1
-231 to 231-1
-263 to 263-1
0 to 28-1
0 to 216-1
0 to 232-1
0 to 264-1
-3.4x1038 to 3.4x1038
-2.2x10308 to 2.2x10308
If you dont have this table handy, the maximums and minimums can be gotten from
Matlab by using these four functions: intmax, intmin, realmax, and realmin.
Each takes one string as input. The string for the first two is the name of the integer type
of interest. The string for the last two is double or single. For example,
Chapter 8
Data Types
119
>> intmax('int32')
ans =
2147483647
>> intmin('int32')
ans =
-2147483648
>> realmax('single')
ans =
3.4028e+038
>> realmin('single')
ans =
1.1755e-038
Note that realmin gives the smallest positive number representable. The smallest
negative number, which is shown in the table, is equal to realmix.
Conversion functions
To produce a numeric value of specific type Matlab provides conversion functions. The
conversion function for a given data type has the same name as that type. It takes one
input argument of any numeric type and returns one output argument of its specified type.
Here are examples of conversion functions in action:
>> x = 10
x =
10
>> class(x)
ans =
double
From the commands above, we see that, the default numeric data type is double.
>> x = int8(10)
x =
10
>> class(x)
ans =
int8
Chapter 8
Data Types
120
From the two commands above, we see how the conversion function int8 can be used
to produce a numeric type of int8 as output, when given an input type of double. We
know that the input argument 10 is double because double is the default numeric
type.
>> y = x
y =
10
>> class(y)
ans =
int8
From the two commands above, we see, as we would expect, that the data type of y
becomes the same as the data type of the value that is assigned to it.
>> y = double(y)
y =
10
>> class(y)
ans =
double
From the two commands above, we see that the conversion function double can be
used to produce an output of type double.
With the exception of int64 and uint64, the advantage of each of the first 9 data
types over double is that they require less memory space per number. Computer
memory is measured in bits, which are the smallest units of memory on any computer,
and bytes, which are groups of 8 bits. All but the last two of the data types in Table 14
include a number as part of their names. That number is equal to the number of bits
required to store a single number of that type. The last two do not include a number in
their names, but single requires 32 bits and double requires 64. Because computers
manipulate their memories most efficiently by accessing a byte at a time, or a power of
two bytes at a time, each type requires an integral number of bytes of storage1, 2, 4, or
8.
All but two of the data types include int as part of their names. These are integer
types, which means that they are capable of storing only integers. The integer types
cannot store fractional parts. An attempt to convert a number with a fractional part to an
integer type will result in rounding, as in the following examples:
>> int8(9.5)
ans =
10
Chapter 8
Data Types
121
>> int8(9.4)
ans =
9
>> int8(-9.4)
ans =
-9
>> int8(-9.5)
ans =
-10
Furthermore, if a conversion function is given a value outside its range, it will return the
value that is at the closest end of its range. For example,
>> int8(128)
ans =
127
>> int8(-1000)
ans =
-128
Some of the integer types have names that begin with the letter u. These types can store
only non-negative integers:
>> uint8(-13)
ans =
0
Arithmetic operations
We have seen many examples of arithmetic in Matlab, all involving the arithmetic
operators +, -, *, /, \, ^, .*, ./, .\, and .^. However, up to now, the operands
have always been of double type. With the exception of int64 and uint64, all other
numeric types can be used in arithmetic operations in Matlab as well6. However, there are
important restrictions on these operations. When the two operands of a binary arithmetic
operator (see Chapter 3, Section 3.2) are of different types, the resulting operation is
called mixed-mode arithmetic. In Matlab there are severe restrictions on mixed-mode
arithmetic. For the expression x op y where op is an arithmetic operator, the following
list gives in braces the set of allowed operators for each given pair of operand types:
These types cannot not be used in arithmetic operations in versions of Matlab before Version 7.
Chapter 8
1.
2.
3.
4.
5.
6.
7.
Data Types
122
The last category shows that arithmetic operations involving differing integer types are
always illegal.
A question arises immediately in mixed-mode operations: What is the type of the result?
When an operation of type 1 is carried out, the result has the type,
double, if both operands were of type double, both were of type char,
or one was double and one was char.
single, if either of the operands was of type single.
When an operation involves an operand of integer type, which includes all types from 2
to 6, the result has that same integer type. Note that, except when a char is involved,
Matlab uses the rule that the output type of an arithmetic operation is the same as the
type of the input type with the smaller range. (This behavior is opposite that of C, C++,
and Java. Their rule is that the output type is the same as the type of the input with the
larger range.)
When the result of an arithmetic operation is out of range, Matlab gives the expression a
special value according to the type of the result (Inf represents infinity):
In summary, Matlab usually chooses the smaller type for its result, and, if the
magnitude of the result is too large or too small for that type, it is set to the closer end of
the range.
Relational operations
The relational operators, ==, ~=, <, >, <=, and >= all allow mixed-mode operands of
any numeric types. They return a value of type logical. For example,
>> int8(4) < single(4)
ans =
0
Chapter 8
Data Types
123
>> class(ans)
ans =
logical
8.2 Strings
Strings were introduced in this book in
Chapter 3 (Section 3.5) and have been
used repeatedly as inputs to the
functions input, in which they were
used to provide a prompt to the user,
and fprintf, in which the first
argument was a string, the format
string, which told fprintf what to
print and how to print it. There is,
however, much more to strings. A string
is a value, like a numeric value, that can
be assigned to a variable and
manipulated by functions.
(nul)
(soh)
(stx)
(etx)
(eot)
(enq)
(ack)
(bel)
(bs)
(ht)
(nl)
(vt)
(np)
(cr)
(so)
(si)
(dle)
(dc1)
(dc2)
(dc3)
(dc4)
(nak)
(syn)
(etb)
(can)
(em)
(sub)
(esc)
(fs)
(gs)
(rs)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(sp)
!
"
#
$
%
&
'
(
)
*
+
,
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(us)
31
63
95
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(del) 127
The name of this character encoding scheme, which is used by almost every
programming language and, for that matter, almost every program that uses the Latin
alphabet, is ASCII (American Standard Code for Information Interchange).7 The
abbreviations in parentheses have special meanings to computer systems that use
communication protocols that are of no interest here, except for these: (nl) means
newline, (ht) means horizontal tab, and (sp) means space. These have meaning to
7
A far more general encoding scheme which is gradually replacing ASCII is Unicode. Unicode has three
forms, one of which uses 32 bits and is capable of encoding over 4 billion characters.
Chapter 8
Data Types
124
fprintf, and there is a special escape sequences for each of them: \n produces (nl), and
\t produces (ht). We saw the first one in Chapter 3 (Section 3.6). The ASCII scheme is
designed for an eight-bit variable, which can represent 256 different characters, 128 of
which are the standard characters given in the table. Matlab reserves 16 bits, or two bytes
for each character, and it includes some characters in an extended ASCII set. We will
not need them.
Chapter 8
Data Types
125
but it is invisible. Checking the ASCII table above we see that the number that encodes a
space (sp) is 32. We can use that information to look for spaces in a string. We also need
to be able to convert the characters into their codes. Matlab enables you to do that by
converting from the type char to the type double using the conversion function
double. Thus,
>> double(' ')
ans =
32
Here, we have given double an argument that is a one-element character string
consisting of one space. Now lets look for spaces in book_title:
>> double(book_title)
ans =
Columns 1 through 9
77
97
116
108
Columns 10 through 18
114
32
83
109
Column 19
115
97
98
32
102
111
97
114
116
105
101
As expected there are two 32s. The first one is followed by 102, which is the ASCII code
for the letter f. The second one is followed by 83, which is the code for S. Numbers
and punctuation marks are treated no differently. If they occur in a string, they are
encoded in ASCII:
>> pi_digits = '3.14159'
pi_digits =
3.14159
>> double(pi_digits)
ans =
51
46
49
52
49
53
57
Here we have assigned the 7-character string 3.14159 to pi_digits. These are the
first digits of the number , but, in this case, instead of assigning the number 3.14159,
which would be of type double, we have, by enclosing 3.14159 in quotes, assigned a
vector consisting of seven elements, each of which is the ASCII code for one character.
Since there are seven elements in this vector, the result of applying the function length
to my_number should not be surprising:
>> length(my_number)
ans =
7
Chapter 8
Data Types
126
Like other vectors, new strings can be made from parts of existing ones:
>> s = 'Two is company, three a crowd.';
>> ssub = s(13:end)
ssub =
ny, three a crowd.
Also, new strings can be made by concatenating existing strings:
>> a = 'Three, two, one'; b = ', '; c = 'BLASTOFF!';
>> count_down = [a,b,c]
count_down =
Three, two, one, BLASTOFF!
Strings can even be put together to make arrays with more than one row and column:
>> first = 'abcdefgh'
first =
abcdefgh
>> second = '12345678'
second =
12345678
>> both = [first;second]
both =
abcdefgh
12345678
>> double(both)
ans =
97
98
99
49
50
51
100
52
101
53
102
54
103
55
104
56
>> both'
ans =
a1
b2
c3
d4
e5
f6
g7
h8
Here we have made an array with two rows in which all the elements are of type char. It
is important, though, to remember that arrays must be rectangular. That is, each row
Chapter 8
Data Types
127
must have the same number of elements. In this case. the variables first and second
are both of length 8, so each row of both has 8 elements. It is not possible to make a
ragged array, in which rows contain strings of differing lengths, as the following
attempt shows:
>> long = 'Matlab'; short = 'Java';
>> languages = [long; short]
??? Error using ==> vertcat
All rows in the bracketed expression must have the same
number of columns.
(The reference to vertcat refers to the internal function that Matlab uses to put row
vectors together into arrays.)
Arithmetic operations
It may seem odd at first, but, like the numeric data types, strings can be used in arithmetic
operations! When we do arithmetic on them, Matlab treats them as a vector of ASCII
numbers, instead of a string of characters. Like the integer types, a string can be used in
mixed-mode arithmetic. A major difference, though, is that when a string is used in
mixed-mode arithmetic, the result of the operation is the type of the numeric operand,
whereas, as pointed out in Section 8.1, when an integer variable is used in mixed-mode
arithmetic, the result is of the same integer type. Here is an example of arithmetic on
strings:
>> language = 'Matlab'
language =
Matlab
>> double(language)
ans =
77
97
116
108
97
98
196
>> class(big_language)
ans =
double
We see that when we multiply language, which is of type char, by 2, which is of type
double, the result is of type double, as predicted above.
Chapter 8
Data Types
128
>> char(big_language)
ans =
Note also the non-Latin characters that showed up when we converted back to char.
These are some of the characters mentioned above that Matlab supports in addition to the
Latin ones. The little square box( ) indicates that there is no printable character (not
even a space) associated with the number 154.
>> char(big_language/2)
ans =
Matlab
This last command produces the original string again by dividing out the factor of two
and converting once again to the type char. We have our original string.
This forward-backward conversion suggests a simple (and easy to crack) coding scheme
for secret messages: Any operation that can be undone is suitable to encode a message.
Here is another example,
>> secret_plans = '1pm: Stairs behind door at right to basement';
>> coded_plans = char(158-secret_plans)
coded_plans =
m.1d~K*=5,+~<9650:~://,~=*~,576*~*/~<=+9190*
Well, this is certainly a mess!
>> decoded_plans = char(158-coded_plans)
decoded_plans =
1pm: Stairs behind door at right to basement
Relational operations
The relational operators, ==, ~=, <, >, <=, and >= all allow mixed-mode operands of
any numeric type and of type char. They return a value of type logical (see below).
As. when we do arithmetic on them, Matlabs relational operators treats strings as a
vector of ASCII numbers, instead of a string of characters. For example,
>> int8(97) < 'a'
ans =
0
Chapter 8
Data Types
129
Thanks to the sensible order of the ASCII codes, letters that come earlier in the alphabet
also have smaller numbers. Thus, a program that is required to alphabetize words can
compare the ASCII numbers in order to determine which letters come first. It is
interesting to note that the upper case letters all precede the lower case ones. It is for this
reason that many computer-sorted word lists put all capitalized words before all the
uncapitalized ones. It may not be the preferred order for a given application, and it is not
necessary to order them that way. However it is the way that requires the least complex
program, and so programmers have often done it that way.
String functions
While it is possible to do almost anything we wish with strings simply by using the
ordinary tools for manipulating vectors, such as indexing, the colon operator,
concatenation, arithmetic, relational operators, etc., there are many tasks that have
already been written as functions for us by the Matlab programmers. Matlab provides a
number of built-in functions that include strings as input arguments and/or output
arguments. Table 16 gives a partial list. One of these functions is very similar to a
function that we have already learned about in great detail. It is sprintf. It is similar in
functionality to fprintf. Both functions permit you to stipulate in detail how data is to
be printed. The difference is that, while fprintf causes its output to appear directly in
the command window, sprintf puts its output into a string. Here is a simple example
that reveals the difference:
>> x = pi;
>> fprintf('x:\nto three decimal places: %6.3f\n', x);
x:
to three decimal places: 3.142
>> s=sprintf('x:\nto three decimal places: %6.3f\n', x);
>> s
Chapter 8
Data Types
130
s =
x:
to three decimal places:
3.142
We see by this example that fprintf itself forms a string, but it is not possible to capture
the string in a variable, as it is with sprintf. We see also that, with both fprintf and
sprintf it is possible to use the escape characters \n to produce the newline
character. The following example makes that clearer:
>> s = sprintf('\n')
s =
>> double(s)
ans =
10
Checking Table 15 we see that the ASCII code for newline (nl) is indeed 10.
Table 16 String Functions
Name
char
findstr
ischar
isletter
isspace
isstrprop
num2str
length
lower
regexp
sprintf
strcat
strmatch
strncmp
strcmp
strcmpi
strncmp
strncmpi
str2num
upper
Description
converts type to char
finds the positions of a substring in a string (see also strfind)
returns 1 if argument is a character array and 0 otherwise
finds letters in string
finds spaces, newlines, and tabs in string
finds characters of specified type in string
converts number to string
determines the number of characters in string
converts letters in string to lower case
finds substrings defined by a regular expression
writes formatted data to string (cf. fprintf)
concatenates strings
search array for rows that begin with specified string
applies strcmp to the first n characters of strings
returns 1 if two strings are equal and 0 otherwise
like strcmp but independent of case
compares first n characters of strings
like strncmp but independent of case
converts string to number
converts string to upper case
For the remaining functions in Table 16 it is recommended that, when you have a task to
perform with strings, such as alphabetizing a list, looking something up in a database of
strings, or using strings in a graphical-user-interface, you consult this table, find possibly
Chapter 8
Data Types
131
useful functions, and use the Matlab help command to learn the details of their
operation. The most powerful of these functions for searching for substrings is regexp.
To learn about regular expressions go to the Help Navigator (Chapter 2, Section 2.4) and
click on MATLAB/Programming/Basic Program Components/Regular Expressions.
8.3 Structs
An array in Matlab, C++, Java, Fortran, and most other languages, consists of a collection
of elements, each of which is of the same elementary data type. The array is said to be
homogeneous with regard to the types of its element. It is not possible, therefore, to have
a matrix whose first row consists of elements of type int16 and whose second row
consists of elements of type char. Such an array, were it legal, would be heterogeneous
with respect to the types of its elements. An attempt to set up any heterogeneous array
will be thwarted by Matlab. Here is an example of what happens,
>> A = [int8(1),int16(2);int32(3),uint32(4)]
Warning: Concatenation with dominant (left-most) integer
class may overflow other operands on conversion to return
class.
Warning: Concatenation with dominant (left-most) integer
class may overflow other operands on conversion to return
class.
Warning: Concatenation with dominant (left-most) integer
class may overflow other operands on conversion to return
class.
A =
1
2
3
4
>> class(A)
ans =
int8
>> class(A(1,1)),class(A(1,2)),class(A(2,1)),class(A(2,2))
ans =
int8
ans =
int8
ans =
int8
ans =
int8
Chapter 8
Data Types
132
Matlab imposes its homogeneity restriction by converting all but the first element in the
list to be of the same class as that first element, which in this particular case is int8. It
also prints a warning for every element that is converted. The homogeneity restriction is
actually quite reasonable because of the important feature of arrays that allows an
operation to be specified simultaneously for all elements of the array, as for example x =
int8(2)*A. This operation would legal for A above, since the elements of A are all of
type int8, but it would legal for only A(1,1), if Matlab allowed heterogeneous arrays.
One might argue about the importance of homogeneity to the functionality of arrays, but
it is also important from an efficiency standpoint. Accessing individual elements of an
array can be handled internally by Matlab, or any other language for that matter in an
especially efficient way if the types of the arrays elements are all the same, but
efficiency of the inner workings of Matlab is beyond the scope of this book, and when
array-wide operations are not important, then the homogeneity restriction becomes
onerous. If, for example, we wish to store information about a person in an array, we
might want to put both his or her social security number and his or her name in the same
data structure. In this case, a first row of type int16 and a second of type char would
work very well.
Fortunately, for applications in which array-wide operations are not required and
heterogeneous elements are desired, Matlab supports a perfect data type. It is called a
struct. Like an array, a struct consists of a set of elements, but unlike an array those
elements can be of differing data types. There is another important difference as well.
Each element is indexed by user-defined name instead of numerical indices. Since that
description is hard to understand at first, we will quickly provide an example:
>> r.ssn = 568470008
r =
ssn: 568470008
>> class(r)
ans =
struct
>> class(r.ssn)
ans =
double
Here we have created a user-defined name, ssn, to serve as an index for an element of a
variable r. The dot between r and ssn indicates that the name to the right of it is the
name of an element of the variable to the left of it. A name used as an index is called a
field name, and the value associated with that name is a field. The variable r is now a
struct. It has one field, whose name is ssn and whose type is double. We can add
as many fields as we like:
>> r.name = 'Homer Simpson'
Chapter 8
Data Types
133
r =
ssn: 568470008
name: 'Homer Simpson'
>> r
r =
ssn: 568470008
name: 'Homer Simpson'
Each field can be of any type. It can, for example, be another struct:
>> r.address.street = '742 Evergreen Terrace'
r =
ssn: 568470008
name: 'Homer Simpson'
address: [1x1 struct]
We have added a new field to r, called address and we have made the type of that
field be a struct. That inner struct has one field, called street, and its value is
the string 742 Evergreen Terrace. Notice that when the structure gets this
complex, when Matlab is commanded to display the contents, it resorts to abbreviating
the inner structure a bit. Thus, instead of showing the structure of the inner struct, it
simply shows that it is a struct. It shows that by means of the struct in the phrase,
[1x1 struct]. (The 1x1 does not mean that the struct has just one field. Its
meaning will be made clear below.) We can add an additional field to the inner struct:
>> r.address.city = 'Springfield'
r =
ssn: 568470008
name: 'Homer Simpson'
address: [1x1 struct]
There is no visible change in Matlabs display of the contents of r because, while we
have added another field to the struct within the third field of r, we have not changed
the fact that the third field of r is a struct. If we want to look at the inner struct
itself, we can do it as follows:
>> r.address
ans =
street: '742 Evergreen Terrace'
city: 'Springfield'
Chapter 8
Data Types
134
= 1989:2005;
568470008
'Homer Simpson'
[1x1 struct]
[1x17 double]
Here we see that, when Matlab displays the contents of the last field, it shows only that it
is a 1 by 17 array type double. The contents of the field address is shown as a 1 by 1 array
of type struct. Matlab chooses to show only the types when the values would occupy
too much space on the command window. Smaller arrays are displayed in full, as for
example:
>> pixel.position = [567, 688];
>> pixel.rgb = [145, 155, 134];
>> pixel
pixel =
position: [567 688]
rgb: [145 155 134]
Since short numeric vectors fit conveniently on one line, they are displayed in full. As a
special case of this sort of display, strings, which are stored as row vectors of type char,
are displayed in full, as was, for example 'Homer Simpson' above.
Accessing individual elements of an array that is a field of a struct is done as usual.
Thus,
>> pixel.rgb(1:2)
ans =
145
155
Structs can also be elements of an array themselves, as long as the homogeneity of the
array is maintained. The type of a struct is specified by its field names. Thus, if an
element of an array is a struct, then all elements of that array must be structs and
all must have exactly the same set of field names:
Chapter 8
Data Types
135
Chapter 8
Data Types
136
Dynamic field names are not available in versions of Matlab previous to version 7.
Chapter 8
Data Types
137
Struct functions
There are a number of useful functions designed specifically for working with structs.
A partial list is given in Table 17.
Name
getfield
isfield
isstruct
orderfields
rmfield
Description
returns the value of a field whose name is specified by a string
true if a struct has a field whose name is specified by a string
returns true if argument is of type struct
changes the order of the fields in a struct
removes from a struct a field whose name is specified by a string
setfield assigns a value to a field whose name is specified by a string
-or- if the field is not present, adds it and assigns it the value
struct create a struct with fields whose name are specified by strings
Several of the descriptions in the table include the phrase, a field whose name is
specified by a string. Like the dynamic field-naming operation, these functions allow for
the possibility of a string that is formed during the execution of a program to be used with
structures . Here is a function that produces the same result as
Chapter 8
Data Types
138
Note that we must use the function struct to create the struct initially, but once the
struct has been created, we must use setfield to add fields to it.
8.4 Cells
We noted above that structs and arrays can be nested within each other and structs can be
nested within structs. What about arrays within arrays? Matlab provides that option as
well, albeit indirectly. It is provided by means of a new data type, called a cell. To
understand the cell, we must understand a bit about the way in which a program
references its variables.
Chapter 8
Data Types
139
must be looked up when no such variable exists, then Matlab halts execution of the
program and issues an error message, as for example,
??? Undefined function or variable 'x'.
If, on the other hand, the command assigns a value to a variable that has not already been
defined, in defines it immediately by placing its name into a table and choosing an area of
memory in which to store the variables values. The area of memory is a set of bytes, and
each byte in the memory has its own unique address. Matlab will choose a contiguous set
of bytes and will put the address of the first byte into the table, along with information
about the type, size and shape of the variable. It reserves this area and will not use it for
any other variable. Every variable has its own unique area of memory.
You can look at part of the contents of the table. You see it by issuing the command
whos. For example,
>> a = 5;
>> b = int8([5 6;-9 9]);
>> c = 'Tiger';
>> whos
Name
Size
a
b
c
1x1
2x2
1x5
Bytes
8
4
10
Class
double array
int8 array
char array
Chapter 8
Data Types
>> whos
Name
Size
a
b
c
1x1
2x2
1x1
140
Bytes
8
4
8
Class
double array
int8 array
double array
Size
Bytes
10x10
800
Class
double array
>> clear('c')
>> exist('c')
ans =
Chapter 8
Data Types
141
Pointers
What is not shown in the table of variables is the address of each variable. That
information is never revealed in the variable table, or any table, by Matlab for any
variable. There is no option to do so, and addresses are not available via any function or
operation. Matlab is different in this regard from some languages, such as C and C++,
which provide an operator that returns the address of any variable whose name is given as
an operand to the operator. These languages also permit one variable to hold the address
of another variable, which is another practice that Matlab does not allow. In these
languages the former variable is said to hold a pointer to the other variable. In fact, in the
parlance of programming languages the term pointer means simply the address of an
object in memory. When a variable holds an address, it is called pointer variable.
Hidden addresses
In C and C++ a pointers value can be set to any desired value, printed, assigned as the
value of a variable, and generally treated like any other number. Matlabs implementation
is a bit more like that of Java, which also keeps the addresses of its variables hidden.
There are debates about the decision to reveal or keep hidden the addresses used during
the running of a program. When they are revealed, the program has the power to select
specific addresses for special uses, as for example input and output to hardware devices
using registers with specific addresses. The ability to specify in the code a specific
address is particularly important feature for embedded applications, which are
applications that run on small, special-purpose computers in appliances, cars, etc. Having
addresses open to direct manipulation is advantageous in these applications, but there are
disadvantages too. When addresses are kept hidden, it is far less likely that a change in
the address space in which the program runs will affect the outcome of the program.
Thus, a Matlab or Java program that runs properly on one computer is made more likely
to run properly on another computer because changes in the address space from one
computer to another cannot affect their programs.
Chapter 8
Data Types
>> p = cell(2,3)
p =
[]
[]
[]
[]
142
[]
[]
>> class(p)
ans =
cell
[]
>> p(1,2)
ans =
{[]}
The set of curly braces around the empty matrix indicates that p(1,2) is, as we know it
must be, of type cell. Those braces are Matlabs way of telling us that p(1,2)
contains the address of the empty matrix. The value inside the braces, in this case the
empty matrix, is the object whose address is stored in p(1,2).
Curly braces are featured in much of the syntax involving arrays of type cell, as we
will see now. For example, curly braces are part of the syntax that allows us to gain
access to the object to which p(1,2) points. We do that by replacing the parentheses by
curly braces in the indexing operation,
>> p{1,2}
ans =
[]
The phrase (ii,jj) refers to the pointer that is stored at position ii,jj, while the
phrase {ii,jj} refers to the object to which it points.
Lets look at what whos will tell us about p:
>> whos p
Name
Size
Bytes
Class
Chapter 8
Data Types
143
2x3
24
cell array
[]
[]
17
Size
Bytes
Class
Chapter 8
Data Types
144
2x3
88
cell array
Size
2x3
[]
[]
Bytes
160
Class
cell array
Chapter 8
Data Types
145
p =
[
17]
[34978]
[1x2 double]
[4x2 int8 ]
[]
'Awesome!'
Chapter 8
Data Types
146
'hello'
[2x2 double]
p
{2,2}
(3,2)
10
20
30
40
The colon operator can be used to assign a subarray, as usual. It can be used within
braces, as for example,
>> q = p(1:2,2:3)
q =
[1x2 double]
[4x2 int8 ]
[]
'Awesome!'
Chapter 8
Data Types
147
Chapter 8
Data Types
148
Awesome!
The characters in the string are printed without quotes, as they are for the display of any
string,
>> s = 'Simply amazing!'
s =
Simply amazing!
please: 'Marge'
please: 'Homer'
please: 'Maggie'
please: 'Lisa'
please: 'Bart'
please: []
is a numbered list
Marge
Homer
Maggie
Lisa
Bart
Chapter 8
Data Types
149
The special argument varargin must be the last dummy argument in the list. It can
also be the only dummy argument. When the function is called with more input
arguments than there are normal dummy arguments, varargin receives the surplus.
It is a cell vector, and each element points to one argument. Inside the function it is
treated as an ordinary cell array. Furthermore, the function nargin, which returns a
count of the number of arguments used in the call, counts all arguments, both those that
are captured by the normal dummy arguments and those that are captured by varargin.
Here is this function in action,
>> print_all_args(14)
14
>> print_all_args(14,15,16,17,18)
14
15
16
17
18
Chapter 8
Data Types
150
Now suppose we want a function that will take an input vector and copy the value of each
of its elements into separate output arguments. We can accomplish that with
varargout. Here is a function that does it:
function [first,varargout] = distribute(v)
first = v(1);
for ii = 1:length(v)-1
varargout{ii} = v(ii+1);
end
As is the rule with varargin, varargout must be the last dummy output argument in
the list. Also, in analogy to varargin, it holds any excess output arguments after the
normal ones. Here is a function in the expected situation, namely, the length of the
input vector is equal to the number of output arguments:
>> [a,b,c] = distribute_to_args([14,15,16])
a =
14
b =
15
c =
16
If fewer output arguments are given, there is no error. The extra elements placed into
varargout are simply ignored:
>> [a,b] = distribute_to_args([14,15,16])
a =
14
b =
15
On the other hand, if there are not enough elements in varargin to handle all the
remaining output arguments, Matlab complains and halts execution,
>> [a,b,c,d] = distribute_to_args([14,15,16])
??? Error using ==> distribute_to_args
Too many output arguments.
Cell functions
Matlab provides a number of functions designed to assist you in using cell arrays. Table
18 gives a partial list.
Chapter 8
Data Types
151
Name
cell
celldisp
cellfun
cellplot
cell2struct
deal
iscell
num2cell
Description
create an array of type cell
show all the objects pointed at by a cell array
apply a function to all the objects pointed at by a cell array
show a graphical depiction of the contents of a cell array
convert a cell array into a struct array
copy a value into output arguments
returns true if argument is of type cell
convert a numeric array into a cell array
Chapter 8
Data Types
Matlab:
o the function class returns the type of its argument
o conversion functions
o numeric types
floating point
double, single
integer
int8, 16, 32, and 64
uint8, 16, 32, and 64
o string
a vector
type is char
o struct type
o cell type
holds pointers
created with function cell
syntax of commands employs curly braces
cell array may hold pointers to arrays of differing types
152
Chapter 9
Recursion
This chapter introduces a fundamental new method of programming called recursion.
Recursion is a powerful idea that makes it possible to solve some problems easily that
would otherwise be quite difficult. Recursion cannot be used in all programming
languages, but it is supported by most modern languages, including Matlab.
Chapter 9
Recursion
154
function y = tax(income)
if income > 100000
y = high(income-45000);
elseif income > 2500
y = low(income-2500);
else
y = 0;
end
function high_tax=high(subject)
rate = 0.33;
min_tax = 18750;
raw_tax = rate*subject;
if raw_tax < min_tax
high_tax = min_tax;
else
high_tax = raw_tax;
end
function low_tax=low(subject)
rate = 0.25;
max_tax = 18750;
raw_tax = rate*subject;
if raw_tax > max_tax
low_tax = max_tax;
else
low_tax = raw_tax;
end
Figure 6. Example of
memory allocation
AR
for
low
AR
for
high
low_tax
subject
rate
max_tax
raw_tax
high_tax
subject
rate
min_tax
raw_tax
income
y
wages
due
AR
for
tax
AR
for
tax
AR
for
high
AR
for
low
low_tax
subject
rate
max_tax
raw_tax
high_tax
subject
rate
min_tax
raw_tax
income
y
wages
due
--2500
0.25
18750
625
----------5000
--5000
---
Figure 7. Snapshot of
memory during execution
Stacked on top of the memory allocated for the command window is the activation record
allocated for the function tax. It contains space for the local variables, income and y;
Chapter 9
Recursion
155
the activation record for the function high is next. Finally, at the top is the activation
record for low. We have depicted the first allocation to be at the bottom and the last at
the top, but the spatial ordering here is not important. The important thing is that each
function has its own area. We will see later that the idea of stacking one activation
record on top of the other make sense. That is the reason for showing them this way in
the figure.
Figure 7 shows a snapshot of the memory during execution. A snapshot is a list of the
values in all memory locations for a particular point in time during execution. The time
point always falls between the executions of two commands. In this case, execution,
which started in the command window with the function calldue = tax(small)
has been suspended during execution of the function low at the point in time between the
completion of the statementraw_tax = rate*subject;and the beginning of
the statementif raw_tax > max_tax. The memory locations containing the three
dashes (---) have not yet been given values. Thus, for example, since the if-statement
has not yet begun, the statementlow_tax = max_taxhas not yet executed, so no
value has yet been assigned to low_tax. Thus, three dashes (---) appear in its memory
location in place of a value.
9.2 Breakpoints
It is easy to make your own snapshot by setting a breakpoint in one of your functions. A
breakpoint is a point in the text of a function at the beginning of one of its command that
is selected by the user as a stopping point. Figure 8 shows an example. A breakpoint is
set by clicking on the dash (-) just to the left of the statement between the number of the
statement and the statement itself. The setting of the breakpoint is indicated by a red
circle. A breakpoint can be removed simply by clicking the mouse on that red circle.
Additional breakpoints can be set by clicking next to other commands. When the function
is executed, execution will be suspended just as the statement if raw_tax >
max_tax is about to begin. If we call tax, as we did in the example above, then after
the program reaches the breakpoint, the command window will look like this:
>> wages = 5000;
>> due = tax(wages)
K>>
The prompt K>>, instead of >>, indicates that a function has reached a breakpoint and
that execution is suspended. At this point, if we give the command who, Matlab will
show us the local variables that have been assigned a value in the function that has
reached the breakpoint, instead of the variables that have been assigned a value in the
command window:
K>> who
Chapter 9
Recursion
156
rate
raw_tax
subject
Note that these variables are among those listed in the activation record of the function
low in Figure 7. From this example, we learn that the command who lists the local
variables of the currently active function that have been assigned a value. The command
whos behaves in the same way. The Matlab terminology for this set of variables is
workspace. Thus, the workspace is the set of variables in the current activation record
that have been assigned a value. The letter w in who and whos comes from that term.
Heretofore, when we used either of these commands, they displayed the variables of the
command window, but now we see that they can also be used to display local variables as
well. (These two commands can be issued within a function as well, and, as expected,
they will display the assigned local variables of the function.) During suspension, these
variables are active in every sense. If we type their names in the command window, we
can see their values, and, if we wish, we can even alter their values before we resume
execution. Suppose, for example, we wanted for some reason to see what would happen if
the value of raw_tax were negative. We could try some random negative value,
say, 17 , by simply assigning raw_tax that value in the command window:
Chapter 9
Recursion
157
AR
for
low
--2500
0.25
18750
-17
-----------
AR
for
tax
AR
for
high
(a) (b)
(c) (d)
Figure 10. Breakpoint icons. (a) Remove all breakpoints, (b) Single-step,
(c) Resume execution, (d) End debugging.
Matlab has an excellent debugging system, which has other features as well (try help
debug), but the most important things to learn are that (a) you can cause execution to be
suspended by setting breakpoints, (b) you can inspect or change local variables while
execution is suspended, and (c) you can execute one step at a time. The End debugging
icon stops execution and returns control to the command window, but the breakpoints are
not removed. They will suspend execution each time the function reaches one of them.
Chapter 9
Recursion
158
Lets return now to our suspended example in which we have forced raw_tax, to have
the value -17. If we resume execution with dbcont or by clickiing the icon in Figure
10(c), we will see this result:
K>> dbcont
due =
-17
It can be seen that the change we made while execution was suspended caused the
calculation to give a strange, but predictable result.
AR
for
tax
AR
for
high
AR
for
low
As we mentioned earlier, the scheme used by Matlab to allocate memory storage for
functions is somewhat different from that described above. The scheme above is called
static allocation. Most modern languages, including Matlab, use dynamic allocation. The
difference is that with static allocation the position in memory of each activation record is
determined before the program runs and remains the same throughout execution, while
with dynamic allocation the position is determined during execution, and it may change
during execution. Static allocation allows for slightly faster execution times, whereas
dynamic allocation requires slightly less memory usage in most cases, but the main
advantage to dynamic allocation is that it
makes recursion possible. Before we see the
low_tax
--connection with recursion, lets learn how
subject
--dynamic allocation works.
rate
--Returning to the example above, lets remove
max_tax
--the breakpoint from the function low and
raw_tax
--insert one instead in the function high before
--high_tax
the statementif raw_tax < min_tax.
155000
subject
If we then issue the following commands in
0.33
rate
the command window:
18750
min_tax
>> wages = 200000;
51150
raw_tax
>> due = tax(wages)
income
200000
y
--a snapshot of the memory will look like that
shown in Figure 11. The situation is similar to
wages
200000
that of Figure 7 because four activation
due
--records are allocated while only three
Figure 11. Snapshot of memory during
activation records are used, one for the
execution.
command window and one each for two
functions. In Figure 7 the functions whose
activation records were used were tax and low; in Figure 11 the functions are tax and
high. Also, in both cases, when execution is resumed, only three activation records will
be used for the entire execution. The space set aside for the fourth activation record is
Chapter 9
Recursion
159
never used. This situation is unavoidable when static allocation is employed because with
static allocation activation records are allocated before execution begins and there is no
way to know which functions will be used before execution begins and inputs are
received from the user (in this case the argument to tax).
This problem of wasted memory is solved by means of dynamic allocation. With
dynamic allocation, an activation record is allocated only when a function is called. Lets
follow the function calls and watch how activations are allocated dynamically for the
current example as execution proceeds from just before the call of tax in the command
window through the suspension of execution at the breakpoint in high. For simplicity,
well label just the activation records without labeling the variables within them.
Before tax is called:
AR for command
window
AR for tax
AR for tax
AR for command
window
AR for command
window
No activation record is allocated for the function low because low has not been called,
so no space is wasted. Lets continue execution now and follow the allocation of
activation records through to the end:
After high has returned:
AR for tax
AR for command
window
AR for command
window
The activation record for the command window is always there, but the other ones come
and go as their functions are called and return. Now we can see why it makes sense to put
the first activation record on the bottom and the most recent activation on the top. That
way it appears that the records are in a stack with new records being put on the top of the
old ones and, when a function returns, the most recently added record is taken from the
top, just the way objects are added to, and removed from, a physical stack. That is the
way computer scientists like to think about this arrangement. In fact when memory is
allocated dynamically in this way, the collection of activation records is called the
Chapter 9
Recursion
160
AR for tax
AR for command
window
(4.8)
We can see that the second part of this definition makes sense by looking, for example, at
f 4 . By carefully grouping the four factors that make it up, we see the following:
Chapter 9
Recursion
161
f 4 1 2 3 4
1 2 3 4
(4.9)
f 3 4
Eq. (4.8) is a recursive definition. A recursive definition is a one that defines a concept in
terms of the concept itself. That would seem to be nonsense because the definition seems
to require that the object already be defined!
Looking more closely at Eq. (4.8), we see that it is only the second part that presents the
potential problem because it is only in that part that the function f shows up in its own
definition. It seems at first to be circular reasoning, but it is not. The crucial aspect of the
second part that avoids circular reasoning is that f n is not defined in terms of f n ,
but in terms of f n 1 . Thus, the definition of f n requires only that f n 1 be
previously defined, and that is not circular reasoning. It is more like spiral reasoning
because, instead of going round and round in a circle, we are spiraling down from f n
to f n 1 , and then to f n 2 , etc., ever closer and closer to the case f 1 , where at
last we will reach the first part of the definition in Eq. (4.8) and stop.
If we use Eq. (4.8) to determine the value of f 3 , for example, we would proceed this
way:
f 3 f 2 3
(4.10)
We cannot carry out the multiplication until we know the value of f 2 . So we make a
note to carry out Eq. (4.10) after we determine the value of f 2 , and we go back to Eq.
(4.8) to calculate f 2 :
f 2 f 1 2
(4.11)
We cannot carry out the multiplication until we know the value of f 1 . So we make a
note to carry out Eq. (4.11) after we determine the value of f 1 , and we go back to Eq.
(4.8) to calculate f 1 :
f 1 1
(4.12)
Finally, we have a case that does not require a further invocation of Eq. (4.8)! We have
arrived at the part of the definition that is not recursive. Every recursive definition must
include such a non-recursive part. We call the non-recursive part the base case. The
recursive part of the definition is called, appropriately enough, the recursive case.
Chapter 9
Recursion
162
Now that we have spiraled down to the base case, we look at the notes that we made to
see what remains to be done. Following our last note, we carry out the operation in Eq.
(4.11) to get f 2 = 2; then, following the note that we made before the last one, we
carry out the operation in Eq. (4.10) to get f 3 = 6. There are no more notes remaining,
so we are done.
We can use our recursive definition to help us write Matlab code to calculate f n .
Suppose we create the four functions, f1, f2, f3, and f4, shown in Figure 13. Each
function has the same form, and the form mirrors the definition in Eq. (4.8). We can use
these functions to calculate f (1) , f 2 , f 3 , or f 4 . We always call f1 from the
command window, and we give it the number whose factorial is required. Suppose, for
example, we want to calculate f 3 . We give the call, f1(3) in the command window.
The important steps in the resulting execution are highlighted in Figure 13 and are
itemized in Figure 12. Figure 14 depicts the state of the activation-record stack at each of
these steps (CW means Command Window).
It is a good idea for the reader to take the time to follow these steps through in detail to
get a clear idea of what is happening. Each function has a base case and a recursive case.
When it is called it makes a decision based on the value of its dummy argument n: If n is
equal to 1, it uses the base case, for which the answer is 1, and it returns 1. If n is greater
than 1, the function uses the recursive case: It calls the next function on the list with the
argument n-1.
There is a problem with using these four functions to calculate f n . The problem arises
when we try to calculate f 5 . We to that by giving the command, f1(5). There is no
problem in f1 which issues the call, f2(4), and is there no problem in f2, which issues
the call f3(3), or f3, which issues the call f4(2). The problem occurs when f4 issues
the call f5(1). There is no f5! Matlab issues the error: ??? Undefined
function or variable 'f5'. We could of course define an f5, and an f6, etc.,
but that is a lot of trouble, and we do not need to. Matlab provides a better way:
recursion.
Chapter 9
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Recursion
163
15
1
2
1-3
4-6
4
5
7
8
7-10
11-12
13-14
15
f3
CW
14
13
before 1
>> f1(3)
ans =
6
f2
f2
f2
f1
f1
f1
f1
f1
CW
CW
CW
CW
CW
Figure 14. Activation record stack at each of the numbered steps in Figure 12.
CW
12
11
10
Chapter 9
Recursion
164
>> f(70)
ans =
1.1979e+100
With this example, the activation-record stack gets very tall. When the base case is
reached, there are 71 activation records on it: 70 corresponding to calls of f and one for
the command window. The stack is tall, but when referring to the degree of recursion, it
is customary to say that the recursion level is deep. In this case the depth of the recursion
is 70 (or arguably 69, since the record for the first call is not recursive).
For a given computer system, there is always a limit to how tall the stack can get because
every activation record occupies memory space, and the memory space on any computer
is finite. Matlab itself puts a limit to the depth of recursion, which defaults to 500. We
can demonstrate that limit as follows:
>> f(0)
??? Maximum recursion limit of 500 reached. Use
set(0,'RecursionLimit',N)
Chapter 9
Recursion
165
0.5, for x 0
g x 1
tan sin x 4 g x 0.7 , otherwise
(4.13)
A recursive function that implements Eq. (4.13) is given in Figure 16. Note that the base
case includes every negative value of x. Unlike the function in Figure 15, it is not
possible to bypass this base case for this function. Thus, there is no need for it to check
for erroneous input.
It is unfortunately easy to write
functions that include cases of
infinite recursion. If, for
example, in Eq. (4.13) we were
to change the base case to
g x 0.5, for x 0 (i.e.,
function a = g(x)
if x < 0
a = -0.5;
else
a = atan((sin(x)+4)*g(x-0.7));
end
Chapter 9
Recursion
166
have negative arguments. The arguments would never hit zero. Matlab would halt the
function with an error when the stack reached 501.
It should be clear that the recursive call should move the function closer to the base case.
In the factorial problem of Figure 15, the argument moves one closer to n == 1 each
time. In Figure 16, x moves closer to being negative by 0.7 each time. A common error
is to write a recursive function that results in infinite recursion because the argument
moves further from the base case. That could happen in Figure 16, for example, if the
recursive call had been, g(x+0.7), instead of g(x-0.7).
9.5.2 Multiple recursive calls per activation
The functions in Figure 15 and Figure 16 each makes one recursive call per activation.
There are many examples of functions that make two or more recursive calls per
activation. We will look at two of them: the Fibonacci series and the derivatives of a
function.
Example 1: The Fibonacci Series
A famous series that can be generated by a function that makes two recursive calls per
activation is called the Fibonacci series, named after the 13th century mathematician who
invented it. Fibonacci posed this problem:
Suppose a pair of rabbits, one male and one female, is born on January 1.
Suppose further that this pair of rabbits gives birth to a new male and female on
the last day of their second month of life, their third month of life, their fourth
month, etc, forever (mathematicians do not care about reality). Finally, suppose
that all new pairs of rabbits do the same. How many pairs of rabbits would be
alive on the first day of the Nth month (and who but a mathematician would
care)?
To help us understand the problem, lets consider the first few months. Figure 17 is a
schematic representation of the development of the rabbit population from January 1
through July 31. Each solid horizontal line is the life-line of a pair of rabbits; the first pair
has the longest line. Each vertical line represents the birth of a new pair.
The number of pairs of rabbits alive at the beginning of a month is equal to the number of
solid horizontal lines that intersect the vertical dotted line for that day. By counting the
intersections we can see the following progression in the number of pairs:
1,
1,
2,
3,
5,
8,
13
These numbers are a consequence of the rules Fibonacci gave for the births. To see how
these rules produce these numbers, we can look the changes, month by month:
Chapter 9
Recursion
167
January 1 and February 1: The first two months are simple. Since the first pair requires
two months to produce offspring, there is one pair on January 1 and still just one pair on
February 1.
March 1: On the last day of February, the first pair produces its first offspring, so there
are two pairs on March 1.
.
April 1: April is the first interesting month. It is interesting because some rabbits
reproduce and some do not. Only the rabbits that are at least two months old reproduce,
so only the pairs that were alive on February 1 will produce a new pair. There was only
one pair alive then, so one new pair is added to the number alive March 1 to bring the
total to three. Thus, the number of pairs on April 1 is equal to the number of pairs on
February 1 plus the number of pairs on March 1.
Number
of pairs of
rabbits
Jan 1
Feb 1
Mar 1
Apr 1
May 1
Jun 1
13
Jul 1
May 1: May is interesting as well for the same reason. Again only those rabbits that are
at least two months old will reproduce, so only the pairs that were alive on March 1 will
produce a new pair. There were two pairs alive then, so two new pairs are added to the
number that were alive on April 1. Thus, the number of pairs on May 1 is equal to the
number of pairs on March 1 plus the number of pairs on April 1.
By now, we can see a pattern: To determine the number of pairs alive at the beginning of
month N, we add the number of pairs alive at the beginning of month N 2 to the
number of pairs alive at the beginning of month N 1 . Letting F N stand for the
number of pairs of rabbits alive on the first day of the Nth month, we have
Chapter 9
Recursion
168
F N F N 2 F N 1
(4.14)
To check things out lets use the function in Figure 18 to calculate the number of pairs for
a month whose answer we already know. Well try May:
>> fibonacci(5)
??? Maximum recursion limit of 500 reached. Use
set(0,'RecursionLimit',N)
to change the limit. Be aware that exceeding your available
stack space can
crash MATLAB and/or your computer.
Error in ==> C:\Documents and Settings\Matlab\fibonacci.m
On line 2 ==> pairs = fibonacci(month-2)+fibonacci(month-1);
Can you guess what happened? We forgot to include a base case! Calls of fibonacci
were made with month = 5, 3, 1, -1, -3, -5, ..., -993. At this point there were
500 activation records on the stack. The next call caused the error. Our error came from
Eq. (4.14). A corrected version of Eq. (4.14) is given in Eq. (4.15).
1, for N 1
F N 1, for N 2
F N 2 F N 1 , otherwise
(4.15)
We now have a base case. In fact we have two of them, one for N = 1 and one for N = 2.
A corrected version of fibonacci, implementing Eq. (4.15) is shown in Figure 19.
function pairs = fibonacci(month)
if month == 1
pairs = 1;
elseif month == 2
pairs = 1;
else
pairs = fibonacci(month-2)+fibonacci(month-1);
end
Figure 19. Corrected recursive Fibonacci function.
Chapter 9
Recursion
169
>> fibonacci(5)
ans =
5
>> fibonacci(6)
ans =
8
>> fibonacci(7)
ans =
13
>> fibonacci(8)
ans =
21
Example 2: Derivatives of a function
Another example of recursion involving two recursive calls per activation arises when we
estimate numerically the 1st, 2nd, 3rd, etc., derivatives of a function. The definition of a
derivative is, from calculus,
f 1 x lim
x 0
f x x f x
x
(4.16)
f x 12 x f x 12 x
x
(4.17)
where we assume that x is small enough to produce a good approximation to the limit
as x approaches zero. The second derivative is defined as follows:
f
f x x f x
x lim
x 0
x
1
(4.18)
f x 12 x 2 f x 12 x 2
1
x 2
(4.19)
Both of these definitions involve recursion. We can give complete recursive definitions
of all derivatives and their approximations as follows:
Chapter 9
Recursion
f x , for n 0
x f n1 x x f n1 x
, otherwise
lim
x
x 0
170
(4.20)
where we have added the concept of the 0th derivative, f 0 x f x . Similarly, the
recursive definition for the numerical approximations to these derivatives is
f x , for n 0
f n x f n 1 x 12 x n f n 1 x 12 x n
, otherwise
x n
(4.21)
obtained by means of the @ operator. For example, if we wish to calculate the 3rd
derivative of the sine evaluated at 0.4, we would give the following command:
>> derivative(@sin,0.4,3)
ans =
-0.92106
Chapter 9
Recursion
171
This answer can be easily checked by comparing with the 3rd derivative of the sine, which
is simply negative of the cosine:
>> -cos(0.4)
ans =
-0.92106
There are many, many other examples of recursive problems and recursive functions.
Two important applications that involve many recursive problems are searching and
sorting. The next chapter introduces these two applications and gives examples of
recursion in both.
Matlab:
o breakpoint
o debugging system
o workspace
Chapter 10
Searching and Sorting
In this chapter we will look at two closely related problems: searching and sorting. Both
problems appear in applications involving databases, and without efficient solutions to
these problems databases would be virtually useless. They would be useless because
databases that are large enough to hold the information we need would be too large to
use. They would be too large to use because it would take too long to find what we are
looking for inside them. There is a large variety of specific applications of searching and
sorting, but the most basic ones involve locating an element in a vector whose value is
equal to a target value. We will use that simple problem as our driving example
throughout this chapter.
10.1 Searching
Searching is important in many areas of computer science. Many large computer systems
include databases that must be searched when an inquiry is made. For example, when you
phone a credit-card company to inquire about your bill, you will be asked for your card
number. In a few seconds the company representative will be looking at your data. Your
data and that of tens of millions of other customers are all stored in a database. Your
information is found by searching among all those millions of card numbers. The target
of the search is your unique number. Furthermore, every day, millions of transactions,
each involving one of those unique numbers take place, and each one requires that a
target number be located in a list of all card numbers. In each of these examples, in the
calculation of account balances, and many other cases, the first task it to find the account
with the target number, and it is accomplished by a searching algorithm.
Chapter 10
175
indicating a special condition. In this case the condition is target not found, or search
failure. In other situations it might mean modem is ready to receive data (i.e., good
news) or modem is not ready to receive data or buffer empty or disk full, etc. A
given flag may also have many possible meanings depending on which of a set of
meaningful values it has. In the present case, in which we are searching for a target, a
positive index can be considered to be a flag that means target found or search
successful, and it conveys further information as wellthe index of the element in
which the target was found. Thus, when we returned 3 above, it meant The search was
successful, and the target was found at index 3.
The function, sequential_search, below carries out the sequential search:
function index = sequential_search(vector, target)
%SEQUENTIAL_SEARCH sequential search
%
SEQUENTIAL_SEARCH(VECTOR,TARGET) returns smallest index
%
for which TARGET == VECTOR(index), or returns -1, if
%
TARGET is not found in VECTOR.
Found = 0; % Assume the target is not in vector
first = 1;
last = length(vector);
for n = first:last
if target == vector(n)
Found = 1; % We found it..
break;
% ..so we quit looking for it!
end
end
index = n;
if ~Found
index = -1;
end
As promised, this function returns 1, as a flag indicating failure, where failure means
that the target value is not equal to any of the elements in the vector. It is customary in
computer science to refer to vector of numbers as a list, and if one of the elements of the
list has a value equal to the target, it is customary to say that the target is on the list or the
target is in the list. If the target is on the list, then sequential_search returns the
first position at which it finds the target. So, for example, suppose the function is applied
to the list [45 23 17 17 2 100 34]. In that case, the number 17 would be found
at index 3 after the target had been compared with three numbers: 45, 23, and 17 (the first
17, that is). When searching for a target that is not on the list, 82, for example, the
function will have to compare the target with every number on the list, requiring 7
comparisons. These few comparisons will not take long, but if there are a million
numbers on the list, time can become a significant factor. If the target is not on the list, or
if it is last on the list, a million comparisons are required. Numbers close to the beginning
will be found quickly, numbers toward the end will take longer, but if all elements are
Chapter 10
176
equally probable, the mean number of comparisons required will be about half the length
of the list: in this case, half a million. Faster searching methods are available, but only if
the list has been sorted before the search is undertaken. For an unsorted list, the
sequential search is the only possible choice.
10.1.2 Binary search
If a list has been sorted before the search is undertaken, searches can be carried out much
more quickly. The search method that should be used in this case is the binary search. It
is more complicated than the sequential search method, but the complication is well
worth it: A binary search requires no more than 40 comparisons to find a number on a list
of one million numbers, whereas a sequential search can require a million of them.
10.1.2.1 Recursive implementation of the binary search
If you have ever looked up a number in a phone book, the recursive approach to the
binary search is one that you already know about. You dont look at every name
sequentially, as in the sequential search algorithm. Instead, you look at a page near the
middle of the phone book. You look at one name on that page and note whether the target
name that you are searching for comes before or after it. If the target name comes before
the name on that page, then you have eliminated about half the names in the book. Then,
you go to a second place in the phone book closer to the beginning and repeat the
process.
The process that you are repeating is the process of finding a name in a list by looking
near the middle and eliminating about half the names in the list. Each time you are
applying the process to a smaller list, but otherwise the process is the same. Since the
process includes the application of itself (to a smaller list), it is recursive. Near the end of
the recursive process, you will probably abandon the approach of eliminating sections of
the book and just scan through the names on a page or two, but the major work was done
when you eliminated large chunks of the book at the beginning with the first few
recursive steps.
When you use this approach you are carrying out your own recursive approximation of
the binary search, and that is the version of binary search that we will consider first. In
Figure 21 a recursive function is shown that implements the binary search algorithm.
Note that there are four arguments. Argument 1 is the vector to be searched, and that
argument is assumed to be sorted in ascending order. Argument 2 is the target that we are
looking for. Arguments 3 and 4 give the beginning and end, respectively of the range of
indices over which we wish to search. Most of the time we will set first to 1 and
last to the length of vector, but sometimes we may wish to search only some limited
range. Including arguments 3 and 4 provides this option. So for example, if we wish to
search all of vector, we would give the call,
>> binary_search_recursive(vector, target, 1, length(vector))
Chapter 10
177
but, if we wish to search only within vector(45:56), we would give the call,
We will see that allowing the range to be specified is also crucial to the recursion. The
function works as follows:
Line 7: The middle of the range is determined. If first is odd and last is even,
or vice versa, then that average will not be an integer. Since mid must be an
integer in order to be an index, the fix() function is used to discard the
fractional part (which is always 0.5), if there is one.
Lines 8-9: If first and last are out of order, then the range is empty, so
target cannot possibly be in the range. Therefore failure is flagged by returning
-1.
Lines 10-11: The value of target is compared to the element at the middle of
the range. If the target and the element are equal, then the search is successful.
Therefore the middle index is returned.
Line 12: If target is less than that middle number, then the middle element and
all the elements that come after the middle element can be eliminated. The search
can now be confined to the range of elements that come before the middle one.
Line 13: A recursive call is made to search only the range of elements that come
before the middle. Whatever index is received from this recursive call is returned.
Line 14: If this statement is reached, then target must be greater than the
middle element. That means that the middle element and all the elements that
Chapter 10
178
come before the middle element are eliminated. The search can now be confined
to the range of elements that come after the middle one.
Line 15: A recursive call is made to search only the range of elements that come
after the middle. Whatever index is received from this recursive call is returned.
It is important to note that, during the first call of this function, about half (actually just
over half) the numbers are eliminated before the first recursive call is made. This search
algorithm is in fact named binary search because the list is repeatedly divided into two
parts. (Actually it is divided into two big parts and one very small one. The very small
part is the single element in the middle.) Searching a subrange of the list would not be
possible without the provision of the 3rd and 4th arguments that allow us to restrict the
range that we search. Thus, these two arguments are crucial to the recursion. The
elimination of about half the remaining elements happens again on the second recursive
call, and on the third, and on each successive recursive call. Thus, each call cuts the size
of the problem roughly in half.
This is a powerful approach to searching because relatively few divisions are required to
trim a large list down to one number. If, for example, we search a list of one million
elements for a target that is equal to the last number on the list, the successive numbers of
elements to be searched with this algorithm are 1000000, 500000, 250000, 125000,
62500, 31250, 15625, 7812, 3906, 1953, 976, 488, 244, 122, 61, 30, 15, 7, 3, 1. This can
be shown to be the worst case. Thus, if the number is in the list, even in the worst case
there will be only 20 calls of binary_search_recursive required to find a target
number within in a list of 1 million numbers. It takes no more than 21 calls to hit failure
when the target is not there. In either case (i.e., the target is on the list or not on the list),
during those 20 or 21 calls, no more than 40 comparisons will be made between target
and the elements of vector. This is a very small number compared to the million
comparisons required by the sequential search: a factor of 25,000 fewer!
The strategy of dividing a problem into smaller problems and then attacking the smaller
problems recursively is a standard approach in the field of algorithms, which is the field
of computer science that deals with the efficiency of computer programs. This strategy is
called divide-and-conquer9. We will look more closely at the idea of efficiency in a later
section of this chapter.
It is informative to follow the algorithm as it works its way through a few specific
searches. Suppose we are searching for targets in a vector named A, which contains 11
elements:
A = [2
17
17
24
43
74
77
80
88
97]
Chapter 10
179
>> binary_search_recursive(A,88,1,length(A))
ans =
10
This search involved three calls of the function (the second two being recursive calls).
The following is a summary of the search progression showing the search ranges for each
successive function call along with the element A(mid) in the middle of the range that
was compared to the target:
>> binary_search_recursive(A,17,1,length(A))
ans =
3
Here is the summary of this search:
Range = A( 1)=
Range = A( 1)=
Here, only the two numbers, 43 and 17, were compared with the target.
It is interesting to note that the first number compared with the target for this list is, in
each case, 43. This is always the first number for this list, because the algorithm always
starts at the middle of the list, regardless of the value of the target. It is also noteworthy
that if there are two or more instances of the target on the list, only one will be found (not
necessarily the first one).
Finally, lets try one example in which the target is not on the list:
>> binary_search_recursive(A,90,1,length(A))
ans =
-1
The summary looks like this:
Range
Range
Range
Range
Range
=
=
=
=
=
A( 1)=
A( 7)=
A(10)=
A(11)=
A(11)=
2
74
88
97
97
to
to
to
to
to
A(11)=
A(11)=
A(11)=
A(11)=
A(10)=
97,
97,
97,
97,
88
middle
middle
middle
middle
element
element
element
element
A( 6)=
A( 9)=
A(10)=
A(11)=
43
80
88
97
Chapter 10
180
This time, the numbers 43, 80, 88, and 97 were compared with the target. In the last
range the first and last elements are out of order, so the algorithm treats the range as
empty. No element is compared with the target. The algorithm halts and returns -1 to
indicate that the target is not on the list.
Chapter 10
181
while loop is executed. As with the recursive version, the variables first and last
are set to be equal to the first and last indexes, respectively, of the range being searched,
but unlike the recursive version, it is not necessary to include them as arguments to the
function. The dividing of the list into smaller and smaller pieces is accomplished by
changing one of these two values at a time, either moving first closer to the end or
last closer to the beginning. As with the recursive version, the index of the element in
the middle of the list is assigned to mid by taking the average of first and last.
All this work is done in a while loop. That loop will end when the target is found
because, in that case, the value of found is changed to 1 (meaning true). If the target
value is not in the list, then the loop will still halt when the values of first and last
become out of order (first>last), as in the recursive version. As before, having first
greater than last means that the range is empty so the target cannot possibly be within it,
and the number 1 is returned as a flag to mean that the number was not found. Lets
apply this algorithm to the first examples given above for the recursive version. The call
is a bit simpler because of the missing 3rd and 4th arguments:
>> binary_search_iterative(A,88)
The search ranges and middle elements are exactly the same as for the recursive version.
In fact the summaries given above for the recursive version apply to the iterative version
as well as they do to the recursive version.
10.2 Sorting
Thanks to the advantage provided by the binary search algorithm over sequential search,
it should be obvious that large lists that are going to be searched repeatedly should first
be sorted in order to make subsequent searches more efficient. Sorting is another
important task in computer applications and is carefully studied by students of that field.
It is important because of the large savings in search time possible when using the binary
search instead of the sequential search. Many sorting methods have been developed,
some of which are quite complicated (far more complicated than the binary search
algorithm given above, for example). The benefit in reduced sorting time is, however,
worth the programming effort. Students who choose computer science or computer
engineering as their major spend a good deal of time mastering the concepts involved in
efficient sorting algorithms. The simplest form of the problem is to sort into ascending
order a vector of numbers. We will confine our attention to that problem.
Chapter 10
182
It is used as follows,
>> vs = selection_sort(vu)
where vu is the vector to be sorted and vs is a vector containing the same elements as
vs but arranged in ascending order.
To learn how the selection sort works, suppose selection_sort is given the
following list:
v = [28
27
86
15
28
64]
Step 1: Find (i.e., to select, hence the name selection sort) the smallest element, which
in this case is v(4), which equals 15, and swap it with the first element, v(1), which
Chapter 10
183
equals 28:
v = [28
27
86
15
28
64]
27
86
28
28
64]
The result is
v = [15
Now we have taken care of v(1), and all that remains is to sort the items in v(2:end).
Step 2: Find the smallest element in v(2:end) and swap it with v(2). As it happens
in this case, the smallest element in v(2:end) is already in v(2). So no swap is
necessary. The list is still
v = [15
27
86
28
28
64]
Now we have taken care of v(1:2), and all that remains is to sort the items in
v(3:end).
Step 3: Find the smallest element in v(3:end) and swap it with v(3). As it happens
there are two smallest elements: both v(4) and v(5) have the smallest value, 28. We
choose to use the first of these, swapping with v(3):
v = [15
27
86
28
28
64]
27
28
86
28
64]
The result is
v = [15
Now we have taken care of v(1:3), and all that remains is to sort the items in
v(4:end).
Each of these three steps is carried out by one iteration of the outer for loop in lines 7-19
of selection_sort. There have thus far been three iterations, during which m has
taken on the values 1, 2, and 3. Each iteration of that loop involves finding the smallest
element in v(m:end) and swapping it with v(m), as we have been doing above. When
iteration m is over, v(m:end) has the correct elements and v(m+1:end) remains to be
sorted.
The work of finding the smallest element is done by lines 8-13. (We could use Matlabs
min function to find it, but that would hide some of the complexity of the algorithm.)
When those lines are completed, the variable m_min holds the index of the smallest
Chapter 10
184
element in v(m:end). Those lines begin with the guess on line 8 that the smallest
element is at the beginning of v(m:end). Thus, m_min is set equal to m. The inner loop
in lines 9-12 then compares that guess against the first element after m, namely, v(m+1).
If it is smaller, then m_min is set equal to m+1, which is the new guess. The loop index n
holds the index of each element to be compared with the latest guess. When n has
reached the end of the vector, and element v(end) has been checked, the guess has
become a certainty. At this point we know that v(m_min) is the smallest element in the
v(m:end).
Now it is time to swap v(m) and v(m_min). That work is handled by lines 14-18. The
if statement checks to see whether a swap is necessary at all. It is unnecessary if the
smallest element is already at v(m), so the swapping is avoided if m_min is equal to m.
If a swap is required, lines 15-17 do the job. These three lines are very common in
computer programming. In order to swap two numbers, it is always necessary to hold one
of them in a temporary variable, often called temp, as in this example. The swap always
begins (line 15) with the copying into the temporary variable of the first one of the values
to be swapped, in this case v(m). The next step (line 16) always copies the second of the
values to be swapped, in this case v(m_min) into the first variable. If it were not for the
fact that we have saved a copy of the original value of first variable in temp, this
copying (i.e., line 16) would cause it to be lost. The final step (line 17) always retrieves
that saved value and copies it into the second variable.
The selection sort continues in this way with its outer loop incrementing m and working
on a smaller and smaller part of the list, v(m:end), each time using the inner loop to
find the smallest element in v(m:end), and using lines 14-18 to swap it with element
v(m). The outer loop stops one position short of the end of the loop when the index m
= length(v). It can stop there because the previous step has established that the last
element is not smaller than the next-to-last element. Therefore, the sort is complete.
10.2.2 Quicksort
A sorting method that is much more efficient for most lists than selection sort, and is
fairly easy to understand, is quicksort.10 A function that implements the quicksort
10
Chapter 10
185
algorithm is given in
Figure 24. Quicksort employs the divide-and-conquer strategy. The central idea is to
divide the vector v that is to be sorted into three parts:
(a) v(1)
(b) a list, which we will call smaller, that consists of all the elements in v that are
smaller than v(1)
(c) a list, which we will call remainder, that holds the remainder of the elements
in v., i.e., those elements in v[2:end] that were not copied into smaller.
Chapter 10
186
v = [28
27
86
>> quicksort(v)
15
28
64]
Chapter 10
187
64]
Step (b) is accomplished by means of lines 11-12. Together these two lines provide an
example of Matlabs logical indexing feature, which is the use of a logical array to
select the desired elements of an array, instead of the normal method of listing the desired
indices. Logical indexing was introduced in Chapter 6.
The right side of line 11 produces a vector whose elements each equal 1 or 0, with 1
meaning true and 0 meaning false. The vector is then assigned to less. The
true/false value of each element less(i) is based on whether v(i)<v(1), i =
1, 2, .... As explained in Chapter 6, the result is called a logical array,
meaning that its type is logical and can therefore be used in operations like the one
on the right side of line 12. The value that is assigned to less in this example is [0
1 0 1 0 0], since v(2) and v(4) are the (only) elements that are less than
v(1).
The right side of line 12 produces a vector consisting of those elements of v that are
located at the same positions as the 1s in less. They are kept in the same order too.
Thus, the vector assigned to smaller is [27 15], since v(2) = 27 and v(4) =
15.
The total effect of lines 11-12 is to remove the elements of v that do not satisfy the rule,
v(i) < v(1).
Step (c) is accomplished by lines 13-14.
Line 13 is similar to line 12, but the logical array less has been replaced by
~less, whose value is opposite to that of less: [1 0 1 0 1 1]. Thanks
to the not operator ~, the vector assigned to smaller has 1s at the positions
for which the elements v(i) is not less than v(1). These elements are v(1) =
28, v(3) = 86, v(5) = 28, and v(6) = 64. Logical indexing causes each
of these elements to be copied into remainder, which now equals [28 86 28
64]. Note that v(1) is on the list. While it is true that v(1) is not smaller than
v(1), we do not want it on this list
Line 14 is responsible for removing v(1) from remainder. Because the
logical indexing operation in line 13, does not change the order of the elements,
v(1) is still in the first position. Since remainder(2:end) contains
everything in remainder except its first element, we can be assured that v(1)
has been left off.
Chapter 10
188
left = quicksort(smaller)
which returns left equal to the sorted list, [15
16,
right = quicksort(remainder)
sets right equal to [28
sorted list:
64
27
28
28
64
86].
Chapter 10
189
Figure 24, the base case is determined by the length of the list. If the length is one, then
there is no work to do. The list is returned without change. The same holds for an empty
list (length equal to zero). For all other lengths recursion is employed.
The quicksort algorithm is much faster than selection sort for most lists. As an example,
on one machine the selection sort takes 19 times as long as quicksort to sort 100 thousand
numbers.11
11
160 seconds for selection_sort, 19 seconds for quicksort on a 1.3 GHz Pentium processor with
512 MB of RAM
Chapter 10
190
There are sorts that do not suffer from this problem. One of them is the merge sort. Like
quicksort, it uses divide and conquer, but it is guaranteed to divide the list into two equal
parts, or, if there is an odd number of elements parts whose lengths differ by only one. A
recursive implementation of merge sort is shown in Figure 25. The algorithm is fairly
simple, but this implementation hides a bit of the complexity because of the call to the
function merge_sorted_lists. The base case is determined by the length of the list
as in quicksort: lists with 0 or 1 elements are already sorted, so the function simply
returns. Line 11 begins the interesting part of the algorithm. The midpoint is determined
in line 11. In line 12 the elements from the first up to this midpoint are sorted. In line 13
the rest of the numbers are sorted. Line 14 does the rest of the work by calling
merge_sorted_lists. That function combines the two sorted lists into one sorted
list. We leave a discussion of that function to the exercises that accompany this chapter. It
is line 11 that guarantees that this algorithm, unlike quicksort, will always divide the
list into approximately equal halves, regardless of the elements in it.
There are many other sorting algorithms available, and computer scientists spend a good
deal of time studying them. Matlab provides an excellent sorter called sort. It uses
varying strategies according to the size of the list and the size of the available memory. A
study of these strategies and of sorting in general is beyond the scope of this textbook.
Chapter 10
191
Chapter 10
192
sequential: a + b*N,
binary: a + b*ceil(log2(N+1)),
where the a and b represent constants that will be different for the two algorithms (i.e.,
two different values for a and two different values for b). The value of a represents the
start-up time for the algorithm (including the time for Matlab to set up the activation
record for the function). The value of b represents the amount of time required per
comparison in the sequential search and represents twice the amount of time required per
comparison in the binary search. The plot below shows a sample behavior for these
functions when a=100 and b= 5 for the sequential search and a=200 and b=10 for the
binary search:
Note that the binary search (these plots are for fictitious implementations) actually
requires more time for small lists (fewer than about 30 items), but after the size of the list
has grown to 100, the sequential search takes over twice as long. The advantage of binary
search grows as N grows. For N = 1000, the ratio is 8 to 1, and for N = one million the
ratio is over 6000 to one!
10.3.2 Order Notation
The important difference between the two plots above lies in the difference between their
general shapes. Both plots increase monotonically with the number of items, but the red
plot (the binary search) has a different shape. It curves downward. Because of that
Chapter 10
193
downward curve, it will eventually go below the straight-line blue plot (the sequential
search).
There are three things that differ between the two formulas above. Each formula has
different values of a and of b and one has ceil(log2(N+1) where the other has
simply N. Of these, the difference that determines the shape of the curve is the last one
the dependence on N. That is so because, for any values of a and b in either or both
formulas, the second formula will produce a plot that curves downward and hence will
cross the straight line for sufficiently large N. That means that for a big enough problem
the binary search will win, even if its a and b are bigger then the a and b for the
sequential search (as they are in the example above). Furthermore, as the plot below
shows, there is little importance to either the ceil() or the +1 in
ceil(log2(N+1)). When we omit them, we are left with log2(N), and the resultant
plot (the dashed line) is almost the same. Finally, the importance of log2(N) is the fact
that we are taking the log of N, regardless of what the base is. As the plot below shows, if
we were to replace log2 with log10 (log base 10), the general shape of the plot would
be the same. It is curved downward, so it will cross the plot of the sequential search. It
crosses the plot of the sequential search at a different place, but the important thing is not
where it crosses, but the fact that it must cross somewhere.
Thus, the important aspects of the worst-time behavior of the binary search can be
described simply by saying that the plot of the search time versus N has the same shape
as log(N) for any base. Likewise the important aspects of the worst-time behavior of the
sequential search are captured by saying that the plot of the search time versus N has the
Chapter 10
194
same shape as N. These statements are said more formally as follows: The worst-case
time complexity of the sequential sort is order N. The worst-case time complexity of the
binary sort is order log N. The phrase order N is written O(N). The phrase order
log(N) is written O(log N). Usually a computer scientist will simply write, the binary
search is O(log N), leaving out the words time and complexity, which are to be
understood. (Sometimes we are interested in the increase in memory required by an
algorithm as N increases, as opposed to the increase in time. In that case, we measure
space as a function of N and determine the space complexity). This notation is called
Order notation, Big-O notation, or sometimes, O notation.
The selection sort is O(N2). The quicksort algorithm is also O(N2), because of its
difficulties with its worst case, a list that is almost in order. Merge sort and all the best
sorting algorithms, Matlabs sort for example, are O(N log N).
We have now discussed four complexities: O(log N), O(N), O(N log N), and O(N2). As
the plots below show, they are listed here from fastest to slowest. The relative sizes are
so different that in order to show them all on the same plot, we have multiplied the first
three by 10,000, 500, and 100, respectively.
Chapter 10
195
10.3.3 Dominance
It is clear from the discussion above that the value of a in the formulas is unimportant.
That is because the second term dominates a for very large values of N. A similar thing
happens for formulas like this: a*log(N) + b*N. Here, the second term is the only
important one because N dominates log(N). The dominance of N over log(N) can be
stated this way: the ratio, N/log(N) can get as large as desired, provided N is made large
enough. In terms of algorithms, that means that if an algorithms time-behavior is of the
form a*log(N) + b*N, then the algorithm is O(N), not O(log N + N). The dominant
term determines the order of the algorithm because the other terms become insignificant
for very large N.
Chapter 10
Matlab:
o [No new concepts specific to Matlab]
196
Chapter 11
Graphical User Interfaces
By default, Matlab runs through a command line interface. That is, individual commands,
functions or scripts are executed by typing instructions into the command window and
pressing enter. For many years, this was the primary method for interacting with a
computer. Contemporary applications of the command line interface still abound. The
DOS prompt in Microsofts command window, as well as the UNIX and Linux operating
systems, for example. Since the 1990s, however, the command line has been replaced as
the dominant method for computer control by the graphical user interface. Popularized by
Apple, and later Microsoft, the graphical user interface provides a more user-friendly and
intuitive means for human-computer interaction. Long, text commands, prone to error,
have been replaced by clicks of the mouse on icons and buttons. Virtually all programs
you use today utilize graphical user interfaces. Even Matlabs command window is
encapsulated within such an interface. Even though Matlab programming is primarily
designed for small groups of experienced users, the importance of graphical user
interfaces has necessitated their inclusion.
Matlabs capabilities in regard to graphical user interfaces have evolved significantly
over the past few years. Each subsequent release has included improvements,
refinements, and additions. Therefore, the features discussed in this chapter may not be
representative for your version.12
This chapter is based on Matlab Version 7.7.0.471 (R2008b), released September 17, 2008.
Chapter 11
198
have practically died out and have been replaced with C++, Java, Visual Basic and
others. Matlab is, in fact, an OOP language.
11.1.1 Objects
OOP requires, by definition, the use of objects. This suggests the question, of course,
what is an object? In everyday life, we can think of an object as a self-contained,
uniquely identifiable thing. That is, if you look around your desk, youre likely to see
many different objects: a pencil, your computer monitor, a math textbook. Each of these
objects is distinct from the others, even if only in small ways. For example, two pencils
might look identical, but they exist in two different spatial locations, and are therefore
distinct, separate objects.
To a certain extent, this definition is a slippery slope: How far do you go in defining
distinct objects? For example, take a look at your computer keyboard. We might think of
that as an object. But a keyboard is made up of individual keys. So whats the object: the
keyboard or the keys? The answer actually can be both. An object may consist of a group
of other objects. But you probably see how this can get confusing. There is really a great
deal of latitude in defining an object. As a programmer, you get to make the decisions as
to what is or is not an object.
From a programming perspective, an object is defined as a set of data values and all the
functions that operate on that data. The user of a programming language that supports
object oriented programming is able to specify both the type of data and the functions for
new objects. Thus, an object is simply an instance of a user-defined data type. The data
may be other objects, which may, in turn be objects, until we get finally to an object
whose data are of types that are defined by the language itselftypes that come with
the language. For example, an object may be defined that consists of a two-element
vector and a function that calculates the mean of these two elements. Another object may
be a object can also be a collection of other objects and functions that operate on that
collection. In programming languages such as C++ or Java, this very general approach to
the meaning of object is supported by an incredibly flexible environment for defining and
creating objects. For our purposes, we will take a much more restrictive, but easier to
understand, view. We will consider only a set of predefined objects in graphical user
interfaces are very well defined and rather intuitive to program.
Think about your Matlab operating environment. You have a series of windows
(command window, workspace, current directory, etc.) There is a menu along the top as
well as a series of icon buttons for new document, cut, paste, etc. Each window is an
individual object. So is each button. We can also think of the overall operating
environment as an object as well.one that contains a series of other objects (the
windows, buttons, etc.)
Chapter 11
199
11.1.2 Properties
Objects are described by their properties. These are typical descriptive characteristics
such as color, height, width, location, etc. The objects in our Matlab operating
environment all have a distinctive set of properties. For instance, the command window
has properties describing its size, background color and location on the screen. Even the
text that appears inside the window is a property. The buttons have properties describing
their color, location, the image that appears on them and even whether theyre active or
inactive (grayed-out).
Much of the work thats involved in programming graphical user interfaces involves
manipulating the properties of objects on your screen. For example, if you designed a
program that would multiply two numbers and return the answer at the click of a button,
your program would have to change the String property of an object to display the
product.
In most OOP languages, the syntax for manipulating properties resembles that of
structure arrays:
Object_Name.Property_Name = Property_Value
In Matlab, you use a function, called set to change the value of a property, and a
function called get to read the value of a property. We describe these functions below.
There are many possible events in graphical user interfaces: the click of a button, entering
text in a box, hitting the enter key, closing a window, and even something as simple as
moving the mouse. When one of these events occurs, your program will execute a
function corresponding to that event. Oftentimes, this is the bulk of your programming.
You have to write the code that tells Matlab what to do when specific events occur.
In most of the Visual languages (such as Visual Basic, Visual C++, Visual J++, etc.),
there are literally hundreds of possible events that must be accounted for. In Matlab,
however, there are only a few possible events. In general, each object has one potential
event associated with it. This significantly reduces the complexity and quantity of the
programming required for a graphical user interface.
Chapter 11
200
11.2.1 Handles
In most OOP languages, setting the properties of objects is relatively straightforward. As
mentioned previously, however, its a little more complicated in Matlab. The reason has
to do with the way in which Matlab stores object information in GUIs. Matlab holds
every object and all their properties in a large cell array. To keep track of individual
objects, Matlab assigns each object a reference number, called a handle. Rather than
referring to an object by its name, we have to refer to it by its handle.
Handle numbers are generated by Matlab, and in general, we dont need to know their
values. We need to pass them as arguments to some important GUI functions, however,
so there must be a way to assign them to variables. In earlier versions of Matlab (before
6.0) it was necessary in every case to use one of these three functions to find an objects
handle.
gcbo returns the handle of the object that initiated the event
gcbf returns the handle of the figure that contains the object that
initiated the event
findobj(figure, property, value) returns the handle of
any object in a given figure that has a matching value for the given
property
In all subsequent versions, however, there are always two variables available that contain
the handles that we need: First, a variable named hObject contains a copy of the handle
of the object that initiated the most recent event, thus removing the need for calling
gcbo. Second, a variable named handles is a struct, whose field names are the tags
of all the objects in the GUI figure, including the figure itself, and whose field values are
Chapter 11
201
their handles, removing the need to use gcbf to find the figure handle or findobj to
find the handle of and object by giving it the objects tag name.13
11.2.2 Callbacks
Every event can have a function associated with it. For example, if a user clicks on a
button, and that event has a function associated with it, Matlab will immediately call that
function. Such functions are known as callback functions, or simply callbacks. Well
learn below how to specify the particular callback function that is associated with a
particular event. As a programmer, one of your tasks is to write code in each callback
functions that performs the specific task that you wish to be associated with that each
specific event.
Thankfully, Matlab will actually automatically generate the code that provides the nuts
and bolts of your GUI (such as moving the mouse across the screen, displaying the proper
graphic for a button depression, etc.) Matlab will even generate the function calls and
basic function definitions for your callback functions! All you have to do is insert
additional the code inside the callback that does what you want it to do.
11.2.3 Working With Properties
Much of your work in writing callback functions will involve manipulating the properties
of the various objects within your GUI. Indeed, any changes to the appearance during the
running of your GUI is done by altering the properties of your objects. Reading input data
typed by the user is achieved by accessing property values as well. There are two primary
functions used to work with properties in Matlab GUIs.
The function get is used to read property values of objects. The basic syntax of the get
function is as follows:
get(handle, property)
Two input arguments are required: the handle of the object in question and the name of
the property you wish to access. Note that the name of the property is stored as a string
and therefore must be surrounded by single quotes.
13
The function findobj was used primarily to find the handle of any object other than
the active figure window or the object which initiated the event function call. For
example, if, when a user clicks a button, we wish for text to appear in a textbox as a
result, we could use findobj to find the handle of that textbox. The function searches
through all the objects in a given figure window and returns the handles of those objects
with property values that match the value passed to the function. We would use the Tag
property to give each object a unique tag and then use findobj to search for an object
with that specific tag name.
Chapter 11
202
The set() function is used to alter the property values of objects. The syntax of set is
as follows:
set(handle, property, value)
Three input arguments are required for the set function: the handle of the object you wish
to manipulate, the name of the property to be changed and the value you wish to set that
property to. Just as with the get function, the name of the property is stored as a string, so
it must be surrounded by single quotes. Note that many property values of objects in
Matlab are stored as strings. In those cases, the value you set should also be surrounded
by single quotes. In some cases, however, the values will be arrays or other numeric types
in which case quotes are not appropriate.
In the newest version of Matlab, this will launch the guide quick start window where you
will be given a number of choices.
Chapter 11
203
You may choose to create a new GUI from a number of pre-defined templates, or you
may open an existing GUI. For now, lets start with a clean slate and select the default, a
blank GUI. We do that by clicking OK.
After initializing, guide will present us with our workspace. (Displayed on the next page)
Guides initial figure window presents us with a grey grid workspace. This is the area
where we will design the layout of our GUI. Note that the grid will not actually show up
on the finished product. The grid lines are there simply for your benefit to assist with the
visual placement and alignment of your objects.
Along the left hand side of the window is the component pallet, which consists of a set
of buttons, all but one of which represents a type of object, which the Matlab help utility
terms a component, that can be added to a GUI. The button on the top left featuring the
cursor arrow does not represent a component. It is used to point at and click on
components already in the GUI. The remaining buttons make up the Component Pallet,
and are used to create objects.
Along the top are a series of menu items and tools to assist you in the creation of your
GUI. In addition to standard features like save, cut and paste, are tools such as the menu
editor, align-objects tool, the property inspector and a run button (green arrow) for testing
your GUI. These tools will be covered a little later in this section.
Chapter 11
204
Each of those buttons on the left has a name that tells you what object they will produce
in the GUI workspace. To see their names, you can click File at the top left, and then
Click Preferences, then click on the box that says Show names in component
palette. Then click OK. You will see a name added to each of those buttons. (We will
not include those in figures below to save space, but you will want to use them at first,
until you get used to the icons and no longer need the names.) The most important ones
are described in Table 19.
Chapter 11
Object Class
Pushbutton
Toggle Button
Radio Button
Checkbox
Slider
Frame
List Box
Popup Menu
205
Chapter 11
Axes
206
To illustrate the use of guide, well begin with a simple example. Suppose we want to
create a GUI that can change the background color of its window. We might have a series
of buttons that when clicked will change the figure window color appropriately.
Chapter 11
207
Having selected an appropriate size for our GUI, well place a series of pushbuttons on
the screen, one for each color we want to use. First click Layout and uncheck Snap to
Grid. Now click on the pushbutton icon at left. Then, while holding down the left mouse
button, drag your cursor across the workspace to create an outline of the button.
Then, release the mouse button to create the pushbutton on your workspace.
Chapter 11
208
By selecting the push button, you can click and drag it about the workspace to position it
where you want it. By moving your cursor over its corner markers, you can also click and
drag to resize the pushbutton.
Now, click right on the button and select Copy. Then click right on the background and
click Paste. (or use Cntl-C and Cntl-V). Do this until you have four identical buttons.
The buttons are all arranged haphazardly. Theres nothing inherently wrong with that, but
for a professional design, they should be aligned. The grid can help you move line then
up if you have a good eye. But the Align Objects tool makes this much easier.
Begin by highlighting two buttons that you wish to align. (Hold down the Ctrl key while
clicking on the top two buttons.) The little squares at their corners indicates highlighting.
Chapter 11
209
Then either click Tools/Align Objects, or find the little Align-Objects shortcut icon on
the row below Tools (two yellow rectangles with a vertical line through them. That will
bring up the toolbox.
The Align Objects toolbox allows you to
choose a horizontal or vertical alignment.
You can even set the spacing between
objects. In this example, we hope to align
the top two pushbuttons vertically. That
means we want either the tops of the
pushbuttons to align, their centers to align or
the bottoms to align. Lets try aligning them
along their tops.
The vertical alignment options are in the
first row. The first button is off, but the
second button allows us to align based on
the top of the pushbutton. Click that option
and then click OK.
Our top row of pushbuttons are now aligned. Note that theyre aligned based on the
button that had the maximum height. In other words, the button on the left came up to
match the button on the right.
We can repeat this process for the buttons in the second row, but to learn a new feature,
instead of using Cntl-left click to highlight two buttons, Just click in the background, hold
Chapter 11
210
the click and move the mouse to produce a rectangle surrounding the lower buttons. They
will be highlighted.
Align the lower pushbutton as you did the upper ones. Now horizontally align the two on
the left as follows: Select them, and open Align Objects. Next (and this is important)
click OFF in the Vertical section at the top. Then, select any of the Align buttons in the
Horizontal section at the right and click. OK With a similar process you can then
produce horizontal alignment for the two on the left right. After that you have four
aligned, identical buttons.
Chapter 11
211
Most objects will have a property to define their colors. In the case of a pushbutton, that
property is called BackgroundColor. Clicking on the little paint can to the right of this
word, will bring up a series of colors to choose from. You can even define custom colors
by setting the intensity of the red, green, and blue componentsthe so-called RGB
values. To see its current RGB values, click on the plus sign to the left of
BackgroundColor.
Chapter 11
212
Chapter 11
213
being characters. Other than characters, the most useful is probably normalized, whose
range is 0 to 1, and whose meaning is fraction of the width or height of the GUI
window. Its usefulness is that, if the user changes the size of the GUI window while it is
running, the position and size of the object will change proportionally.
The String property defines the text string that appears on the button. Lets suppose we
want this button to change the background color to red. To let the user know the purpose
of this button, lets replace the words Push Button with Red by clicking on the little
text icon to the right of String, and replace Push Button in the box that opens with
Red. Click OK and notice that the button changes immediately in the GUI. Then click
the paint can to the right of ForegroundColor and choose the color red. Now Red appears
in the GUI as the label for that button. Click the value (normal) for FontWeight and select
bold.
An extremely important
property that is common to
all objects is the Tag
property. The tag acts
more or less like the name of
the object. The tag will be
used as part of the name of
the callback function for the
object. (It can also be used
to find the handle of the
object using the findobj
function, but we will not
need to do that.) Matlab will
automatically
create
a
unique tag name for each
object in your GUI. You are free to change the tag name to whatever you wish, as long it
is a legal Matlab variable name, and you should make every tag name both meaningful to
anyone reading your program, as well as unique among the tags in your GUI. This tag
will not be seen or known by the users of this GUI, but a meaningful name makes your
code easier to understand. Lets choose Red_Button for this tag, since that will be
easy for us to remember while we are programming. Double-click the tag name, which is
to the right of the word Tag (it will be of the form pushbutton#, where # is some number,
in the case above it is pushbutton7), and type Red Button (no quotes required here).
Finally, the Visible property will make your object visible or invisible to the user. It has
two settings: on and off. Switching the visible property to off will cause the object to
disappear from the users screen. Switching this property to on will cause it to appear
again. Like the inactive state, invisibility is appropriate when the function of the object is
not needed until some event has taken place. For example a file-save button might be
kept hidden until a file name has been entered. Typically, however, objects will remain
visible, and will leave ours in that state. The property Inspector sets the initial states.
Chapter 11
214
By double clicking any of the other buttons on your GUI, you can make their properties
for appear in the property inspector.
Lets round out our buttons by creating one for green, one for blue and one for purple.
Then highlight them all and move them to be in the middle of the GUI by clicking left on
anyone of them and while holding the mouse down, moving the mouse.
In addition to the obvious objects having properties, the figure window itself is also an
object, and its properties can be viewed and changed in the property inspector as well.
Double click on the grid area itself to view the figure windows properties.
Once were satisfied with the initial layout and initial property settings of our GUI, its
time to save them. From the file menu, select Save As and give a name to your file.
Any legal Matlab variable name will do. Lets call this one MyVeryOwnGUI. Your GUI
will be saved as a .fig format file: MyVeryOwnGUI.fig. Matlab calls files in this
format figure files. They are used to store any figure, including the figure that holds a
GUI. The file includes all the layout information and all the properties of the objects in
the figure.You cannot inspect a figure file with an editor. You inspect it only indirectly
by opening the figure file in guide and looking at its properties with the Property
Inspector.
Chapter 11
215
As you save your figure file, you will notice something unusual happening. Matlab has
automatically created a new M-file as well, with the same name as the Fig-file that it just
created: MyVeryOwnGUI.m. This file is used in conjunction with the figure file to run
the GUI.
If we move our mouse over one of the buttons, it will be highlighted, as shown on the
right, but clicking inside it does nothing. The event of clicking the mouse is, as this point,
ignored by the GUI. Well make something happen below.
Chapter 11
216
Chapter 11
217
>> MyVeryOwnGUI
>> MyVeryOwnGUI
>> MyVeryOwnGUI
The result will appear at first to be only one GUI, but that is because they are all
generated in exactly the same place and are exactly the same size. By moving them with
the mouse, we can see all three of them, as shown here.
Chapter 11
218
% --- Outputs from this function are returned to the command line.
function varargout = MyVeryOwnGUI_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
You will sometimes find it necessary to make changes in the first subfunction, and,
rarely, in the second. However, you will always find it necessary to make changes to the
third and following subfunctions. These are the callback functions. As explained above,
these functions are called when events occurs in the GUI figure. When such an event
occurs, the primary function (n.b., not a callback function!) is called by Matlab. Unlike
the call that we give in the command window to activate an instance of the GUI,
however, the call that Matlab makes when an event takes place includes arguments. The
Chapter 11
219
first of these arguments is the name of the callback function associated with the object in
the figure in which the event took place. Matlab finds the name of that callback function
in the .fig file for the GUI. The name of the callback function is also shown in the
Property Inspector in the field called Callback. In fact, the call of the primary function is
given there ver batim complete with the arguments that Matlab is to use.
Callback functions are called by other functions when their names are passed through an
input argument into the calling functions during execution. When an event takes place in
the GUI (mouse click, mouse moves, mouse released, or keyboard activity), a callback
function is called by the function gui_mainfnc. That function is called by the primary
function, and when it does, it passes to gui_mainfnc the name of the subfunction that
is to be called. The full sequence is as follows:
1. The user causes an event with the mouse or keyboard.
2. Matlabs GUI system detects the event and calls the primary function, which is in
our current case MyVeryOwnGUI, passing as an argument the name of the
callback function
3. The primary function calls gui_mainfnc,
4. gui_mainfnc calls the callback function.
5. The callback function executes.
The name of a callback function is determined by the tag (some of which we changed by
using the Property Inspector) of the object with which it is associated. Here are the
callback functions in MyVeryOwnGUI.m:
% --- Executes on button press in Red_Button.
function Red_Button_Callback(hObject, eventdata, handles)
% hObject handle to Red_Button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Note that the name of each callback function incorporates the name of the tag of the
object that triggers it. It can be seen that we changed the tag of each of our four buttons to
Chapter 11
220
give them names that we can easily remember as associated with the color that they are
supposed to produce.
Its time to make the Red button do what we want it to do: change the background color
of the figure to red. To do that, we need to put a command inside the callback function
for that button, which is the function named Red_Button_Callback. The command
must change a property of the figure. The name of the property is probably Color, but
it might be BackgroundColor. By the way, unlike the situation with variable
names, function names, and file names, capitalization is of no consequence with property
names. Thus, color, COLOR, cOlOr, and Color are all treated equally. To determine
that name of the color property for the figure, we can consult Guides Property Inspector.
We double click anywhere in the background of the figure (the grid area). There is no
BackgroundColor, so we guess (correctly) that the property Color, is what we want. In
order for the callback function to change the color of the figure, it must first obtain the
handle for the figure. To write code that will do that, we need to know the Tag of the
figure. Looking further down the property list, near the end, we find Tag, and we see that
the name is figure1. We now have all the information we need to write code to change the
figures color. The command that will do it is
set(handles.figure1,'Color',[1 0 0]);
As mentioned above, handles is a struct whose field names are the tags of all the
objects in the figure, including the figure itself. A copy of that struct is passed as an
input argument to each callback function along with two other arguments, hObject,
which is the handle of the object that triggered the callback and eventdata, which is
an unused argument that Matlab has been reserving (for years) for possible future use.
The value of eventdata is always (up to this writing) the empty matrix. (We will
make no use of it in order to maximize the chance that our dandy GUI will work in
futures version of Matlab that use it).
The value that we are giving to the Color property is the vector [1 0 0], which means:
Give the red component full intensity and give the green and blue components zero
intensity. (The string 'Red' in place of [1 0 0] has the same effect.).
After we add this command, the callback for the red button looks like this:
function Red_Button_Callback(hObject, eventdata, handles)
% hObject handle to Red_Button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.figure1,'CoLoR','r');
Chapter 11
221
and similar commands for the other two buttons, changing the intensities to [0 0 1] for
blue and [.7 0 1] for purple. Now when we activate our GUI and click on the Red Button,
the result looks like this:
Pressing the other buttons changes the color as expected. We can press them in any order
as many times as we wish. The callbacks will be called, and the color will change.
Weve done it! MyVeryOwnGUI is working. ButThis color is pretty intense. It would
have been nice if we had included a capability to be able to dim it a bit. Fortunately, we
can now go back and add objects that we didnt think of when we started, and we can add
callbacks for them without losing the work that weve already done. We simply open the
GUI figure file in guide, add an object or objects, set their properties with the Property
Inspector, and save as before. The figure file and M-file will be modified, and we will
find a brand new callback function at the end of the M-file right after the
Purple_Button_Callback function. In the next section will look at the slider,
which is just what we need for this dimming task.
The Slider
The slider is an object that looks like a horizontal or vertical scroll bar. It allows the user
to adjust a number by moving a rectangular slider, which shifts from left to right within a
trough. Lets put a slider at the bottom of our GUI. To do that, we click on the Slider
button in the component pallet at left and drag out a rectangular shape, as we did for the
Chapter 11
222
buttons. The result looks like this (weve turned on the Show-names-in-componentpalette again so that you can easily identify the Slider button):
There are three ways to move a slider: The first is to click on the slider and move it
before releasing. The second is to click somewhere in the trough, and the third is to click
on either of the darkened squares with little arrows on them at the left or right end. In
second or third case, the slider will jump a set distance toward the clicked point.
Of course, we do not have a working slider yet. We have laid it out, but we need to set its
properties and then work on its callback function. First, well set the properties. If we
double click the slider that we have created, we will see its property list in the Property
Inspector. As in most cases, we first change the tag to something appropriate for the task
that the object is to perform. In this case we will chose intensity_slider. The only other
properties that we need to work on are Max, Min, SliderStep, and Value. The value
property is the key to the operation of the slider. When the user moves the slider, only
one thing happens, its Value property changes. It will increase or decrease, but it will
remain within the range Max-to-Min. We are going to use the Value as a multiplier to
reduce the color intensity from its full value to lower values all the way down to zero. So
we want the range to be 0 to 1. These are the most common values, and so they are
already set for us by Matlab. So, no need to change Min and Max. The slider step is easy
too. Its value is a two-element vector, and the initial value is [0.01 0.1]. The first number
is the percent change of the value when we click on one of the arrows at either end; the
second number is the percent change when we click in the trough. These values are fine,
so no need to change SliderStep. We want our initial value to be 1, so we have to change
the value of Value from Matlabs default of 0. To do that we click on the icon to the left
of the [0.0]. That icon represents a vector because we can in fact specify that the slider
simultaneously changes every element in a vector by the same factor. When we click on
it we see this window
Chapter 11
223
We want to save changes (virtually always), so we click Yes (or hit Enter) and the GUI
pops up.
When the GUI pops up the slider is now sitting at the right, because we gave an initial
value of 1 and that is the maximum of the range (which runs from left to right). We can
click on the slider and move it, but nothing happens because we have not changed the
callback. If we open the MyVeryOwnGUI.m in our editor, we find this new code at the
end:
% --- Executes on slider movement.
function intensity_slider_Callback(hObject, eventdata, handles)
% hObject handle to intensity_slider (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
%
get(hObject,'Min') and get(hObject,'Max') to determine range of slider
Chapter 11
224
This time there are two new functions, the callback, as expected, and a second function,
intensity_slider_CreatFcn. This second function is called only once, when the
slider is created upon GUI activation.
Now we work on the sliders callback. Matlab has included a helpful comment (Hints:
...) that tells us how to read the value of slider and its maximum and minimum values.
All we need is the value, so we add the command,
intensity_factor = get(hObject,'Value');
Now we want to multiply intensity_factor times the most recent color that was
selected by the buttons. Each time the slider is adjusted, this callback will be called to do
that. Lets imagine that we have clicked the red button to produce the bright red
background that we saw above. Now we move the slider two times. Suppose the
intensity_factor changes from one, down to, say, 0.5, and then from 0.5 back up
to 0.75. We want to see the color go from bright red to half-red and back to red. In
order to do that, we need to multiply the red color vector, which is [1 0 0] first by 0.5 and
then by 0.75. That must be accomplished by commands in this callback. Consider the
following code, which seems, at first glance, to do what we want:
current_color = get(handles.figure1,'color');
new_color = intensity_factor*current_color;
set(handles.figure1,'color',new_color);
Consider the first time the slider is moved after the red button is clicked. The sliders
Value property is set to 0.5 and the callback is called. The first command reads the
current color[1 0 0]. The second one calculates the new color0.5*[1 0 0], which
equals [0.5 0 0], and the third one writes the new color into the color property of the
figure. As soon as the new color is written into the color property of the figure, the
background will change on the screen. All seems well. Unfortunately, however, if we
move the slider again, the results will not be what we want.
Suppose that the second motion of the slider results in a slider value of 0.75, as we
imagined above. The sliders callback will be called again, and these three commands
will be executed again. The first one will read the current color, which is still [0.5 0 0].
The second will set the new color to 0.75*[0.5 0 0], which equals [0.375 0 0]. What we
wanted instead was to multiply 0.75 times [1 0 0], which would give [0.75 0 0]. The
problem is that we have not stored the original color that was set when the color button
was clicked. We need to do that in the callback of each of the four buttons, and we need
to be able to read that value from within the sliders callback.
Sharing values among callbacks
We are presented with a problem. We need to set a value in one callback, for example
Red_Button_Callback, and read that value later in another callbacknamely
intensity_slider_Callback. As we have learned in our study of functions, each
Chapter 11
225
functions variables have only local scope, so the value we set in one function cannot be
accessed by a second function unless the value is returned by the first function to the
second. Since these functions are not calling each other that method is impossible.
Furthermore, the definitions of the functions are beyond our control. These callback
functions do not return anything! We learned a method for sharing values by means of
the global attribute, but that option is a bad one because it means that, if the user happens
also to declare a variable with the same name to be global in, say, the Command
Window, commands there would interfere with the behavior of the GUI. Thus, we have a
difficult problem.
Fortunately, Matlab has anticipated both the need for sharing values among callbacks and
the danger of using the global attribute. It has provided a safe and relatively easy
alternative. Since the call of each callback function includes the argument handles, we
can store the values that we want to share inside it. To see how this scheme works, we
will show a modification of the Red_Button_Callback and the
intensity_slider_Callback that implements sharing through handles (we have
omitted the comments to save space):
function Red_Button_Callback(hObject, eventdata, handles)
set(handles.figure1,'Color',[1 0 0]);
(1) handles.current_color = [1 0 0];
(2) guidata(hObject, handles);
function intensity_slider_Callback(hObject, eventdata, handles)
intensity_factor = get(hObject,'Value');
(3) new_color = intensity_factor*handles.current_color;
set(handles.figure1,'color',new_color);
The numbers indicate the new commands. (1) stores the red value in a new field of
handles, called current_color. As we have seen in Chapter 8, if this field is
already there, it will be used; if not, it will be added to the existing fields of handles.
(2) is the command that makes the value accessible to other callback functions. It is a call
to a function, guidata, which stores the value of its second argument in the figure file.
The data that it saves in that file is simply a struct. The struct must have one field
for each object in the figure, but it can have additional fields as well. Once we have
added this new field and stored a value in it, each callback will receive it as an argument
when it is called.
To understand fully the need for the call to guidata, we must remember that the
variable handles, like any input argument of any function in Matlab, is a local variable.
When the function is called, a value is copied into handles, but when the function
exits, nothing is copied back (a few languages do support this behavior via so-called inout arguments, but not Matlab). Thus, adding a field and/or changing the value of a field
in the local variable handles will have no effect on any variable or value outside the
function. That is why the call to guidata is required.
Chapter 11
226
Continuing with our analysis of the code above, we come to (3), which retrieves the color
that was most recently set by one of the buttons (in the case we are analyzing that would
be the red button). It gets it from the current_color field of handles, which is a
local variable (i.e., not the same variable as that in a buttons callback function), but
which received its value when it was called by gui_mainfcn.
If we run our GUI now it works as expectedalmost! A new problem has shown up.
When we click a button and then move the slider to, say the middle, which produces a
50% intensity, all works properly. However, when we click a button after we have moved
the slider, we discover a problem. The button click produces a color at 100% intensity,
but the slider is showing 50%. If we move the slider the intensity is adjusted properly, but
until we do, the GUI is in a confusing state. To solve that problem we could do one of
two things: (1) Move the slider all the way to its maximum position when we click a
button, or (2) Use the current intensity factor when we click a button. We will choose the
former, only because it shows how to change the state of one object from within the
callback of an other object. Here is the modified callback function for the red button:
function Red_Button_Callback(hObject, eventdata, handles)
set(handles.figure1,'Color',[1 0 0]);
handles.current_color = [1 0 0];
guidata(hObject, handles);
set(handles.intensity_slider,'Value',1);
The only new command is the last one. We simply set the Value to 1 for the slider. When
that is done, the slider moves immediately to the right on the screen. We could have
placed this command anywhere within this function. We put it last to show that it does
not have to come before the call to guidata. It is not necessary to employ guidata for
this change because it is not handles that we are changing, but the property of an object
whose handle is stored in handles.intensity_slider.
Our GUI now works properly.
The Static Text Box
But were not done yet! The GUI works properly, but we need to add something: a label
to inform the user of the purpose of that slider. Our buttons suggest that they will produce
a color, but the slider will seem mysterious. We will add the label, Intensity
Adjustment. We can add a label anywhere in the figure by means of a Static Text Box.
To do that, we first click on the bottom right of the background and stretch it down a bit
to provide more room, and then we click on the button in the component pallet that says
Static Text and drag a rectangle on the workspace just below the slider. When we release
the mouse button, we see this,
Chapter 11
227
We double click our new static text box to bring up the Property Inspector. Unlike the
other property lists that we have seen, a static text box is not automatically given a
callback, because, as the name implies, it is not meant to be active. It is used simply to
provide static information. Its visibility can be changed, its position can be changed, its
message can be changed, and other things can be changed, all by changing its properties,
but typically, as in our case, all we need to do is specify that its string be Intensity
Adjustment, and choose the right size and weight for the font. We choose a FontSize of
12.0, and for FontWeight we choose bold. With this increased font size it is necessary to
widen the box and re-center it.
After we make these simple changes and save our GUI, we are done (really!). The image
below shows it in action after the red button has been clicked and the intensity has been
reduced. We could do much more by adding other objects and other callbacks, but the
basic ideas are the same: Drag a component from the component pallet, modify the
Chapter 11
228
properties, save the figure file and the M-file, and modify the callbacks. As we have seen
above, this process tends to be iterative. Surprises always arise. When they do, we will
typically find it necessary to alter one or more callbacks. Occasionally, we will find that
we need to add a component or change a property, but most of the time is spent with
programming.
There is a wealth of information among these three topics. To get descriptions of the all
the components in the component pallet, expand Creating GUIs with GUIDE, then
expand Laying Out a GUIDE GUI, then expand Adding Components to the GUI, and
click on Available Components.
Chapter 11
229
Chapter 11 Appendix
Handy Commands for GUIs
Here are some functions that will often come in handy when writing GUIs
axes
AXES(H) makes the axis with handle H current.
It is helpful when plotting is to be done in a GUI (but see subplot below!). When the
GUI was set up, an Axes component would have been selected from the component pallet
and placed somewhere in the GUI. While the GUI is running, plotting can be directed to
that component by means of the axes command. For example, suppose the plot is to
appear in an axes object whose tag is foo. Then the following commands would do it:
axes(handles.foo);
plot(x,y);
close
CLOSE closes the current figure window
It is the command that will stop the GUI and close its window (i.e., its figure). This is the
command that you should put in the callback function of the GUIs Quit button.
num2str
T = NUM2STR(X) converts the matrix X into a string representation T
with about 4 digits and an exponent if required.
It is helpful when a number is to be displayed in a textbox. For example if a textbox
whose tag is foo must display the value in the variable v. Then the following commands
would do it:
text = num2str(v);
set(handles.foo,'string',text)
str2double
X = STR2DOUBLE(S) converts the string S, which should be an
ASCII character representation of a real or complex scalar value,
to MATLAB's double representation. The string may contain digits,
a comma (thousands separator), a decimal point, a leading + or - sign,
an 'e' preceding a power of 10 scale factor, and an 'i' for
a complex unit.
It is helpful when a number in a textbox needs to be read and converted to a number for
use in some function. For example, if a textbox whose tag is foo, contains the string 4,
and we need to assign that number to a variable v. Then the following commands would
do it:
text = get(handles.foo,'string')
v = str2double(text);
Chapter 11
230
would cause a line to be plotted, as shown below, in a rectangular area whose lower left
corner is 0.3 of the width of the figure from the left of the figure, 0.2 of the height of the
figure from the bottom of the figure, with a width equal to 0.4 of the figure width, and a
height equal to 0.6 of the figure height.
If you wish to place, say, three plots on the right side of the GUI, you might, for example,
use these commands
subplot('position',[0.5, 0.1, 0.4, 0.25])
plot([0:10],[0:10],'r')
subplot('position',[0.5, 0.4, 0.4, 0.25])
plot([0:10],sin([0:10]),'g')
subplot('position',[0.5, 0.7, 0.4, 0.25])
Chapter 11
231
plot([0:10],cos([0:10]))
uiputfile
UIPUTFILE Standard save file dialog box.
[FILENAME, PATHNAME, FILTERINDEX] = UIPUTFILE(FILTERSPEC, TITLE)
displays a dialog box for the user to fill in and returns the
filename and path strings and the index of the selected filter.
It is useful when it is time to save information into a file. This command brings up a
standard dialog box provided by the operating system, and allows the user to choose any
directory on the file system into which to save the file. For example, if the following
command is given:
[filename,pathname] = uiputfile('*.*','Save file as')
Then a dialog box will open up that looks something like this (under Windows XP):
Chapter 11
232
If the user types the name Popcorn.wav in the File name box and clicks Save, then the
function will return two values:
filename = Popcorn.wav
pathname = C:\Documents and Settings \My Documents\MATLAB\
These two values can then be used to write values into a file. For example, the GUI might
use the Matlab-provided function wavewrite, to save audio information in a file:
wavwrite(audio_array, sampling_rate_p,16,filename).
This is the typical use of uiputfile : Despite the fact that the user clicked Save during
the call to uiputfile, nothing is saved while this function is running! The call to
uiputfile does nothing but return a file name and pathname chosen by the user by
means of the dialog box. It does not create a file or save anything into it! The file creation
and the writing into the file, or the writing into a pre-existing file, is done by some other
function.
Chapter 11
233
Computer Science:
o object-oriented programming
objects
property
property value
o graphical user interface (GUI)
event-driven programming
handle
callback
Matlab:
o graphical user interface
o handle
o properties
get and set
o guide
GUI workspace
component pallet
Property Inspector
o standard objects:
Pushbutton
Slider
Static Text Box
Access Matlabs help facility on:
Toggle Button, Radio Button, and Checkbox
Edit Text Box, Static Text Box, List Box
Popup Menu
Axes
o handy commands for use with GUIs
axes, close, num2str, str2double, subplot (new use),
uiputfile
Chapter 12
Symbolic Mathematics
When mathematicians work, they use symbols, such as x and y, to represent numbers
and the functional notation f(x) to represent a function of x. We have used the same
symbols in Matlab, and yet the meanings are subtly different. The Matlab symbols x and
y refer to floating point numbers or integers of the types we considered in Chapter 8,
whose ranges and accuracies are limited, and f(x), sqrt(x), etc. refer to functions that
operate on these numbers. A common feature of all the numbers that can be represented
as floating point numbers or integers is that they are rational numbers, i.e., numbers that
are equal to ratios of integers.
The x and y of mathematics, on the other hand, refer to real (or complex) numbers whose
values are often defined only by being solutions to equations. These solutions are
sometimes not rational, as for example the solution to the equation, x 2 2 , which we can
represent by x 2 or x 21 2 . In Matlab we can easily set x = 2^(1/2)or x =
-2^(1/2), but the meaning is not the same. The result of Matlabs calculation of
2^(1/2)is approximately equal to 21 2 , but it is certainly not exact because 2 is an
irrational number and cannot be represented to perfect accuracy with any floating point
number. The statement x 21 2 , on the other hand, means x is equal to the number that
solves the equation, x 2 2 . The equation is the central feature here, not the number.
We learn from calculus that the derivative is another function, in this case,
df x
2x .
dx
In this case there is no number involved at all. We have, by taking a derivative,
manipulated one function to produce another function. There are many such relationships
between functions of importance in mathematics. For example, if we treat 2x as a
function of x, then its integral gives a family of functions:
2xdx x
c,
Chapter 12
Symbolic Mathematics
235
each with a different value for c. As another example of the manipulation of functions, if
g x x 2 2 x 2 , then it can be shown that g x p x q x , where p x x 1
and q x x 2 . Here we have factored a function, or expression, into two
functions, or terms, whose product is equal to the original function.
In each of each of these cases, manipulations of equations and functions are the central
problems; specific numbers play only a supporting role.
Such manipulations cannot be done by the Matlab with which we have become familiar
in the previous chapters. That Matlab deals with rational numbers and with functions and
programs that manipulate rational numbers to produce other rational numbers. What we
have seen is the numerical side of Matlab. Numerical mathematics is the greatest strength
of Matlab, and it is the most well known part of Matlab. Indeed it is the only side of
Matlab that most people know. However, Matlab has another sidesymbolic
mathematics. Symbolic mathematics is the manipulation of symbols according to
mathematical rules. It is the sort of thing that we learn first in algebra and then in
calculus. We learned in algebra, for example, how to factor a polynomial, such as g x
above, and we learned how to differentiate and integrate functions in calculus.
In this chapter we will open Matlabs symbolic capabilities by giving the command
syms, and once we are there, we will use those capabilities to manipulate equations and
functions. We will also learn how, after we have got the function we want, to plug in
values for variables to calculate numerical answers to numerical problems. The symbolic
approach is quite different and will take the reader a while to assimilate. The best way to
do that is to repeat the examples shown in the chapter.
(Note: The examples in this chapter should be carried out in order during the same
command session because some of them depend on the fact that previous ones have been
done. If you have to start in the middle, note that in some cases a syms statement is
needed and also, possibly, an assignment statement or two. You can look back to the
earlier examples to find the missing statements.)
You should use Matlabs help command on the functions discussed below as a further
means for understanding them. However, you should know that when you ask Matlab for
help, you will, in some cases get help on the wrong function! That happens when Matlab
has two functions with the same name, one of which is called when non-symbolic
arguments are given to it and the other of which is called when symbolic arguments are
given to it. Matlab uses the computer-science term overloaded method to describe a
function that has both a numerical and a symbolic definition. The word method here
means simply function. The use of the word method to mean function is common in
object-oriented programming languages, such as C++ and Java. Matlab, however, while it
does support some object-oriented functionality, particularly in its GUI development (See
Chapter 11) is not an object-oriented language.
Chapter 12
Symbolic Mathematics
236
To get help for the symbolic version, type help sym/factor (the .m is optional).
This technique: help sym/function_name, works for any symbolic function.
In versions of Matlab previous to Matlab 7.7.0 (R2008b), symbolic mathematics and
variable-precision arithmetic (see next section) were handled by an engine, which is a
program running in the background. This engine is called Maple, and it is available as a
separate stand-alone product from Waterloo Maple, Inc. (www.maplesoft.com).
Beginning with version 7.7.0 (R2008b), these functions are handled by a different engine,
called muPAD. MuPAD is not available as a separate product, but it is also runs in the
background of other mathematical products.14 The MathWorks, Inc.,
(www.mathworks.com), which is the company that makes and sells Matlab, paid
Waterloo Maple, Inc. for the rights to incorporate Maple into Matlab, but in 2008 it
purchased the company that formerly distributed muPAD. The basic functionality has not
changed significantly (after all, the derivative of x 2 is still 2x ), but with the previous
versions, purchase of Matlab did not include symbolic mathematics or variable-precision
arithmetic. The user had to pay separately for a symbolic toolbox. Beginning with Matlab
7.7.0 (R2008b), they are included with all Matlab installations.
In addition to Mathworks and Waterloo Maple, another company that provides symbolic
mathematics capabilities is Wolfram Research, Inc. (www.wolfram.com), which makes
and sells Mathematica. If symbolic mathematics is the major thrust of your work, then
you might want to look into these other programs.
Chapter 12
Symbolic Mathematics
237
computer on which Matlab runs has special hardware for calculating that works with this
representation. If you wish to carry out calculations with greater accuracy, also known as
greater precision, you can use Matlabs facility for variable precision arithmetic. It is
provided through the function vpa.
Here are some examples that show how it works. The function vpa takes two
arguments. The first argument is a string containing the expression that is to be
evaluated15, and the second argument is the number of digits of accuracy requested:
>> vpa('pi',50)
ans =
3.1415926535897932384626433832795028841971693993751
>> vpa('exp(1.2) ',50)
ans =
3.3201169227365472380597566370852291584014892578125
Chapter 12
238
Symbolic Mathematics
1.69314718055994530941723212145818
which gives an answer correct to 32 digits. If we omit the quotes, the log function
operates without high precision returning different number, which is then printed by vpa
to 32 digits, the last 17 of which (underlined below) are different from the high-precision
version:
>> vpa(log(2) + 1)
ans =
1.69314718055994528622676398299518
We will see another way to persuade vpa to evaluate an expression at high precision in
Section 12.3.
The syms statement turns all the variables listed with it into symbolic variables and
gives each of the variables a value that is equal to its own name! Thus, the value of a is
a, the value of b is b, etc. The variable E is now symbolic because it was assigned to be
equal to an expression that contained one or more symbolic variables. Its value is a*x^2
+ b*x + 5.
Typing whos will show which variables are symbolic:
zebra = 10;
whos
16
Name
Size
E
a
b
c
1x1
1x1
1x1
1x1
Bytes
142
126
126
8
Class
sym object
sym object
sym object
double array
Necessary, that is, for doing it in the command window or an M-file. However, there is an alternate
approach which provides beautifully type-set mathematics, which can be accessed by typing mupad in the
command window. To learn it, click its Help button and then select Getting Started.
Chapter 12
239
Symbolic Mathematics
x
y
zebra
1x1
1x1
1x1
126
126
8
sym object
sym object
double array
If we give the same assignment again for E, after c has been made symbolic, its value
will now be affected,
>> E = a*x^2 + b*x + c
E =
a*x^2+b*x+c
Chapter 12
Symbolic Mathematics
240
Here we see that the numeric side of Matlab found an approximate floating point number
for the sine of one-third pi, whereas the symbolic side of Matlab found a simpler
expression for it, namely 3 2 .
If we want a numerical version of the symbolic answer we can get it by means of the
conversion function double (See Chapter 8),
>> double(ans)
ans =
0.86603
The astute reader may have noticed that we evaluated the expression sin(pi/3)at high
precision without putting it in the quotes that were stipulated earlier. High precision was
gotten in this case without the quotes because we had declared pi to be a symbolic
constant. When the function sin is given a symbolic constant or a symbolic variable, it
performs a symbolic calculation and returns a symbolic result. That symbolic result is
evaluated by vpa to the requested precision. No quotes are needed. The ability of sin to
vary according to the type of its actual parameter is another example of polymorphism.
Sometimes there is no simpler form:
>> sin(pi/7)
ans =
sin(1/7*pi)
In fact, when dealing with polynomials, we need to tell Matlab what we want. For
example, if we wish to expand a product of polynomials into the standard polynomial
form with the highest degree term first followed by terms of lower degree, we use the
function expand:
>> expand((x+1)*(x+2))
Chapter 12
Symbolic Mathematics
241
ans =
x^2+3*x+2
The function expand is more versatile than direct polynomial expansion. It can expand
trigonometric functions whose arguments are polynomials as well:
>> expand(sin(x+y))
ans =
sin(x)*cos(y)+cos(x)*sin(y)
>> expand(tan(x+y)^2)
ans =
(tan(x)+tan(y))^2/(1-tan(x)*tan(y))^2
The function simple will look for a simple version of an expression, where the
definition of simple is roughly few characters required for the representation. It prints
out every version that if finds that requires fewer characters and returns one that has the
fewest. It typically agrees with human intuition about what is simple. In the following
example, we show only part of the output,
>> simple( (sin(x))^2 + (cos(x))^2 )
simplify:
1
radsimp:
ans =
1
Simple tries many methods for simplification. To suppress the printing of all the
methods tried, use it in the form f=simple(e), where e is the symbolic expression that
Chapter 12
Symbolic Mathematics
242
The last example uses the complex equivalence, cos a i sin a eia .
The command solve(E) assumes that you wish to solve the equation E = 0. If E
contains the variable x, then it solves for x . In this case, there are two solutions. It gives
the two solutions as two elements to a single symbolic vector. The assumption that x is
the unknown is always made when there is an x in the equation, unless you give as a
second argument the variable for which to solve:
>> solve(E,c)
ans =
-a*x^2-b*x
This time there is only one solution. If there is an exact numerical solution to the
equation, solve will give that instead of a symbolic expression. For example,
>> F = 14*x^2+50*x-24;
Chapter 12
Symbolic Mathematics
243
>> solve(F)
ans =
[ -4]
[ 3/7]
Here again, if we wish to get a floating point version of the answer, we can use double,
>> double(ans)
ans =
0.4286
-4.0000
If you have two or more equations in two or more unknowns, you simply give all the
equations to solve as arguments, followed by a list of the unknowns. For example:
>> [xval,yval] = solve(x+3*y-7, 2*x+y, x, y)
xval =
-7/5
yval =
14/5
If the list of unknowns is omitted, solve will try to guess them. It starts with x, y, and
z. Solve can also be given its equations in the form of strings. Use help to learn more
about solve.
We have learned previously how to solve simultaneous linear algebraic equations by
using matrix division. We can do the same thing symbolically. Here is an example:
>> b = [3; a+2];
>> A = [a*c, a; 3+c, a+c];
>> X = A\b
X =
[
-(a^2-a-3*c)/a/(-3-c+a*c+c^2)]
[ (a^2*c+2*a*c-9-3*c)/a/(-3-c+a*c+c^2)]
>> error = simple(A*X-b)
error =
[ 0]
[ 0]
The use of simple is important. Without it, the result is very complicated. It does not
appear to be equal to zero, but, upon simplification, everything cancels out. Matlab tends
(using Maple) not to simplify unless it is explicitly commanded to do so.
Chapter 12
Symbolic Mathematics
244
>> syms a b c
>> subs(a^3+b^2-c,{a,b,c},{3,4,5})
ans =
38
Note the braces {, and }, above. Both the list of symbols and the list of the values to be
substituted for them are cell arrays. This same function can be used to substitute symbolic
expressions for some (or all) of the symbolic variables. Thus, for example,
>> subs(a^3+b^2-c,{a,b,c},{3,4,a+b})
ans =
43-a-b
syms x
E = sin(x);
Estring = char(E);
fprintf(Here is the function: %s\n, Estring);
Chapter 12
Symbolic Mathematics
245
Chapter 12
Symbolic Mathematics
246
Its first argument is the expression to be expanded. Its second argument is the number of
terms to include. The result of the expression above is
x-1/6*x^3+1/120*x^5-1/5040*x^7+1/362880*x^9
which has all of the first eleven terms, six of which equal zero. Another way to say what
the 11 means here is that all the terms up to x^(11-1) are given.
The polynomial expansion of an expression is a good approximation to the expression
when the argument (x, in this case) is small. How small must x be? How good is the
approximation? To get an idea of the answer to each of these questions it helps to plot
both functions to compare one to the other.
>> ezplot(E)
>> hold on
>> ezplot(sin(x))
It can be seen that the approximation is good in the range from -3 to 3, but is bad if |x| is
greater than 4.
12. 9 Calculus
The two central operations in calculus are taking the derivative and integrating.
Chapter 12
247
Symbolic Mathematics
Derivatives
The Matlab function that performs differentiation is diff. These operations show how it
works:
>> diff(x^2)
ans =
2*x
>> diff(x^n)
ans =
x^n*n/x
>> diff(sin(x)^2)
ans =
2*sin(x)*cos(x)
Diff takes a second argument that is the name of the variable with respect to which the
derivative is to be taken (x is the default) or, if it is a number (i.e., not symbolic), then it
indicates the number of times the derivative is to be taken. For example,
>> diff(x^3,2)
ans =
6*x
Integrals
f ( x)dx
Chapter 12
248
Symbolic Mathematics
ans =
sin(x)-x*cos(x)
>> int(a^x,a)
ans =
a^(x+1)/(x+1)
When there are two arguments, as in the last example, the second argument is the
variable of integration. These are all indefinite integrals, meaning that there are no limits
of integration. Note that Matlab does not add the constant associated with an indefinite
integral. For example, the answer given by Matlab for int(x) is 1/2*x^2, not
1/2*x^2 + constant.
A definite integral can be taken by giving three arguments. The second and third
arguments in that case are the first and second limits of integration.
x b
int(f, a, b)
xa f ( x)dx
The last example has four arguments. In that case, the second argument is the variable of
integration, and the last two arguments are the limits of integration.
Sometimes Matlab will give back an answer that includes a function that you may not
recognize. The following command, for example, returns an expression involving the
function, erf().
>> int(exp(-x^2),0,1)
ans =
1/2*erf(1)*pi^(1/2)
Chapter 12
249
Symbolic Mathematics
The function erf() is the error function, which is well known to those who work in
statistics. If you dont recognize a function that Matlab gives you, use help, e.g., help
erf.
Differential Equations
Suppose a problem can be written as a differential equation. The most common form is
that in which the first derivative of a function of time, y (t ) , is related to the function
y (t ) itself and some given function of time. For example,
dy
2 y 12t 2
dt
Here the function of time is 12t 2 . Matlab can find the solution for you via the function
dsolve, as follows:
>> dsolve('Dy+2*y=12*t^2')
ans =
6*t^2-6*t+3+exp(-2*t)*C1
This function takes a string, as opposed to a symbolic expression, as its argument. The
letter D has a special meaning and cannot be used otherwise inside dsolve. It means
first derivative of. The C1 is a constant of integration
Higher derivatives can be handled as well. The letters D2 mean second derivative of,
etc. Heres an example a second-order equation:
>> dsolve('D2y=c^2*y')
ans =
C1*sinh(c*t)+C2*cosh(c*t)
This time there are two constants of integration, C1 and C2. The functions sinh and
cosh are the hyperbolic sine and cosine, respectively, and are defied as follows:
sinh( x)
1
2
e x and cosh( x)
1
2
e x .
Its easy to specify initial conditions with extra arguments (all strings):
>> dsolve('D2y=c^2*y', 'y(0)=1','Dy(0)=0')
ans =
cosh(c*t)
Chapter 12
250
Symbolic Mathematics
Here the initial value of y is 1 and the initial value of the derivative of y is 0. Matlab
cannot solve some differential equations. Such equations may require numerical
approximation methods. Courses in numerical mathematics treat such methods.
12.10 Summations
A summation of the form, E(1) + E(2) + + E(n) can be evaluated with Matlab by
using the function symsum. If E is a symbolic expression in k, then
b
symsum(E, a, b)
k a
k 1
Getting Started
Using the Symbolic math Toolbox
Function Reference
Much of the material in the first two items is covered in this chapter. Under Function
Reference, is a categorical list of all symbolic functions(Calculus, Simplification,
Variable Precision Arithmetic, etc.) plus a link to an alphabetical list.
Chapter 12
Symbolic Mathematics
251
Homework Problems
252
Homework Set 1
1. [Answer in English] Suppose you complete all the problems for this homework
except the last and are ready to turn them in. Then you realize that you cannot do the
last one!
a. Is it a violation of the Honor Code for you to get help at that time from another
student on that last problem?
b. If you do get help, then, according to our Honor-Code rules in this class, is it
required that, before you turn anything in, you throw away all your work on this
assignment, start over on it, and redo everything without looking at your previous
work?
2. [Answer in English] Consider the two languages C++ and Matlab. For each of the
following problems, which language would be preferable
a. Writing a new interactive spreadsheet to compete with Microsofts Excel.
b. Calculating the current in electrical circuits for which you are given the resistances
and the voltages.
c. Writing a new interactive tool to be used by people who are unfamiliar with any
programming language but want to calculate the current in electrical circuits when
given the resistances and voltages.
d. Designing a heart pump.
e. Calculating the specific heat of a transformer oil when given the changes in
temperature and masses involved.
f. Writing a database management system.
3. [Answer in English]
a. Suppose you write a new version of sqrt, which you put in the directory
C:\Documents and Settings. Suppose further that you want your new version to
be called automatically instead of Matlabs built-in version whenever you issue
the command sqrt in the Command Window. Should you put C:\Documents
and Settings at the beginning of the Matlab path or at the end?
b. What is a program?
c. Consider this sentence, Add one to all the positive integers. Is it an algorithm? If
not, why not?
d. When statements in a program are interpreted, are they always translated or always
executed or both?
e. When statements in a program are compiled, are they always translated or always
executed or both?
f. Which statements are more likely to be interpreted, the statements in source code
or the statements in executable code?
253
Homework Problems
4. [Answer in English] Each part below gives a sequence of characters that represents a
single potential variable or function name. Identify each one as being legal or illegal.
If it is illegal, say why it is illegal.
a.
b.
c.
d.
e.
f.
g.
h.
i.
j.
Not_a_valid_Matlab_name
LoW_MOnthly_mOrtg_age_RATeS
L7
7L
Fortran99
Guaranteed*Platinum
_xyz
Low.Rates
sqrt
$BASIC
5. [Answer in English]
a. Is the option of using commas to separate the columns in a matrix an illustration of
variation in Matlabs syntax or a variation in Matlabs semantics?
b. What is the difference in syntax between the two types of multiplication in
Matlab?
c. What is the difference in semantics between the two types of multiplication in
Matlab?
d. Is exponentiation a binary or unary operation?
6. [Answer in English] Problems on the legality of arithmetic operations:
a. If size(X) returns 2 5, which of the following operations is(are) legal:
X+X, X*X,
X.*X,
X+X', X*X',
X.*X',
X'*X,
X'.*X
Homework Problems
254
d. Using the subarray operation with the colon operator, give a command that sets
Lower_Right to be a matrix that holds the subarray that makes up the lower right
quadrant of X.
8. [Answer in Matlab] Problems on the colon operator:
a. Assign X to be a 5x2 (5 rows and 2 columns) matrix such that row m consists of
the numbers from m-2 to m-1. Do it by using the colon operator once for each of
the 5 rows. Your answer will look something like this:
X = [-1:0; 0:1; ]
b. Assign X to be the same matrix as in the previous part, but this time use the colon
operator once for each of only 2 rows to produce the 2x5 transpose of X and use
the transpose operator to change it into the same 5x2 matrix that you produced for
part a. (This problem is meant to show you that sometimes it is easier in Matlab to
produce the transpose of a matrix, then to produce the matrix itself.) Your answer
will look something like this:
X = []
c. Using the subarray operation with the colon operator, give a command that sets Y
to be the matrix that holds the odd rows of X (i.e., rows 1, 3, and 5).
d. Using the subarray operation with the colon operator and the transposition
operator, give a command that sets Z to be a row vector that contains the elements
of the second column of X.
9. [Answer in Matlab]
a. Create a 6x3 matrix (6 rows and 3 columns) named x such that row m consists of
the numbers from m to m+2. Do this for each row by using the colon operator to
incrementally assign the values.
b. Create a matrix, w, whose value is equal to the transpose of x. Again, do this for
each row by using the colon operator to incrementally assign the values.
c. Using the subarray operation with the colon operator, give a command that sets y
to be the matrix that holds the odd columns of x. (i.e. columns 1 and 3)
10. [Answer in Matlab in the order stated] Exercise with arithmetic operators:
Homework Problems
255
256
Homework Problems
2*series2(m,1).
257
Homework Problems
1
10
13
16
19
258
Homework Problems
Homework Set 2
23. [Answer in Matlab] In these two problems you may use the operators +, -, *, /, and
^, but you may not use parentheses:
a. Using only the numbers 1, 2, 3, and 4 once each, give an expression that has the
smallest absolute value possible.
b. Using only the numbers 1, 2, 3, and 4 once each, give an expression that has the
largest value possible.
24. [Answer in Matlab] An important quality of a random number generator is that there
is minimal correlation between one random number and the next one. In this problem
you will write code to test the correlation of the numbers produced by randn. The
n on the end of this word stands for normal distribution, and one quality of the
normal distribution is that numbers are equally likely to be positive or negative.
a. Give one command to generate 100,000 random numbers using randn and store
them in a vector r (suppress printing).
b. Give a second command that computes the sum,
N 1
c. Give a third command that computes the absolute value of the sum,
rr
i i 1
d. Give a fourth command that calculates the ratio of the second sum divided by the
first. This ratio should be small, if there is a small correlation between the signs of
successive numbers.
25. [Answer in English] Consider the statement, fave = input('Please ), given at
the beginning of Section 3.5 of Ch. 3. Describe what happens in each of the following
situations. Give any error messages that Matlab produces in each situation ver batim
(by cutting and pasting from the command window) and tell the value of given to
fave.
a. The user types in a 2x2 matrix instead of a vector.
b. The user types in hello.
c. The user types in the name of a variable that already has been assigned the value
[5 25 45].
d. The user types in the name of a variable that does not currently have an assigned
value.
e. The user types in a string (i.e., anything inside single quotes).
26. [Answer in English] Consider this command:
fprintf('No.: %g, price= %5.2f.\nTotal is %7.3f\n', 80, 3.1, 4*3.1);
Homework Problems
259
b. While it is rarely used, fprintf does return a value (i.e., in addition to printing
something into the command window). The value is the number of characters
printed to the screen. Repeat the first fprintf command above in your command
window but this time capture the value that is returned as follows:
x = fprintf('No.: %g, price= %5.2f.\nTotal is %7.3f\n', 80, 3.1, 4*3.1);
Write a sequence of commands to accept the initial and final velocities (both integers)
and the time of acceleration (in minutes) from the user, and calculate acceleration in
miles per hour2. (Your answer will probably be a floating point value). Print out your
answer using fprintf in the following format (numbers should appear where there
are blanks below) with two digits to the right of the decimal place for each:
The object has an initial velocity of ______ mph, and undergoes an
acceleration of _____ mph2 for _______ minutes, to achieve a final
velocity of ___ mph.
28. [Answer in Matlab] A course involves 7 graded assignments. The grades in these
assignments contribute the following respective percentages of the course grade:
20%, 10%, 30%, 5%, 5%, 15%, and 15%. There are 10 students in the course.
a. Give one command that sets up a column vector containing these percentages (use
0.20 for 20%, etc.)
b. Give a second command that sets up a matrix containing (fictitious) grades for
each student for each assignment, letting each grade fall within the range from
zero to 100.
c. Give a third command that calculates the weighted average for each student and
puts them in a column vector.
29. [Answer in English] Add parentheses to the following expressions to show the order
in which the operations are carried out. (Dont be fooled by the spacing!) The first
one is answered for you to show how to answer the rest of them.
Homework Problems
260
a. 1+2 ^ 3*4
ANSWER: 1 + ( (2^3) * 4)
b. 1+2-3/4*5
c. 2^3 ^ 3*5
d. 1 - 2-3 + 3-2
e. [1 2;3 4]*[1 2; 3 4]^2
f. 1+2/3/4*5
g. 1/2^5+6^2+3
h. 2^4/3*5
i. 1-4+5-2+3
j. [1 2;3 4]*[1;2].^3
k. 1*2-3/4*5
l. 2*3 ^ 3*5
m. 1 2^3 + 3-2
n. [1 2;3 4]*[1 2; 3 4]^2*[1 2; 3 4]
30. [Answer in Matlab.] Let p = the precedence vector arithmetic operators, where p(1),
p(2), p(3), and p(4) give the precedences of parentheses, exponentiation,
multiplication and division, and addition and subtraction, respectively. Give the
Matlab command that sets p equal to the appropriate row vector for each of the
following, but in each case leave the precedence for parentheses the same as the
standard Matlab value:
a. The standard Matlab precedences.
b. A set of precedences that would cause the expression 27*80-6*10 to be equal
to 19980.
c. A set of precedences that would cause the expression 10^2+3*2-4 to be equal
to 1e-10.
d. A set of precedences that would cause the expression 2-4^3*2 to be equal to 4094.
31. [Answer in Matlab] Write code that produces the last plot (the fancy plot) of
Section 3.7 of Ch. 3. Hint 1: Plot five vectors y1, y2, y3, y4, y5 versus the vector x.
The vector x is a vector whose first element is zero, whose elements are spaced by
0.1, and whose largest value is 200. Hint 2: The following mathematical functions
will be useful:
cos(x)
exp(-(x-100)2/200)
-exp(-(x-100)2/200)
(1/2)exp(-(x-100)2/200)
-(1/2)exp(-(x-100)2/200)
Place the black circle at the center. Suppress all printing to the command window.
Don't forget to include the title of the plot and the labels for the x and y axes. NOTE:
You must not use any of Matlabs looping or selection facilities (e.g., for loop, if
statement).
Homework Problems
261
32. Suppress all printing. Give commands to produce a plot of the following two
functions over the range from 0 to 2 :
f x 2 sin x e x
g x 4 x3 10 x 5 20 x 4 30 x 3
a. [Answer in Matlab] Put x on the horizontal axis (as usual). Make the horizontal
distance between plotted points 0.001 or less. Plot the first function as a red line
and the second as a blue line. Add a grid. Include a title that says Plots of two
functions of x. Label the horizontal axis x (no label for the vertical axis). Give
a legend that identifies the two plots as f(x) and g(x), respectively (use help
legend). You do not need to worry about the tick marks or the numbers that
Matlab uses to label them. Just use what appears automatically.
b. [Answer in English] Using the plot that you have just produced, determine to
within two decimal positions to the right of the decimal point the smallest value of
x within the range 0 to 2 for which f x g x .
33. [Answer in English] Find the largest value of x within the same range for which
f x g x .
Write Matlab code to do the following things. Use the colon operator to reduce the
size of your commands as much as possible:
a. Produce a column vector x that contains the numbers from -10 through 10,
increments of 0.01.
b. Suppose there is a circle whose center is at (0, 0) and whose radius r = 10. For
each index m, let the elements x(m) and yp(m) of vectors x and y be equal to the
x and y coordinates, respectively, of a point P(x, y) on the upper half of the circle,
which is the half on which y 0 . Let the elements x(m) and yn(m) of vectors x
and y be equal to the x and y coordinates of a point P(x, y) on the lower half of the
circle, for which y 0 . Use the equations, y (r 2 x 2 )1/ 2 and y (r 2 x 2 )1/ 2 ,
to produce yp(m) and yn(m).
c. Plot yp versus x and yn versus x in the same figure to produce a red circle. After
you have used plot, give the command axis equal to see a truly circular shape.
34. [Answer in Matlab] The following set of equations is given:
ax by cz f
dx by ez g
bx cy cz h
262
Homework Problems
0.5
E
0.5
W2
W3
0.3
H
K
0.7
At each of the junctions C, D, E, F, G and H, the pipes are split and water flows
according to the proportions indicated in the diagram. If water flows into A and B at
p and q gallons per minute respectively, determine the following:
a. Consider the junctions C, D, E and their associated water flows, W1, W2 and W3.
W 1
p
Assign a matrix X, such that W 2 X
q
W 3
W 1
I
263
Homework Problems
that a person living in the country moves to the city is 0.20 and moves to the suburbs
is 0.20. Suppose that currently 650,000 people live in the city, 335,000 people live in
the suburbs and 185,000 people live in the country.
a. How many people would you expect to be living in the city, suburbs and country
(respectively) after one year? (Hint: start by devising a system of linear equations
representing the new populations as a function of the current populations and their
likelihood of moving.)
b. How many people would you expect to be living in the city, suburbs and country
(respectively) after two years?
c. How many people would have been living in the city, suburbs and country
(respectively) one year ago?
37. [Answer in English] A paper distribution company is putting together shipments
containing various types of computer printer paper. On hand, they have 14 gross of
high brightness inkjet paper, 25 gross of medium brightness inkjet paper and 15 gross
of all-purpose paper. The company ships three types of pallets containing different
quantities of paper according to the table below:
Pallet Type 1
4 gross
6 gross
5 gross
Pallet Type 2
1 gross
4 gross
1 gross
Pallet Type 3
3 gross
2 gross
2 gross
Determine the number of each type of pallet the company can assemble and ship.
38. [Answer in Matlab] Money flows into a certain medical foundation from two sources:
donations and interest earned on endowment. These funds are then used as follows:
Donations: Thirty percent goes into fundraising and the rest goes into research
and clinics.
Interest: Ten percent goes into fundraising and the rest goes into research and
clinics.
All money that flows into research and clinics is divided this way: Forty percent goes
into research and the rest goes into clinics. Finally, the money that goes into
fundraising, research, and clinics flow into material costs and personnel costs
according to the table below:
Material Costs
Personnel Costs
Research
80%
20%
Clinics
50%
50%
Fundraising
70%
30%
a. Let s (for source) be a column vector such that s(1) equals the money from
donations and s(2) equals the money from interest. Let g (for goals) be a
264
Homework Problems
column vector such that g(1) equals the money spent on research, g(2) equals the
money spent on clinics, and g(3) equals the money spent on fundraising. Give the
proper values to the elements of a matrix A such that A*s = g.
b. Let c (for costs) be a column vector such that c(1) equals material costs and c(2)
equals personnel costs. Give the proper values to the elements of a matrix B such
that B*g = c.
c. Give an expression in terms of A and B for a matrix C such that C*s = c.
d. Suppose the foundation has an annual budget calling for $2.5 million to be spent
on research, $4 million to be spend on clinics, and $2 million to be spent on
fundraising. Using one of the matrices, A, B, or C, calculate the vector s that
gives the required amounts of donations and interest.
e. Using the same budget, as that given in the previous part, calculate the vector that
gives the resulting material costs and personnel costs.
39. [Answer in Matlab] Use the same values for a through e that were given in the
previous problem, but this time treat x, y, and z as unknowns, and give the following
values to f, g, and h: 14, 15, and 16.
a. Give a command that sets up the appropriate matrix.
b. Give a second command that sets up the appropriate vector.
c. Give a third command that calculates the unknowns.
R3
R5
R1
R4
265
Homework Problems
where the gray boxes are resistors, the two thick lines labeled 5.00 volts represent a
battery, and the arrows represent the flows of current. The following equations give
the relationships among the resistors, the currents, and the battery:
i2 i4 i1
i2 i3 i5
i1 i3 i6
i1 R1 i3 R3
i4 R4 i5 R5
i1 R1 i4 R4 E
i3 R3 i5 R5 E
The Rs give the resistances of the respective resistors, which are given as labels in the
diagram. Thus, R1 100, R3 200, R4 40.0, R5 50.0 (ohms). Note that there is no
R2. The strength of the battery is represented by E, and E = 5.00 volts.
This set of simultaneous equations in the unknown currents i1 , i2 ,..., i6 can be written
in the form Ax b , where the currents are the elements of the vector x. In order to
determine the elements of A and b, you must first rewrite the equations above so that
the unknowns are all on the left. For instance, the first equation can be rewritten as
i2 i4 i1 0 . It also helps then to rewrite that equation into a form that has all the
variables in the ascending order by subscripts with zeros multiplying the ones that are
missing: 1* i1 1* i2 0* i3 1* i4 0* i5 0* i6 0 . Note that we have also
multiplied the other variables by 1, to show that even they have a coefficient. After
you have written them that way (not to turn in), do the following:
a. Write the command that sets up the matrix A.
b. Write the command that sets up the matrix b.
c. Write the command that solves Ax = b for the currents in x.
41. [Answer in English] There are 7 equations in 6 unknowns in problem 40, but because
of redundancy among the equations, they are not over determined. Thus, the solution
that you found above is exact (within round-off error). Since they are not over
determined, it is possible to find the same 6 currents by solving only 6 equations.
Suppose you were allowed to use only 6 of the equations in the previous problem to
find the 6 currents. Which equation would you omit: 1, 2, 3, 4, 5, 6, or 7?
42. Consider the matrices H and K and the column vector c, given below
266
Homework Problems
c 20.2533 ,
d c 0.01
16.8692
0
a. [Answer in Matlab] Give the commands to solve each of the following equations
for x:
Hx c,
Hx d ,
Kx c,
Kx d
b. [Answer in English] Calculate condition numbers and use them to explain the
similarities and differences among the solutions that you got to part a.
43. A television tower is 1200 feet tall and is held firm against the wind by 4 cables that
are each fastened to the top of the tower at one end and to the ground at the other, as
shown in the figure:
267
Homework Problems
Each cable is under tension, as follows: Cable 1 is at 1000 pounds, Cable 2 is at 1500
pounds, Cable 3 is at 870 pounds and Cable 4 is at 1500 pounds.
There are three components of force exerted by each cable on the tower: two
horizontal components in the East/West direction and North/South direction and one
vertical component in the downward direction. The orientation of each cable
determines the ratio of each of its component forces to its tension. For example, the
East/West component of force exerted on the tower by Cable 1 divided by the tension
in Cable 1 is -0.61546. The minus sign means that the component is toward the West.
A positive number means East. The North/South ratio is also -0. 61546. Here negative
means Southward and positive means Northward. The downward ratio is 0.49237.
These ratios are determined completely by the direction of the cable. If the tension on
the cable were doubled, each component would double also, and the ratios would
remain the same. This is true for all the cables. Its a property of the physics of the
structure.
Here are the ratios for all components for all cables in this orderEast/West,
North/South, Down:
Cable 1:
Cable 2:
Cable 3:
Cable 4:
-0.61546 -0.61546
0.90815
0.27245
0.88697 -0.29566
-0.91863
0.22966
0.49237
0.31785
0.35479
0.32152
a. [Answer in Matlab] Give the commands to calculate the three components of the
net force exerted by these cables on the tower. (You calculate the net force by
adding the component forces for each cable including the signs in the
calculations.)
b. [Answer in Matlab] Give commands to calculate the three components of net
force exerted on the tower if Cable 1 breaks and the other cables tensions each
remain the same. (They would remain the same for only a brief instant after Cable
1 broke.)
c. [Answer in Matlab] Suppose we could adjust the tensions in the four cables to any
values we wished. We might want to adjust them so that there is no net horizontal
force on the tower. What tensions should we have on the four cables to produce a
zero net force in the East/West direction and a zero net force in the North/South
Homework Problems
268
Homework Problems
269
Homework Problems
270
4. Weight lifters sometimes need a table for converting from mass in kilograms (kg) to
weight in pounds (lb). Suppose that the masses come in 5 kg units. You are to write a
program that generates a conversion table beginning with 20 kg and going up by steps
of 5, stopping at a limit specified by the user. Each row of the table will have two
entriesthe mass and its corresponding weight. The first row will be for 20 kg. The
second row will be for 25 kg, etc. The user is prompted to specify the largest mass
desired. The table goes no higher than that.
Thus, if the user specifies the value N (kg), then the table should stop at the largest
multiple of 5 that is not greater than N. For example, if N = 97, the largest mass in the
table would be 95 kg. The weight of 1 kg is 2.205 lb. You do not need to print out the
units in your table. It is to be a table of numbers.
a. [Answer in English] Write a black-box description of the problem. In other
words, complete steps 1 and 2 of the five-step design process presented above.
b. [Answer in Matlab] Write a Matlab solution to the problem. DO NOT USE
BRANCHING OR LOOPS.
5. A projectile is fired from the origin with an initial speed of v at an angle of theta.
You wish to write a program that will ask the user to input v and theta and then
calculate and report the horizontal distance traveled by the projectile.
a. [Answer in English] Write a black box description of the problem. In other
words, complete steps 1 and 2 of the 5-step design process.
b. [Answer in English and/or Pseudocode] Design an algorithm to solve this
problem.
6. You wish to create a program to determine the minimum number of coins needed to
give a specific amount of change requested by the user. The program should produce
output like the following:
89 cents can be given as:
3 quarters 1 dime and 4 pennies
In this way, we strive for a grammatically correct output and avoid printing pointless
information (like 0 quarters).
a. [Answer in English] Write a black box description of this problem. In other
words, complete steps 1 and 2 of the 5-step design process.
271
Homework Problems
No
Sale = Y
Y == Z
Sale = X
No
Sale = Z
9. A bicycle salesperson is offered a choice of wage plans: (1) a straight salary of $300
per week; (2) $3.50 per hour for 40 hours plus a 10% commission on sales; (3) a
straight 15% commission on sales with no other salary. Write a program that takes as
input the salespersons expected weekly sales and outputs the wages paid under each
plan as well as announcing the best-paying plan.
10. [Answer in Matlab] Suppose you are programming a DVD player. When you turn
the player on, it provides the following menu of choices:
1.
2.
3.
4.
5.
Homework Problems
272
Once the user enters a choice, the program must call one of several functions to
process the request. In a preliminary version of the program, instead of calling a
function, a message is printed indicating the choice. Write the code that requests
input of a numerical choice (from 1 to 5) from the user, and then use a switch
construct to print out the users choice in words. For example, if the user chooses 1,
your code should print the message The user wants to play the disk. (or a similar
message.) You should include a response for invalid input.
11. [Answer in Matlab] Write a nested if statement that does the following:
It prints Complex Number on one line, if x is a complex number. [Hint: use
help to look up the function imag( ).]
If x is not complex but is positive, it prints Positive Number on one line.
It prints Zero, if x equals zero,.
It prints Negative if x is less than zero.
Use input to get the x value from user. Include a reasonable prompt.
12. [Answer in Matlab] Write a program that will ask the user how fast he or she drives,
and then print out what response a police officer would make to the following speed
ranges: >75, >55, >45, <45. Use nested if-else statements.
273
Homework Problems
13. [Answer in Matlab] Write a set of nested if statements to perform the logic shown in
the diagram below.
Start
True
If
x>5
False
False
Print Its a
small number
True
If
x>10
True
If
x=7
Print Its a
lucky number
False
Print Its a
number
End
14. [Answer in Matlab] Write a switch statement that prints the name of the weekday
corresponding to the number stored in x: If x equals 1, then Monday is printed, if x
equals 2, then Tuesday is printed, etc.. If x is not in the range, 1 to 5, then the
statement should print Not a weekday.
15. [Answer in Matlab] Suppose a Matlab program is to be written that prints the name of
the month and the number of days in that month corresponding to a number input by
the user. For the purposes of this assignment, you may disregard leap years.
a. Write the Matlab code to read a value input from the keyboard and assign it to the
variable x.
b. Write a switch statement that prints the name of the month corresponding to the
number stored in x: If x equals 1, then January is printed, if x equals 2, then
274
Homework Problems
February is printed, etc. If x is not in the range, 1 to 12, then the statement
should print Not a month.
c. Write a second switch statement that will print the number of days in the month
specified by the user. If x is not in the range, 1 to 12, no output should be printed.
16. [Answer in Matlab] Suppose an automated library catalogue has the following menu
of choices:
1
2
3
4
5
Once the user enters a choice, the program must call one of the several functions
to process the request. In a preliminary version of the program, instead of calling
a function, a message is printed indicating the choice. Write code that requests the
input of a numerical choice from 1 to 5, and then uses the switch construct to
print out the users choice in words. For example, if the user chooses 1, your code
should print the message The user wants to search for a title. Include a response
for invalid input.
17. [Answer in Matlab] Suppose 200 hundred freshmen, who each are given a unique
identification number in the range [1, 200], are organized into 4 groups according to
the value of the identification number, i.e., [1: 50] are in group 1, [51:100] are in
group 2, and so on. Suppose an identification number is stored in a variable named
number. Use the if construct to set a variable named group to be equal to the
appropriate group number according to number. If number is out of range, the if
construct should print an error message instead of setting the value of group.
18. [Answer in Matlab] The equations for various conics and the values of x to be used
while plotting them are given below:
1)
2)
3)
4)
Circle:
Hyperbola:
Parabola
Ellipse
y
y
y
y
=
=
=
=
sqrt(16 x^2)
sqrt(x^2 16)
sqrt(4 * (x 6))
sqrt(1 (x^2)/4)
Homework Problems
275
Sine of x
Cosine of x
Tangent of x
Exponential of x
Natural Logarithm of x
Base 10 Logarithm of x
Square Root of x
Quit
The user should be prompted to type in the number x and then be shown the menu
above and asked to make a selection. The program should print the value of the
selected function by using a switch construct. If Quit is the selection, then nothing
should be printed. Include a reasonable response for a number out of range. You may
assume that the user will type in a real scalar.
21. [Answer in Matlab] Write a program to compare the car emissions for various
pollutants to given emission limits, taking the age of the car into consideration. Print
Within emission limit if the emissions are within legal limits, else print Your car is
a danger to the environment. The algorithm is as follows:
The pollutant is selected by choosing an integer (pol_number) from a menu of the
form:
(1)
(2)
(3)
(4)
Carbon Monoxide
Hydrocarbons
Nitrogen Oxides
Non-methane Hydrocarbons
The user is prompted to enter the emission (emission) in grams per mile.
The user is prompted to enter the odometer reading (odom) and the year in which the
car was manufactured (year_man).
The entered values are compared to the limits given in the table below and the
appropriate message is printed.
276
Homework Problems
Carbon Monoxide
Hydrocarbons
Nitrogen Oxides
Non-methane Hydrocarbons
Second 5 years or
second 50,000 miles
4.2 gr/mile
0.39 gr/mile
0.5 gr/mile
0.31 gr/mile
Not P or Not Q
Not ((Not P) or Q)
Not (Not P and Q)
Not (Not P and Not Q)
23. The word Boolean is derived from the name of George Boole, a nineteenth century
English mathematician who is considered the father of symbolic logic. Boole was a
self educated scholar with limited formal training. He began his teaching career at
the age of 16 as an elementary-school teacher and eventually progressed to a
professorship at Queens College in Cork.
a. [Answer in English] The expression A or B evaluates to true provided that
the value of either or both of the variables is true. Design a Boolean expression
that evaluates to true provided that the value of exactly one of the two variables
is true.
b. [Answer in English] The following four Boolean expressions divide into two
groups with two equivalent expressions in each group. What are the two groups?
(Two expressions are equivalent if they evaluate to the same value of true or
false for each possible way of setting Footloose and FancyFree to true or false)
not(Footloose) and not(FancyFree)
Homework Problems
277
not(Footloose) or not(FancyFree)
not(Footloose and FancyFree)
not(Footloose or FancyFree)
24. [Answer in Matlab] Write one single expression that involves only operators (i.e., no
function calls) and only the variables x and y. Your expression must evaluate to:
1, if x or y, or both x and y, equal zero
x/y, if x is greater than y and x and y are not 2 or 4
1, if x is equal to y
y/x, if x is less than y and x and y are not 2 or 4
x^y, if x^y is equal to y^x and x is not equal to y
Use input to get x and y. Use a reasonable prompt.
DO NOT USE BRANCHING OR LOOPS. GIVE JUST ONE SINGLE
EXPRESSION! [Hint: Use relational operators and logical operators along with the
arithmetic operators. For example: (x>y)*x*y will be equal to the product of x and y
if x is greater than y, but it will equal zero if x is less than or equal to y.]
25. [Answer in Matlab] A prime number (or prime integer, often called simply a prime
for short) is a positive integer, p > 1, that has no positive integer divisors other than 1
and p itself. One way to test whether a number is prime is to simply divide p by all
the integers smaller than itself to determine if it has additional divisors. Use a while
loop and an if statement to determine whether a number N (where N > 2) input by the
user is a prime number. (Hint: the function mod() may prove useful.)
26. [Answer in Matlab] The Fibonacci series is represented as follows: 1, 1, 2, 3, 5, 8,
13,
It is defined as follows:
x1 = 1,
x2 = 1,
xi = xi-1 + xi-2 for all integer i greater than 2.
a. Write a program using loops to print the first 20 numbers in the Fibonacci series.
b. Generate a semi-logarithmic plot of the Fibonacci series you generated in part a.
You will want to make the y-axis logarithmic.
27. [Answer in Matlab] One place that the Fibonacci series (see problem 26) regularly
occurs is in population growth rates. If a population has no deaths, then the series
shows the increase in population after each generation. A generation is the time it
takes a member to reach reproductive maturity. The formula applies most
straightforwardly to asexual reproduction at a rate of one offspring per parent per
generation. In any event, the green crud population grows at that rate and produces
278
Homework Problems
one generation every five days. Hence, if a green crud population starts out as 10
pounds of crud, then in 5 days there is still 10 pounds of crud; in 10 days there is 20
pounds of crud, in 15 days there is 30 pounds, in 20 days there is 50 pounds, and so
forth. Write a program that takes as input the initial size of a green crud population
(in pounds) and a number of days and then outputs the number of pounds of green
crud after that many days. Assume that the population size remains the same for four
days and then increases on the fifth day.
28. [Answer in Matlab] The function f(n) is defined as follows:
f (1) 7
f (2) 3
f (n) 2 f (n 1) 3 f (n 2) for n 3
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Ignore the fact that, if the requested number is too large, some of the longer lines in
the pattern will wrap-around from one line to the next.
30. [Answer in Matlab] The formula for multiplying two matrices, A and B, is given as:
K
Where
A is an M by K matrix,
B is a K by N matrix and
Homework Problems
279
280
Homework Problems
Homework Set 4
Problems that do not explicitly say "Answer in English" are to be answered in Matlab.
1. Write a predicate called isscalar that takes one argument that determines
whether or not that argument is a scalar (i.e., returns 1 if for scalar, 0 otherwise).
2. Write a predicate called are_equal that takes two arguments and determines
whether or not they are equal. In order to be equal they must have the same sizes,
and have equal elements.
3. Write a stub for a function called Vandy that takes 3 arguments and returns two
output arguments.
4. Write a stub for a function called dualfunction that takes 2 arguments and
returns two output arguments. The first equals the sum of the two input elements,
the second equals the difference of the two elements.
5. Write a predicate called is_even that takes one argument and determines
whether or not that argument is an even number.
6. Write a predicate called string_equal that takes two string arguments and
determines whether or not they are equal. In order to be equal they must have the
same number of characters and have the same elements.
7. Write a function called order3 that takes zero to three arguments and returns
three values. Example calls:
Case 1: [x,y,z] = order3;
Case 2: [x,y,z] = order3(a);
Case 3: [x,y,z] = order3(a,b);
Case 4: [x,y,z] = order3(a,b,c);
In the first case x, y, and z are set to zero. In the second case, x, y, and z are set
equal the value of a. In the third case, if a is equal to b, then x, y, and z are set
equal to a, but, if a and b are unequal, then x is set equal to the smaller one, and y
and z are both set equal to the larger one. In the fourth case, x, y, and z receive
the values of a, b, and c in ascending order. Hint: nargin will be helpful. If fewer
than three output arguments are given, then the function should not calculate the
missing values. Hint: nargout will be helpful.
8. [Answer in English] In your own words, explain the differences between local,
global and persistent variables in Matlab.
9. [Answer in English.]
280
281
Homework Problems
This call would cause the square root of x to be plotted horizontally versus the
tangent of x vertically for values of x from 0 to 2*pi in steps of 0.1. The
resulting plot would be equivalent to
plot(sqrt(0:.1:2*pi),tan(0:.1:2*pi);
You will need to use Matlab's function function feature, and the built-in function
feval.
15.
a) Write a function called simplestats() that will accept up to five input
arguments and will return up to four output arguments. The input arguments
should all be scalar values. The following values for output arguments should be
281
282
Homework Problems
returned in this order: the sum of the arguments, the product of the arguments,
the mean of the arguments, the standard deviation of the arguments.
b) Write a function call for simplestats() that will calculate the sum,
product and mean of the following values: 10, 25, 31, 44
16. [Answer in English] Look at the code that is below. The loop iterates 100 times.
Inside that loop there are two special cases that are sometimes set by if
statements.
for i = 1:100
a = rand(1); b = rand(1); c = rand(1);
if rand(1)>.5
% Special case 1:
b = a;
end
if rand(1)>.5
% Special case 2:
c = a;
end
Approximately how many times would you expect this special case to be
set? In other words, approximately how many times would you expect the
statement, b = a, to be executed during this loop?
b. Approximately how many times would you expect both Special case 1
and Special case 2 to be set at the same time. In other words,
approximately how many times would you expect both the statements b
= a and c = a to be executed during the same iteration?
a.
17. Copy the following function into your M-file. The function takes two arguments,
x and y, each of which is a vector, and it returns the largest index i such that x(i)
is no bigger than y(i). Insert a conditional into the while statement so that it
stops when the value of x(i) exceeds that of y(i) or the length of either vector is
exceeded by i. Use short-circuiting to avoid index errors.
function i = no_bigger(x,y)
i = 1;
while %replace this comment with a conditional
i = i+1;
end
i = i-1;
282
283
Homework Problems
RB
R AB * RBC
R AB R AC RBC
RC
R AC * RBC
R AB R AC RBC
R A * RB R A * RC RB * RC
RB
RBC
R A * RB R A * RC RB * RC
RA
Duration in seconds
Frequency in Hz
283
284
Homework Problems
21. Write a predicate called is_singular that takes one argument that determines
whether or not that argument is a singular matrix (i.e., returns 1 if for singular
matrix, 0 otherwise). A singular matrix is a square matrix that does not have a
matrix inverse. A square matrix has an inverse if and only if its determinant is
nonzero. It also has an inverse if and only if its condition number is not infinity.
Use Help det to determine which method Matlab recommends for determining
whether a matrix is singular and use it. Hint: You can conclude that there is no
inverse if the condition number is larger than 1/eps. eps is a function that returns
the smallest possible fractional difference between two numbers in Matlab.
22. Write a predicate called are_complex_conj that takes two arguments and
determines whether or not they are complex conjugate to each other. In order to
be complex conjugate, they must be the same size, their real parts must be equal,
the absolute values of their imaginary parts must be equal, and the signs of the
imaginary parts of one argument must be opposite that of the corresponding
imaginary parts of the other argument. For example:
[2 + 3i, 4 5i] and [2 3i, 4 + 5i] are complex conjugate to each other.
[2 + 3i, 4 5i] and [2 + 5i, 4 5i] are not complex conjugate to each other.
2 + 3i and [2 3i, 4 + 5i] are not complex conjugate to each other.
23. Write a stub for a function called Commodore that returns 2 output arguments if
user calls it with 3 input arguments but returns 3 output arguments if user calls it
with 4 input arguments. Hint : The use of nargin function should be helpful.
24. Write a function called Loanbal that is called this way:
y = Loanbal(y0, I, payment, N)
It must compute a vector y of loan balances where y(n) is the balance at month n.
The amount borrowed is y0, the annual interest rate is I, and the amount paid
each month is payment. The maximum number of payments is N, but the balance
should never fall below zero. The formula to compute the loan balance is
expressed by
I
y n 1 * y n 1 payment
12
25. Given a positive real number a , the square root of a can be computed from the
nonlinear difference equation
yn 0.5 * yn 1
yn 1
284
285
Homework Problems
y1 0.5 * 2 1.5
2 2
3 2 17
y2 0.5 *
1.4166667
2 3 12
17 2
1.4142157
y3 0.5 *
12 17
12
Clearly, yn is converging to
a 1.4142136 .
285
286
Homework Problems
The function, bigger2, takes two arguments and returns the larger value. Use
feval and the bigger2 function to write two new functions, bigger3 and
bigger4 that take three and four arguments respectively and returns the largest
value. You should use the function function feature of Matlab as well as the
feval function to solve this problem.
30. Use the following code for this problem:
function ii = is_equal(x,y)
ii = 1;
is_find = false;
while %replace this comment with a conditional of your choosing
if x(ii) == y(ii)
is_find = true;
end
ii = ii + 1;
end
if (is_find == false)
ii = 0;
end
Modify the code above to accomplish the following: the function should take two
arguments, x and y, each of which is a vector. You want the function to return
the value of the first index, ii, such that x(ii) is equal to y(ii). If this condition
does not exist, the function should return 0. Use short circuiting to stop the loop
once the desired index is found. Additionally, you should be sure to include code
to avoid index length errors in your loop.
31. Write a function called my_log(x,N) that will use a for loop to calculate an
approximate natural log of x , using N terms in this summation:
1 x 1
log x 2
n 1 2n 1 x 1
N
286
2 n 1
287
Homework Problems
Include a check that x is positive (positive means > 0, not 0). If x is negative,
your function must print x must be positive and return zero.
32. a) The Taylor series approximation for ex is given as:
xn
e
n0 n!
x
Write a function, taylor(x) that will use this summation to calculate and
return the value of ex for any x entered by the user. You should continue to sum
terms until the absolute value of the last term added is < 0.001. Hint: Matlabs
built-in function factorial will be useful.
b) Write a function, taylor_compare(x), that will take the Taylor series
approximation for ex and will return the percentage error between the
approximation and the result from the Matlab function exp(x)
33. Write a function, permute(n,r), that will take two arguments, n and r, and
return the permutation nPr. Permutation is calculated using the following formula:
n
Pr
n!
(n r )!
You should write a single subfunction: facti() that will calculate the factorial
values needed in your calculation. You will also wish to make your function
robust by ensuring the required arguments have been passed to the function and
that n >= r.
34. The greatest common divisor of two positive integers is the largest integer that
divides them both. For example, the greatest common divisor of 9 and 6 is 3.
Write a function that accepts two integer input arguments and returns their
greatest common divisor.
35. Suppose you are given a two-dimensional cell, c, whose values contain contact
information for a companys employees. Each row contains information for a
different employee. The first column contains the employees ID number, the
second column contains their name, the third column contains their office location
and the fourth column contains their work phone number. Write a function called
cell_to_struct() that will take the information contained in cell c and
transfer it to a new structure array called personnel. The structure array
personnel should contain the following fields: id_num, emp_name,
office_loc, and phone. You may assume that the cell is fully populated, that
is, each row contains data in all columns.
287
288
Homework Problems
36. Write a function called solve_and_check that solves Ax=b for x when given
A (first argument) and b (second argument), returns x, and also checks the answer
is giving to see whether it is correct. If not, it still returns the least-squares
solution, but it also issues the statement Warning: At least one of the equations is
not solved to within round-off by this solution. To determine whether or not to
issue the warning, you may use only one IF statement, or possibly one IF-ELSE
statement with only one conditional, and it should do that if and only if at least
one of the elements of Ax-b is larger in absolutely than b/1e6, and no loops are
allowed in this function. (HINT: An if statements conditional is deemed true if
and only if all of the elements of the conditional are true.)
37. Write two functions, deposit() and withdraw() that will record monetary
transactions to a single (identical) bank account. Both functions should accept
one input argument. deposit() should add its arguments value to the bank
account. withdraw() should subtract its arguments value to the bank account.
Both functions should print the new balance after the transaction, using fprintf().
Additionally, the user should be notified if theyre overdrawn (that is, if they have
a negative balance). Initially, there is no money in the account. HINT: Use a
global variable.
288
289
Homework Problems
Homework Set 5
Problems that do not explicitly say "Answer in English" are to be answered in Matlab.
User-defined data types
2. Write a function called countspaces that will accept one input argument, a
string, and return as an output argument the number of space characters in that
string. You may assume that the argument passed is guaranteed to be a string.
Hint: Use the isspace function.
3. Write a function called rot_wrap that takes two input arguments and returns
one output argument as follows: code = rot_wrap(message,n), where
code and message are each strings (i.e., vectors of type char), and n is a
positive number. These two strings are the same at every position except at
positions of lower case letters. If it is a lower-case letter, then there is a change.
The change is that n is added to the ASCII code for the letter. Furthermore, if the
result of the addition is outside the range of the codes for the lower-case letters
than the result is wrapped around to the beginning of the set of lower-case
letters. It is as if the alphabet were written on a circle and the new letter is the
result of shifting by n around the circle as shown by the example in the figure
below. The example shows that for n = 5, the letter x will be changed to the
letter c. If the second argument is omitted, then the default n = 5 should be used.
If the second argument is negative, the function must give an error message and
return. If the first argument is not a string, the function must give an error
message and return.
289
290
Homework Problems
z a b c
.
.
.
.
.
.
Recursion
4. [Answer in English] For each of the following situations, give the maximum
number of activation records on the stack. In each case assume that there is
always one record on the stack for the command window.
a. A is called from the command line, A calls B, B calls C, C calls D, D
returns, C returns, B returns, A returns.
b. A is called from the command line, A calls B, B calls C, C calls D, D
returns, C calls E, E calls F, F returns, E returns, C returns, B returns, A
returns.
c. A is called from the command line, A calls B, B calls C, C calls C, C
returns, C returns, B returns, A returns.
d. A is called from the command line, A calls B, B calls C, C calls A, A
returns, C returns, B returns, A returns. (This is an example of indirect
recursion. Indirect recursion is the situation that happens when A calls B
and before B returns another function calls A.)
e. The function fibonacci (Ch. 9, Fig. 15) is called with month = 5.
5. Write a recursive function called hw5_5 to implement this recursive definition:
f n 2, for n 1
f n log f n 1 , otherwise
290
291
Homework Problems
f n 2, for n 1
f n
f n 1 n, otherwise
7. The following function takes a very long time to execute when its argument is 20
or more:
function a = hw5_slow(n)
if n < 1;
a = 10;
else
a = hw5_slow(n-1)+ 1/ hw5_slow(n-1);
end
Change it so that it is fast (should be almost instantaneous for n < 500) but still
calculates the same thing. Call your new version, hw5_7.
8. Consider the function fibonacci
a. Make a new version, called fib_sooner that is the same as
fibonacci, except that the infertile interval is one month instead of
two.
b. Make a new version, called fib_faster that is the same as
fibonacci, except that there are two pairs per month born to each
fertile pair instead of one.
c. Plot the growth of both on the same graph. Which one grows faster? (You
do not have to submit a function or a plot. Just say which is faster.)
9. Consider the following recursive function:
function a = permutations(v)
% (v must be a vector)
vlen = length(v);
if vlen <= 1, a = v;
else
a = [];
for jj = 1:vlen
tail = permutations(v([1:jj-1, ...
jj+1:end]));
H = size(tail,1);
head = v(jj)*ones(H,1);
a = [a;[head, tail]];
end
291
292
Homework Problems
end
a. [Answer in English] Run the function on some vectors and look at the
output of the function What does the function do? (i.e., what is the purpose
of the function?).
b. [Answer in English] What is the base case?
c. Make the smallest alteration to the recursive case that you can so that the
rows of the output appear in reverse order. By reverse we mean here that
the numbers on a row are the same, but the first row becomes the last row,
the 2nd row becomes the next-to-last row, etc. In other words, suppose the
answer produced by the code above for argument V is array M. Then, after
you have changed the function, its answer, when given the same argument
V, would be M(end:-1:1,:). Name your function permutations.
10. [Answer in English] The following code contains an error. It can be corrected by
changing one line. How can the error be corrected? Give the answer in words.
You do not have to submit an altered function.
function m_min = min_index(v)
%MIN_INDEX find index of smallest element
%
MIN_INDEX(V) returns the index of the
%
smallest element in the vector V.
%
Method uses recursion.
if isempty(v), error('v is empty');
elseif length(v) == 1, m_min = 1;
else
m_min = 1;
mp2_min = min_index(v(2:end));
if v(mp2_min) < v(m_min)
m_min = mp2_min;
end
end
292
293
Homework Problems
Homework Set 6
Searching problems
1. [Answer in English] Consider the list: L = [4 5 12 14 17 24 25 27 28
31 35 36 39].
Suppose you are using the binary search algorithm. For each of the following
targets, give a list of the numbers in B (not their indices) that would be compared
with the target in the order in which they would be compared with it.
a.
b.
c.
d.
24
4
17
15
is replaced by
293
Homework Assignment 6
294
temp = v(m);
v(m) = v(m_min);
v(m_min) = temp;
294
Homework Assignment 6
295
d. 4 3.2 N 2 N
(-100, 100)
N
(100, 50)
E
S
Origin
(x , y)
295
Homework Assignment 6
296
V
x
F = r2P. The work done by the gas when the volume expands from V1 to
volume V2 is therefore:
V1
V2
PdV
In a steam engine the pressure P and volume V of steam satisfy the equation PV1.4
= k, where k is a constant. (This is true for adiabatic expansion that is,
expansion in which there is no heat transfer between the cylinder and its
surroundings.) Using Matlabs symbolic mathematics facility, give commands
that calculate the work done by the engine during a cycle when the steam starts at
a pressure of 160 lb/in2 and a volume of 100 in3 and expands to a volume of 800
in3.
296