Chapter 6 OCR
Chapter 6 OCR
CONTENTS
functions that return menu-driven program syntax errors ó.1 More Types of
more than one value variable scope run-time errors User- Defined
Functions ... 193
functions that do not base workspace logical errors
return any values local variable tracing 5.2 MATLAB
side effects main function breakpoints Program
call—by—value g lobal variable breakpoint alley
Organization 202
modular programs persistent variable function stubs ó.3 Application:
main program declaring variables live script M enu -D riven
primary function bug code cells M odular
Program ..... 207
subfunction debugging
Variable
Scope .::::.214
Chapter3 introduced scripts and user-defined functions. In that chapter, we saw B.5 Debugging
how to write scripts, which aresequences of statements that are stored in MATLAB Techniques. 219
code files and then executed. We also saw how to write user-defined functions, also
ó.ó Live Scripts,
stored in MATLAB code files that calculate and returna single value. In this chapter,
Code Cells, and
we will expand on these concepts and introduce other kinds of user-defined func-
Publishing
tions. We will showhow MATLAB programs consist ofcombinationsofscripts and
Code ........... 225
user-defined functions. The mechanisms forinteractions of variables in code files
and the Command Window will be explored. Techniques forfinding and fixing Summary .......... 228
mistakes in programs will be reviewed. Finally, the use of live scripts created by Common
the Live Editor(new asofR20 lGa), and usingcodecells in scripts will be introduced. Pitfalls .............. 228
Programming Style
Guidelines ........ 228
6.1 MORE TYPES OF USER-DEFINED FUNCTIONS
We have already seen how to writea user-defined function, stored ina code file,
that calculates and returns one value. This is just one type of function. It is also
possible fora function to return multiple values and it is possible fora function
to return nothing. We will categorize functions as follows: 193
end
ó.
1 M o reTypes of U ser-
D ef
in e d F u n ctio n s
In the vector of output arguments, the output argument names areby conven-
tion separated by commas.
Choosing New, then Function brings up a template in the Editor that can then
be filled in:
function [ output_args] =untitled(input_args)
%UNTITLEDSummaryofthis functiongoeshere
% Detailedexplanationgoeshere
end
Ifthis is not desired, it may be easier to start with New Script.
For example, here isa function that calculates two values, both thearea and the
circumference ofa circle; this is stored ina file called areacirc.m:
areacirc.m
function [area, circum) = areacirc(rad)
%areacircreturnstheareaand
%thecircumferenceofacircle
% Format: areacirc(radius)
As this function is calculating two values, there are two output arguments in
the function header (area and circum), which areplaced in square brackets [].
Therefore, somewhere in thebody ofthefunction, values have to be stored
in both.
As the function is returning two values, it is important to capture and store these
values in separate variables when thefunction is called. In this case, the
first value returned, the area of the circle, is stored ina variablea and the second
value returned is stored ina variable c:
>> Éa, --areacírc 47
a =
50.2655
25.1327
Ifthis is not done, only thefirst value returned is retained—in this case, the area:
>> dz sp (a ser c::i cc: (4) )
5 0 .2 6 5 5
Note that in capturing the values, the order matters. In this example, the func-
tion first returns the area and then the circumference of the circle. The order in
which values are assigned to the output arguments within the function, how-
ever, does not matter.
CHAPTER 6: NATLAB Programs
ûUICK QUESTION!
What would happen ifa vector of radii was passed to the > (a, cj = areachxc (I.• 4)
function? a =
3.1416 12.5664 28.2743 50.2655
Answer: As the.* operator Is usedin the function to multiply
rad by itself,a vector can be passed tothe input argument rad. '
6.2832 12.5664 18.8496 25.1327
Therefore, the results will also be vectors, so the variables on
the left side ofthe assignment operator would become vectors
of areas and circumfe°ences.
ûUICK QUESTION!
What if you want only the second value that is returned?
Answer: Function outputs can be ignored usinp the tilde:
6.2832 12.5664 18.8496 25.1327
The help function shows thecomment listed under the function header:
Thisfunctioncalculatestheareaand
thecircumferenceofacircle
Format: areacirc(radius)
The areacirc function could be called from the Command Window asshown
here, or froma script. Here isa script that will prompt theuser for the radius
of just one circle, call the areacirc function to calculate and return the area and
circumference of the circle, and print the results:
calcareacirc.m
%This scriptprompts the user for the radius of a circle,
% callsa functiontocalculateandreturnboth thearea
% andthecircumference, andprintstheresults
%It ignores units anderror-checking for simplicity
>> ca2careaczrc
Pleaseenter theradiusofthecircle: 5.2
Foracirclewitharadiusof 5.2,
thearea is84.9andthecircumference is32.7
ó.1 M o re Type s o f U se r-D efin e d F u n ctio n s
PRACTICE 6.1
Writea function per/marea that calcu fates and returns the perimeter and area ofa rectang Ie. Pass
the length and width of the rectangleas in put arguments. For example, this function might be
cafled from the following script:
ca1careaperim.m
As another example, considera function that calculates and returns three out-
put arguments. The function will receive one input argument representinga
total number of seconds and returns the number of hours, minutes, and
remaining seconds that it represents. For example, 75 15 total seconds is2 h,
5 min, and 15s because 75 15 =3 G00x 2 + GOx 5 + 15.
The algorithm is as follows.
• Divide the total seconds by 3600, which is the number ofseconds in an
hour. For example, 75 15/3600 is 2.0875. The integer part is the
number ofhours (e.g., 2).
• The remainder of the total seconds divided by 3600 is the remaining
number ofseconds; it is useful to store this ina local variable.
• The number ofminutes is the remaining number ofseconds divided by
GO (again, the integer part).
• The number ofseconds is the remainder of the previous division.
breaktime.m
function [hours, minutes, secs) =breaktime(totseconds)
%breaktimebreaksatotalnumberof seconds into
%hours, minutes, and remaining seconds
%Format: breaktime(totalSeconds)
hours = floor(totseconds/3600);
remsecs = rem(totseconds, 3600);
minutes = floor(remsecs/60);
secs = rem(remsecs,60);
end
C HA PTE R 6 : NATLAB Programs
15
As before, it is important to store all values that the function returns by using
three separate variables.
Statementshere
end
Note what is missing inthe function header: there are no output arguments and
no assignment operator.
For example, the following function just prints the two arguments, numbers,
passed to it in a sentence format:
printem.m
functionprintem(a,b)
% printemprints twonumbers in a sentence format
% Format: printer(num1, num2)
Note that as the function does not returna value, it cannot be called from an
assignment statement. Any attempt to do this would result in an error, such as
the following:
>> x=printem(3, S) %Error!!
Error usingprintem
Toomanyoutputarguments.
We cantherefore think of the call toa function that does not return values asa
statement by itself, in that the function call cannot be imbedded in another
statement such as an assignment statement or an output statement.
The tasks that are accomplished by functions that do not return any values
(e.g., output from an fprintf statement ora plot) are sometimes referred to
as side effects. Some standards for commenting functions include putting the
side effects in the block comment.
PRACTICE 6.2
Writea function that receivesa vector as an in put argument and prints the individuaI elements
from the vector ina sentence format.
Element1 is 5.9
Element2 is33.0
Element3 is 11.0
Calling this function prints the circumference, but there is no way to store the
value so that it can be used in subsequent calculations:
>> ca2 cel rc uml (3.3 }
2 0 .7 3 4 5
100 C HAPTER 6: NATLAB Programs
Since no value is returned by the function, attempting to store the value ina
variable would be an error:
>> —— ca2ccircum2(3.37
Error using calccircuml
Toomanyoutputarguments.
Bycontrast, the following function calculates and returns the circumference, so that
itcan be stored and used inother calculations. For example, ifthe circle is the base of
a cylinder and we wish tocalculate the surface area of the cylinder, we would needto
multiply the result from thecalccircum2 function by the height of the cylinder.
ca1ccircum2.m
function circle circum= calccircum2(radius)
% calccircum2 calculates andreturns the
circumferenceofacircle
% Format: calccircum2(radius)
One possible exception to this rule of not printing when returning is to havea
function returna value if possible but throw an error if not.
>>príntrandnp
Therandom# is 0.52
Infact, the function can be called with or without empty parentheses, whether
or not there are empty parentheses in the function header.
This was an example ofa function that did not receive any input arguments nor
did it return any output arguments; it simply accomplisheda task.
The following is another example ofa function that does not receive any input
arguments, but in this case, it does returna value. The function prompts the
user fora string and returns the value entered.
stringprompt.m
functionoutstr = stringprompt
% stringpromptpromptsfora stringand returns it
% Formatstringpromptor stringprompt()
>> mystríng=stríngprompt
Whenprompted, enter a string of any length.
Enter the stringhere: Hi there
mystring=
Hi there
PRACTICE 6.3
Writea function that will prompt the user fora string of at least one character, loop to error-check
to make sure that the string has at feast one character and return the string.
106 CHAPTER 6: NATLAB Programs
ûUICK QUESTION!
It is important that the number ofarguments passed in the Answer: The fi°st proposed function call, (a], is valta. There
call toa function must be the same as thenumber ofinput are three arguments that are passed tothe three input argu -
arguments in the function header, even if that number Is zero. ments in the function header, the name ofthefunction is qq /,
Also. !fa function returns more than one value, it is important and there are two variables in the assignment statement to
to "capture" all values by having an equivalent number ofvari- store the two values returneo from thefunction. Function call
ables ina vector on the left side of an assignment statement. (b) is valid, although only the first value returned from the
Although it is not an error if there aren”t enough variables, function would be stored in answer; the second value would
some ofthevalues returned wi II be lost. The following ques- be lost. Function call lc] is invalid because the name ofthe
tion is posed to highlight this. function is given incorrectly. Function call (d] is invalid
because only two arguments are passed to the function, but
Given the following function header (note that this is just the
there are three input arguments in the function header.
function header, not the entire function definition]:
Ina modular program, there would be one main script (or, possiblya function
instead) that calls three separate functions to accomplish these tasks:
6.2 MATLABP ro
g ram0 rg
a niz ation I
As scripts and functions are all stored in code files that have an extension of .m,
there would therefore be four separate code files altogether for this program;
one script file and three function code files, as follows:
calcandprintarea.m
%This is the main script tocalculate the
% areaofacircle
%It calls3 functionstoaccomplishthis
radius = readradius;
area= calcarea(radius);
printarea(radius,area)
readradius.m
function radius =readradius
% readradiuspromptsthe userandreadstheradius
% Ignoreserror-checking fornow for simplicity
% Format: readradius or readradius()
ca1carea.m
functionarea= calcarea(rad)
% calcareareturnstheareaofa circle
% Format: calcarea(radius)
printarea.m
functionprintarea(rad,area)
% printareaprintstheradiusandarea
% Format: printarea(radius, area)
PRACTICE 6.4
Modify the readradius function to error-check the user's input to make sure that the radius is valid.
The function should ensure that the radius isa positive number bylooping to print an error mes-
sage until the user entersa va did radius.
6.2 MATLABP ro
g ram0 rg
a niz ation I
6.2.2 Subfunctions
Thus far, every function has been stored ina separate code file. However, it is pos-
sible to have more than one function ina given file. For example, if one function
calls another, the first (calling) function would betheprimary function and the func-
tion that is called isa subfunction. These functions would both be stored in the same
code file, first the primary function and then thesubfunction. The name ofthecode
file would be thesame asthename oftheprimary function, to avoid confusion.
To demonstrate this,a program that is similar to the previous one, but calcu-
lates and prints the area ofa rectangle, is shown here. The script, or main pro-
gram, first callsa function that reads the length and width oftherectangle, and
then callsa function to print the results. This function callsa subfunction to
calculate the area.
rectarea.m
% Thisprogram calculates Sprints theareaof arectangle
readlenwid.m
function [l,w] = readlenwid
% readlenwidreads &returns the lengthandwidth
% Format: readlenwid or readlenwid()
printrectarea.m
functionprintrectarea(len, wid)
% printrectareaprints therectanglearea
% Format: printrectarea(length, width)
>> he2pprlntrectarea
printrectareaprints the rectangle area
Format: printrectarea(length, width)
>> he2pprIntrectarea>ca2crectarea
calcrectareareturns the rectanglearea
Format: calcrectarea(length, width)
6.3 Applicatio n: Menu - Driven Modular Prog ram 203
PRACTICE 6.5
Fora right triang Ie with sides a, b, and c, wherec is the hypotenuse andB is the ang Ie between
sidesa and c, the lengths of sidesa and 6 are given by:
a = c* cos(8)
b = c* sin(8)
Writea script righttri that callsa function to prompt theuser and read in values forthe hypotenuse
and the angle (in radiansl, and then calfsa function to calculate and return the lengths of sidesa
andb anda function to print out all values ina sentence format. For simplicity, ignore units. Here
is an example ofrunning the script, the output format should be exactly as shown here:
As the value ofn increases toward infinity, the result of this expression
approaches the value of e.
An approximation for the exponential function can be found using what is
calleda Maclaurin series:
e‘ m 1 + — + — + — + ...
1! 2! 3!
We will writea program to investigate the value ofe and the exponential
function. It will be menu-driven. The menu options will be:
• Print an explanation of e.
• Prompt theuser fora value ofn and then find an approximate value fore
using the expression (1+ 1/n)‘.
• Prompt theuser fora value forx. Print the value of exp(x) using the
built-in function. Find an approximate value for e‘ using the Maclaurin
series just given.
• Exit the program.
• Calla function eoption to display the menu andreturn the user's choice.
• Loop until the user chooses to exit the program. Ifthe user has not chosen
to exit, the action of the loop is to:
Depending on theuser's choice, do one of the following:
- Calla function explaine to print an explanation of e.
- Calla function limite that will prompt theuser forn and calculate an
approximate value fore
- Prompt theuser forx and calla function expfn that will print both an
approximate value for e‘ and the value of the built-in exp(x).
Note that because any value forx is acceptable, the program does
not need to error-check this value.
Call the function eoption to display the menu andreturn the user's
choice again.
6.3 Application: Menu - Driven Modular Prog ram 203
Theentire program consists of the following script file and four function code
files:
eapplication.m
%Thisscriptexploreseand theexponential function
%Choice4 is toexittheprogram
while choice -=4
switchchoice
case1
%Explaine
explaine,
case2
%Approximateeusinga limit
limite,
case3
%Approximateexp(x) andcomparetoexp
x= input('Pleaseenteravalue forx: '),
expfn(x),
end
%Displaymenu againandgetuser'schoice
choice= eoption;
end
eoption.m
function choice= eoption
%eoptionprintsamenuofoptionsanderror-checks
% until theuserchoosesoneoftheoptions
%Format: eoptionoreoption()
printchoices
choice= input(' ');
while-any(choice == 1:4)
disp('Error-pleasechooseoneoftheoptions. ')
printchoices
choice= input(' ');
end
end
functionprintchoices
fprintf('Pleasechooseanoption:\n\n');
fprintf('1) Explanation\n')
fprintf('2) Limit\n')
fprintf('3) Exponential function\n')
fprintf('4) Exitprogram\n\n')
end
ó.
3 A p pli
catio n:M enu -Driven M o du la
r P rog ram
explaine.m
functionexplaine
% explaineexplains alittlebitaboute
% Format: explaineorexplaine()
fprintf('Theconstanteiscalled thenatural')
fprintf(' exponentialbase.\n')
fprintf('Itis usedextensivelyinmathematicsand')
fprintf(' engineering.\n')
fprintf('Thevalueoftheconstanteis 2.7183\n')
fprintf('Raising etothepowerofxisso common that')
fprintf(' this iscalledtheexponential function.\n')
fprintf('Anapproximation foreis foundusinga limit.\n')
fprintf('Anapproximation fortheexponential function')
fprintf(' canbe foundusing a series.\n')
end
limite.m
function limite
limitereturnsan approximateofeusing a limit
Format: limiteor limite()
% Callasubfunction topromptuserforn
n=askforn,
fprintf('An approximation ofewithn= %dis%.2f\n', ...
n, (1+ 1/n) ’n)
end
functionoutn=askforn
askfornpromptstheuser forn
Formataskforn or askforn()
% Iterror-checkstomakesurenisapositiveinteger
expfn.m
functionexpfn(x)
% expfn comparesthebuilt-in functionexp(x)
% andaseriesapproximationandprints
% Format expfn(x)
% nisarbitrarynumberof terms
n= 10,
fprintf('Approximateexp(x) is %.2f\n', appex(x,n)
end
functionoutval= appex(x,n)
% appexapproximatese tothexpowerusingtermsup to
% x to thenthpower
% Format appex(x,n)
fori= 1:n
outval=outval + (xi)/factorial(i),
end
end
(1)Explanation
(2)Limit
(3)Exponential function
(4) Exitprogram
Then, what happens will depend on which option(s) the user chooses. Every
time the user chooses, the appropriate function will be called and then this
menu will appear again. This will continue until the user chooses4 for ’Exit
Program.' Examples will be given of running the script, with different
sequences of choices.
In the following example, the user
• Chose1 for’Explanation’
• Chose4 for’Exit Program'
(1) Exprarabi on
(2)L:i m:i t:
(3) ExponenI:i a1 EuncI::i on
(4 ) Ex:iI program
• Chose2 for’Limit'
When prompted forn, entered two invalid values before finally
enteringa valid positive integer
• Chose4 for’Exit Program'
Again, for simplicity, the menu options and choices are not shown.
> eapp1:i cv I:i on
Pleaseenteravalue forx: 4.6
Valueofbuilt-inexp(x) is 99.48
Approximateexp(x) is98.71
Pleaseenteravalue forx: -2.3
Valueofbuilt-inexp(x) is 0.10
Approximateexp(x) is0.10
function runsum=mysum(vec)
% mysum returnsthe sumofavector
% Format: mysum(vector)
runsum= 0;
for i=1:length(vec)
runsum= runsum+vec(i);
end
end
Running this function does not add any variables to the base workspace, as
demonstrated in the following:
>> c2ear
>> rto
>> aíso(mysum((5 9 1
15
>> rto
>> who
Yourvariablesare:
i runsum vec
Variables that are defined in the Command Window canbeused ina script, but
cannot be used ina function. For example, the vector vec could be defined in the
Command Window (instead of in the script), but then used in the script:
CHAPTER 6: NATLAB Programs
mysumscriptii.m
%This script sums avector from the CommandWindow
runsum= 0;
fori=1:length(vec)
runsum=runsum vec(i);
end
disp(runsum)
>> c2ear
>> ver =I : 7,
>> mo
Yourvariablesare:
vec
>> mysumscriptiz
28
>> mo
Yourvariablesare:
i runsum vec
Note Because variables created in scripts and in the Command Window both usethe
This however, is very poor base workspace, many programmers begin scripts witha clear command to
programming style. It is eliminate variables that may have already been created elsewhere (either in
much better to pass the the Command Window orinanother script).
vector vec toa function.
Instead ofa program consisting ofa script that calls other functions to do the
work, in some cases programmers will writea main function to call the other
functions. So, the program consists of all functions rather than one script
and the rest functions. The reason for this is again because both scripts and
the Command Window usethebase workspace. By using only functions in
a program, no variables are added to thebase workspace.
It is possible in MATLAB aswell in other languages, to have global variables that
can be shared by functions without passing them. Although there are some
cases in which using global variables is efficient, it is generally regarded as poor
programming style and therefore will not be explained further here.
The following program demonstrates this. The script callsa function /uncI
which initializesa variable count to 0, increments it, and then prints the value.
Every time this function is called, the variable is created, initialized to 0,
changed to 1, and then cleared when thefunction exits. The script then calls
a function func2 which first declaresa persistent variable count. If the variable
has not yet been initialized, which will be the case the first time the function is
called, it is initialized to 0. Then, like the first function, the variable is incremen-
ted and the value is printed. With thesecond function however, the variable
remains with its value when thefunction exits, so the next time the function
is called, the variable is incremented again.
persistex.m
%This scriptdemonstratespersistentvariables
funcl.m
function funcl
% funcl increments anormalvariable "count"
% Format funcl or funcl()
count = 0;
count = count+ 1;
fprintf('The valueofcount is %d\n',count)
end
func2.m
function func2
% func2 incrementsapersistentvariable "count"
% Format func2 orfunc2()
persistentcount%Declarethevariable
if isempty(count)
count = 0;
end
count = count+ 1;
fprintf('Thevalue of count is %d\n',count)
end
218 CHAPTER 6: NATLAB Programs
The line
persistentcount
declares the variable count which allocates space for it but does not initialize it.
The if statement then initializes it (the first time thefunction is called). In many
languages, variables always have to be declared before they can be used; in
MATLAB, this is true only forpersistent variables.
The functions can be called from thescript or from theCommand Window, as
shown. For example, the functions are called first from the script. With the
persistent variable, the value of count is incremented. Then, fiincl is called
from the Command Window andfiinc2 is also called from the Command
Window. As thevalue of the persistent variable had the value 2, this time
it is incremented to 3.
>>pers£stex
This is whathappens witha "normal" variable:
Thevalueof count is1
Thevalueof count is1
This is whathappens withapersistentvariable:
Thevalueof count is1
Thevalueof count is2
> > Eun ct
Thevalueofcount is1
Ascanbeseen from this, every time the function funcl is called, whether from
persisted or from the Command Window, thevalue of1 is printed. However,
with func2 the variable count is incremented every time it is called. It is first
called in this example from persisted twice, so count is1 and then 2.Then, when
called from theCommand Window, it is incremented to3 (so it is counting
how many times the function is called).
The way to restarta persistent variable is to use the clear function. The
command
> > ctearE uncI:i one
will reinitialize all persistent variables (see help clear for more
options). However, as of Version 2015a, a better method has been
established which is to clear an individual function rather than all of
them, e.g.,
> > ct ear E un c2
ó.
5 D e buggin g Te ch n iq ue s
PRACTICE 6.6
The following function posnum prompts the user to entera positive number and loops to error-
check. It returns the positive number entered by the user. It ca Elsa subfunction in the loop to print
an error message. The subfunction hasa persistent variable to count the number oftimes an
error has occurred. Here is an example ofcafling the function:
>> enteredvalue=posnum
Enter apositivenumber: -S
Error# l ... Followinstructions!
Does -S.00look likeapositivenumber toyou?
Enter apositivenumber: -33
Error# 2... Followinstructions!
Does-33.00 look likea positive number toyou?
Enter apositivenumber:6
enteredvalue =
6
functionnum=posnum
% Prompt useranderror-checkuntilthe
% userentersapositivenumber
% Formatposnumorposnum()
num= input('Enterapositivenumber: );
whilenum<0
errorsubfn(num)
num= input('Enter apositivenumber: ');
end
end
function errorsubfn(num)
% Fill this in
end
Of course, the numbering ofthe error messages will continue if the function is executed again
without clearing it first.
been caused bya moth inthecomputer's circuitry! The process of finding errors
ina program and correcting them, is still called debugging.
As we have seen, the checkcode function can be used to help find mistakes or
potential problems in script and function files.
Dldyoumean:
>>newva2ue=va2ue+3;
Runtime orexecution-time errors are found whena script or function is execut-
ing. With most languages, an example ofa runtime error would be attempting
to divide by zero. However, in MATLAB, this will return the constant Inf.
Another example would be attempting to refer to an element in an array that
does not exist.
runtimeEx m
%This script shows anexecution-time error
vec = 3:5;
fori = 1:4
disp(vec(i))
end
ó.
5 D e buggin g Te ch n iq ue s
The previous script initializesa vector with three elements, but then attempts to
refer toa fourth. Running it prints the three elements in the vector, and then an
error message is generated when it attempts to refer to the fourth element. Note
that MATLAB gives an explanation of the error and gives the line number inthe
script in which theerror occurred.
>> ruxtzmeBx
3
4
5
Attempted toaccessvec(4), indexoutofboundsbecausenumel(vec)=3.
ErrorinruntimeEx (line6)
disp(vec(i))
Logical errors are more difficult to locate because they do not result in any error
message.A logical error isa mistake inreasoning by the programmer, but it is not
a mistake in the programming language. An example ofa logical error would be
dividing by 2.54 instead of multiplying to convert inches to centimeters. The
results printed or returned would be incorrect, but this might not be obvious.
All programs should be robust and should wherever possible anticipate poten-
tial errors, and guard against them. For example, whenever there is an input
intoa program, the program should error-check and make sure that the input
is in the correct range of values. Also, before dividing, any denominator should
be checked to make sure that it is not zero.
Despite the best precautions, there are bound tobe errors in programs.
6.5.2 Tracing
Many times, whena program has loops and/or selection statements and is not
running properly, it is useful in the debugging process to know exactly which
statements have been executed. For example, the following isa function that
attempts to display “In middle of range” if the argument passed to it is in
the range from3 to G, and “Out of range” otherwise.
testifelse.m
function testifelse(x)
%testifelsewilltestthedebugger
%Format: testifelse(Number)
if3 Sxe 6
disp('Inmiddleof range')
else
disp('Out of range')
end
end
215 CHAPTER 6: NATLAB Programs
>> testifelse 77
Inmiddleofrange
>> testife1se{-27
Inmiddleofrange
Onewayoffollowing the flow of the function or tracing it, is to use the echo
function. The echo function, which isa toggle, will display every statement as it
is executed as well as results from thecode. For scripts, just echo can be typed,
but for functions, the name ofthefunction must be specified. For example, the
general form is
echo functionnameon/off
We canseefrom this result that the action of the if clause was executed.
6.5.3 Editor/Debugger
MATLAB hasmany useful functions for debugging, and debugging can also be
done through its Editor, which is more properly called the Editor/Debugger.
Typing help debug attheprompt intheCommand Window will show some of
the debugging functions. Also, in the Help Documentation, typing
“debugging” in the Search Documentation will display basic information
about the debugging processes.
It can be seen intheprevious example that the action of the ifclause was executed
and itprinted “In middle ofrange,” but justfromthatitcannotbe determined why
this happened. There areseveral waystosetbreaitpoints ina file (script or function)
so that the variables or expressions can be examined. These can be done from the
Editor/Debugger or commands canbe typed from theCommand Window. For
example, the following dbstop command will seta breakpoint in the sixth line
of this function (which is the action of the ifclause), which allows the values of
variables and/or expressions to be examined atthat point in the execution. The
function dbcont can be used to continue the execution and dbquit can be used
to quit the debug mode. Note that the prompt becomes Km > indebug mode.
ó.
5 D e buggin g Te ch n iq ue s
-2
K>> 3<x
ans=
0
K>> 3<x<6
ans=
K>>dbcont
Inmiddleofrange
end
By typing the expressions3 < x and then3 <x < G, we can determine that the
expression3 <x will return either0 or 1. Both0 and1 areless than 6, so the
expression will always be true regardless of the value of x! Once inthedebug
mode, instead of using dbcont tocontinue the execution, dbstep can be used to
step through the rest of the code one line ata time.
Breakpoints can also be setand cleared through the Editor. Whena file is open in
theEditor, in between theline numbers on theleft and the lines of code isa thin
gray strip which is the breakpoint alley. In this, there are underscore marks next to
the executable lines of code (asopposed tocomments, forexample). Clicking the
mouse inthealley next toa line will createa breakpoint at that line (and then
clicking on the red dot that indicatesa breakpoint will clear it).
PRACTICE 6.7
The following script is bad code in several ways. Use checkcode first to check it for potential prob-
lems and then use the techniques described in this section to set breakpoints and check values of
variables.
debugthis.m
fori = 1:5
i = 3;
disp(i)
end
forj =2 :4
vec (j) =j
end
C HAPTER 6: NATLAB Programs
[x,y] =getvals;
z = calcz(x,y);
printall(x,y,z)
Thethree functions have notyetbeen written however, so function stubs are put
inplace so thatthe script can be executed and tested. The function stubs consist of
the proper function headers, followed bya simulation of what thefunction will
eventually do. For example, the first two functions put arbitrary values in forthe
output arguments and the last function prints.
getvals.m
function [x,y) =getvals
x = 33;
end
calcz.m
function z= calcz(x,y)
Z = X + /,
end
printall.m
functionprintall(x,y,z)
disp(x)
disp(y)
disp(z)
end
Then, the functions can be written and debugged one ata time. It is much easier
to writea working program using this method than to attempt to write every-
thing atonce—then, when errors occur, it is not always easy to determine where
theproblem is!
ó.ó L ive S c ri pt s, C o d e C e lls, a nd P u b lis hin g C o d e
new open save “ *””’°" ’='° ^” ’°^" code Text sectton "’""" ’>’'"" Run
Aii eun
Let's createa vector x, and then show thedifference between seyeral tunc1ions of x. First,
FIGURE 6.1
TheLive Editor.
C HA PT E R 6 : NATLAB Programs
new open save C°""°re " '° ‘ '" co de Texr section “ "’”"" "" ”“' bun
Aii run
• • • @ Print Break Image Section ••
FIGURE 6.2
"Run current section" from Live Editor.
All of the code from thelive script can be executed by choosing the Run Allbut-
ton. Alternatively, individual sections can be executed by clicking on the bar to
the left of the section as seen in Fig. G.2.
Oncea live script has been completed, it can be shared with others as an.mlx file,
or it can be converted toa PDF or HTML format. To do this, click on the down
arrow under "Save," and then either "Export to PDF" or"Export to HTML."
Live scripts can also be converted to code files with the .m extension by choos-
ing Save As and then choosing MATLAB Code file from thedrop down menu
fortheFormat.
Using thetype command ona live script will show just the code sections. The
entire contents of the .mlx file can be seen from theLive Editor.
>> typeszntest.m2x
x = -pi:0.01:pi;
y=x.’2.*sin(x),
plot(x,y, 'r*')
y=sin(x);
plot(x,y, 'bo')
PRACTICE 6.8
If you have R2016a or later, try creatinga five script with text, equ ations, and code top roduce at
least one p lot.
To break code into cells, create comment lines that begin with two % symbols;
these become thecell titles. For example,a script from Chapter3 that plots sin
and cos has been modified to have two cells: one that creates vectors for
sin(x) and cos(x) and plots them; anda second that addsa legend, title, and
axis labels to the plot.
sinncosCells.m
%Thisscriptplots sin(x) andcos(x) in the sameFigure
%Window forvalues ofx ranging from0 to 2pi
%%Create vectorsandplot
clf
x = 0: 2*pi/40: 2*pi;
y=sin(x);
plot(x,y, 'ro')
holdon
When viewing this script in the Editor, the individual cells can be chosen by
clicking the mouse anywhere within the cell. This will highlight the cell with
a background color. Then from the Editor tab, you can choose "Run
Section" to run just that one code cell and remain within that cell, or
you can choose "Run and Advance" to run that code cell and then advance
to the next.
By choosing the "Publish" tab and then "Publish," the code is published by
default in HTML document. For the plotl ptCells script, this createsa docu-
ment inwhich there isa table of contents (consisting of the two cell titles),
the first code block which plots, followed by the actual plot, and then the
second code block that annotates the Figure Window, followed by the mod-
ified plot.
Explore the use of the functions mlock and munlock toblock functions
from being cleared using clear.
It is also possible to create code cells in functions. Investigate this. ■
SUMMARY
COMMON PITFALLS
• Not matching up arguments ina function call with the input arguments
ina function header.
• Not having enough variables in an assignment statement to store all of
the values returned bya function through the output arguments.
• Attempting to calla function that does not returna value from an
assignment statement, or from an output statement.
• Not using the same name forthefunction and the file in which it
is stored.
• Not thoroughly testing functions for all possible inputs and outputs.
• Forgetting that persistent variables are updated every time thefunction in
which they are declared is called—whether froma script or from the
Command Window.
global persistent
Exercises
1 Given the following function header:
function [x,y] = calcem(a, b, c)
and seconds (DMS] form just like time. For example, 2¢.5° is equivalent to 2¢°
30’0". Writea script that will prompt the user foran angle in DD form and
will print in sentence format the same angle in DMS form. The script should
error-check forinvalid user in put. The angle conversion is to be done by calling
a separate function from the script.
6 Given the following function header:
function doit(a, b)
doit(S, 2, 11.11)
x= 11,
y= 3.3,
doit(x,y)
Writea function that prints the area and circumference ofa circle fora
given radius. Only the radius is passed to the function. The function
does not return any values. The area is given by x and the circumference
is 2ar.
8 Writea function that will receive an integern and a character as input argu-
ments and will print the charactern times.
9 Writea function that receivesa matrix as an in put argument and printsa
random row from the matrix.
10. Writea function that receivesa count as an input argument and prints the value
of the count ina sentence that would read ‘It happened1 time." if the value of the
count is 1. or ‘It happened xx times.“ if the value of count (xx] is greater than 1.
11. Writea function that receives anx vector,a minimum value, and a
maximum value. and plots sinlx) from the specified minimum tothespecified
maximum.
12. Writea function that prompts the user fora value of an integern and returns
the value of n. No input arguments are passed to this function. Error-check
to make sure that an integer is entered.
13. Writea script that will:
Calla function to prompt the user foran angle in degrees
Calla function to calculate and return the angle in radians. (Note: x
radians= 180°I
Calla function to print the result
Write all of the functions, also. Note that the solution to this problem involves
four code files: one which acts asa main program (the script], and three for
the functions.
1L. Modify the program in Exercise 13 so that the function to calculate the angle isa
subfunction to the function that prints.
Prog rammi ng StyleG u i del i nes 219
[x,y,z] =getcartesian(),
printspherical(x,y,z)
getcartesian.m
1 ó. The lump sumS tobe paid when interest ona loan is compounded annually is
given by S= P(1+/]" whereP is the principal invested,i is the interest rate, and n
is the number ofyears. Writea program that will plot the amountS as it
increases through the years from1 to n. The main script will calla function to
prompt theuser forthe number ofyears (and error-check to make sure that the
u ser entersa positive integer]. The script will th en calla function that will plotS
for years1 through n. It will use 0.05 for the interest rate and $10,000 for P.
17. Writea program towritea length conversion chart toa file. It will print lengths
in feet from1 to an integer specified by theu ser, in one column and thecor-
responding length in meters (1 foot= 0.30¢8 ml ina second column. The main
script will call one function that prompts theu ser forthe maximum length in
feet: this function must error-check to make sure that the user entersa valid
positive integer. The script then callsa function to write the lengths toa file.
18. The script circscript loopsn times toprompt theuser forthe circumference ofa
circle (wheren isa random integer]. Error-checking is ignored to focus on
functions in this program. For each, it calls one function to calculate the radius
and area of that circle, and then calls another function to print the se values.
The formulas are r= c/(2xI and a = x/ wherer is the radius,c is the circum-
ference, and a is the area. Write the two functions.
CHAPTER 6: NATLAB Programs
circscript.m
n= randi(4);
fori = 1:n
circ= input('Enter thecircumferenceofthecircle: );
[rad, area) = radarea(circ);
dispra(rad,area)
end
19 The distance between any two points (x/,y/] and (x2,y2)iS given by:
area s ) b) c)
where a, b, and c are the Ie ngths of the sides of the triang ie, and s is equal
to half the sum of the lengths of the three sides of the triang ie. Writea
script that will prompt the user to enter the coordinates of three points that
determine a triang Ie (e.g., the x and y coordinates of each pointl. The
script will then calculate and pri nt the area of the triang ie. It will call
one function to calculate the area of the triang ie. This function will calla
subfunction that calculates the length of the side formed by any two points
(the distance between them].
20 Writea program towritea temperature conversion chart toa file. The main
script will:
calla function that explains what the program will do
calla function to prompt the user forthe minimum and maximum tem-
peratures in degrees Fahrenheit and return both values. This function
checks to make sure that the minimum is less than the maximum andcalls
a subfunction to swap thevalues if not.
calla function to write temperatures toa file: the temperature in degrees
F from the minimum tothemaximum in one column and the
corresponding temperature in degreesC in another colum n. The conversion
isC (F— 321 x 5/9.
2 1 Modify the function func2 from Section 6.¢.1 that hasa persistent variable count.
Instead of having the function print the value of count, the value should be
returned.
22 Writea function per2 that receives one number as an in put argument. The
function hasa persistent variable that sums thevalues passed to it. Here are
the first two times the function is called:
> > p ec2 (4}
ans =
4
Programming StyleG u ideli nes
answer = 5;
fprintf('Answer is %d\n',answer)
pracfn
pracfn
fprintf('Answer is %d\n',answer)
printstuff
fprintf('Answer is %d\n',answer)
pracfn.m
functionpracfn
persistentcount
if isempty(count)
count= 0;
end
count = count+ 1;
fprintf('This functionhas been called %dtimes.\n',count)
end
printstuff.m
functionprintstuff
answer = 33;
fprintf('Answer is %d\n',answer)
pracfn
fprintf('Answer is %d\n',answer)
end
26 The braking distance ofa car depends on its speed as the brakes are applied
and on the car's braking efficiency.A formula forthe braking distance is
2
d
* ' 2 Rg
wherebd is the braking distance,s is the car's speed,R is the braking efficiency,
and g is the acceleration due to gravity (9.81 j.A script has been written that calls
a function to prompt theuser fors and P, calls another function to calculate the
braking distance and callsa third function to print the braking distance ina
sentence format with one decimal place. You are to writea function stub forthe
function that prompts fors andP and the actual function definitions for the
other two functions.
[s, R] =promptSandR,
brakDist= calcbd(s, R),
printbd(brakDist)
1 1
= ¢ arctan 5 — arctan
3›
P rog ra m m in g StyleG u i de lin e s 233
This is calleda sum ofa series. There are six terms shown in this series. The
first term is ¢, the second term is —¢/3, the third term is ¢/5, and so forth. For
example, the menu-driven program might have the following options:
Print the result from Machin's formula.
Print the approximation using Leibniz” formula, allowing the user to specify
how many terms to use.
Print the approximation using Leibniz’ formula, looping untila “good”
approximation is found.
Exit the program.
29 Writea program tocalculate the position ofa projectile ata given time /. For an
initial velocity and angle of departure8s. theposition is given byx andy
coordinates as follows (note: the gravity constantg is 9.81 m/s2I:
x= vo cos(8o)!
y = vo sin(8o)f— 2gt2
The program should initialize the variables for the initial velocity, time, and
ang le of departure. It should then calla function to find thex and y coordinates
and then another function to print the results. If you have version R201 óa or
later, make thescript intoa live script.
This page intentionally left blank