(++) Denotes an advanced topic for self-study
NOTE
All of the course .m
files are installed in ~phys210/matlab
so
provided that your Matlab path is set up properly, you should be able
execute any of them from your Matlab command window. You can also
view the definition of any of them from within the command window
using the type
command. as described below.
NOTE
help
command>> help <topic>
Example
>> help linspace
LINSPACE Linearly spaced vector.
LINSPACE(X1, X2) generates a row vector of 100 linearly
equally spaced points between X1 and X2.
LINSPACE(X1, X2, N) generates N points between X1 and X2.
For N = 1, LINSPACE returns X2.
.
.
.
doc
command>> doc <topic>
This command will bring up the desktop help
facility, positioned
at the section for <topic>
.
lookfor
command>> lookfor <keyword>
The lookfor
command returns a list of functions (including those that
the user has defined), and their synopses, that have something to do
with <keyword>
Example
>> lookfor vector
.
.
.
detrend - Remove a linear trend from a vector ...
issorted - TRUE for sorted vector and matrices.
iscolumn - True if input is a column vector.
isrow - True if input is a row vector.
isvector - True if input is a vector.
.
.
.
which
command: Display full pathname to script/functionUse which
to display the full pathname to any script or function
defined in a .m
file in your Matlab file.
Example
>> which tplot
/home/phys210/matlab/tplot.m
Since Matlab does not have a required statement terminator, it provides a mechanism to extend a statement across multiple lines.
To continue any Matlab statement on the next line, end the current line with an ellipsis:
...
i.e. three consecutive periods with no intervening whitespace.
Example
>> a = [[1, 2, 3, 4, 5, 6, 7]; ...
[8, 9, 10, 11, 12, 13, 14]; ...
[16, 17, 18, 19, 20, 21, 22]]
a =
1 2 3 4 5 6 7
8 9 10 11 12 13 14
16 17 18 19 20 21 22
If you need to define a long string and want to continue the definition across multiple lines, use string concatenation whose syntax is illustrated in the following example
>> longstr = ['String concatenation is accomplished by entering ', ...
'text as if you were defining a row vector of strings.']
String concatenation is accomplished by entering text as if you were defining a row vector of strings.
There is a very useful feature in kate
and gedit
(and many other text
editors), known as syntax highlighting, in which text that defines
a program (or function, script, ...) is automatically color-coded
according to the syntax of the language being used. For example,
when syntax highlighting is enabled, keywords such as function
, if
, end
,
etc. will appear in a
distinct color. This auto-coloring generally makes it easier to write
syntactically correct programs.
Let's enable syntax highlighting in your editor of choice, if it isn't already enabled.
First, open a terminal window and change to your Matlab directory
% cdm
% pwd
Then edit the file q1.m
that you created for the first quiz:
% kate q1.m &
or
% gedit q1.m %
The proceed as follows:
kate
From the top menu bar select:
Tools -> Highlighting -> Scientific -> Matlab
gedit
From the top menu bar select:
View -> Highlight Mode ...
In the window that pops up select octave
.
You may encounter the following messages if you mistype statements and/or refer to quantities that are not defined.
Undefined quantities
>> whatmeworry
Undefined function or variable 'whatmeworry'.
Typo that Matlab interprets as a command/function invocation
>> xx = 32
>> yy = 16
% Typo ... meant to type 'xx-yy' or 'xx - yy'
>> xx -yy
Error: "xx" was previously used as a variable, conflicting with
its use here as the name of a function or command.
Combination of 1 and 2
>> zz cc
Undefined function 'zz' for input arguments of type 'char'.
octave
usersThese notes and sample codes have been written to ensure maximum portability/compatibility between Matlab and octave.
However, there are syntactic differences between the two that you may encounter when looking, for example, at on-line documentation for either of the languages
One example is that Matlab uses end
to terminate many programming
constructs (function definitions, if-then-else statements,
loops, etc.). octave also supports this syntax, but has additional
reserved words (such as endfunction, endif, ...) that improve
code readability.
Do not use octave's extensions if you want to preserve compatibility with Matlab.
As with Maple, Matlab has support for both
Schematically, here are some key features of these two approaches to programming in Matlab on which we will focus:
Data and Algorithms
Data
Algorithms
if
for
, while
Other important language elements for scientific programming
As we have already discussed we will consider two distinct types
of Matlab code, both of which must be defined in .m
files:
M scripts (programs)
M functions
We will adopt the convention that every Matlab function that
we write will be coded in a separate .m
file.
So, if as part of the Matlab homework assignment I ask you to write three separate Matlab functions with names
foo
woof
myfcn
then you will create three separate text files
foo.m
woof.m
myfcn.m
which will contain the definitions of the respective functions.
Again, provided that the source files live in a directory in you Matlab path, or in the Matlab's working directory (e.g. you started Matlab from the bash command line in the directory containing the files), then you will simply have to type
>> foo(<arguments-to-foo>)
>> woof(<arguments-to-woof>)
>> myfcn(<arguments-to-myfcn>)
For example, assume that foo
expects two arguments. If we
type
>> foo(2,3)
then Matlab does the following
foo
. It needs to do so since:
foo
with two
integer-valued arguments is the same as that for indexing a
2D array foo
foo
, Matlab then
checks the Matlab path, always starting with the working directory
until it finds a file called foo.m
. Note that in the last point I've use the language: "Provided that
the file defines a function of two arguments ..." purposely.
That is, I did not say "Provided that the file defines the function
named foo
and that foo
takes two arguments ...".
That's because there's a little Matlab weirdness here that I would rather not have to tell you about. However, in the interest of full disclosure, here goes.
.m
file IS the name of the Matlab functionAs we have seen in the overview of Matlab programming, and assuming
for the sake of exposition that foo
returns a single value we
would define it using a header statement like:
function x = foo(a, b)
thus giving the function the name foo
. Now, the subtlety is that
if this is the only function defined in foo.m
(and we will adopt
the programming practice that every function we write will be
defined in its own .m
files and, conversely, that no .m
file
will contain the definition of more than one function),
then Matlab doesn't care what name we use in the header statement.
As far it is concerned, since we've defined the function in the file
foo.m
then whenever we use foo
in a Matlab statement it will
execute the function in that file, with the supplied arguments, and
hand back the value to the invoking environment.
To see an example of this, let us first note that there is a very
useful command in Matlab called type
with basic syntax
>> type <function-name>
which will display the definition of a Matlab function (so it is
analogous to op(<procedure-name)
in Maple. Try the following
>> type foo
function x = Bruce(a, b)
x = a + b;
fprintf('I think my name is Bruce and I will return the value %d\n', a + b);
end
>> type woof
function x = Bruce(a, b)
x = a - b;
fprintf('I think my name is Bruce and I will return the value %d\n', a - b);
end
As you can verify by looking in the contents of
~phys210/matlab
the files foo.m
and woof.m
do contain the definitions we see when
we issue the type
commands.
So one would think that I've defined (or redefined) two functions
named Bruce
. Certainly if I did the analogous thing in Maple, the
second definition would obliterate the first.
Now, if we try to invoke Bruce, we find ...
>> Bruce(1,1)
Undefined function 'Bruce' for input arguments of type 'double'
... which is reasonable, since there isn't a file Bruce.m
in the
Matlab path. On the other hand, however, both foo
and woof
"work" ...
>> foo(2,3)
I think my name is Bruce and I will return the value 5
ans =
5
>> woof(2,3)
I think my name is Bruce and I will return the value -1
ans =
-1
If this seems a bit wacky to you, well, I totally agree with you and
I'm more than a bit mystified as to why the Matlab implementers made
this particular design decision, but they did. When a single function
is defined in a file <stem>.m
, Matlab totally ignores the actual name we
use in the function statement and simply asserts that the file contains
the definition of the function <stem>
.
So that's the full disclosure bit. Needless to say, we're not going
to use the name Bruce
in all of the function statements that we write,
even though we could. Rather we are going to do the rational thing
and always use the same name for the function that we use for the name
of the .m
file.
And the fact that it's taken me so long to describe this subtlety is why
I hesitated to tell you about it in the first place. However, chances
are that one or more of you will define a function in the right .m
file
but with the "wrong" name in the function statement, and will notice
that it works---and then I'd be caught!
Note that this a different approach than we followed in our Maple programming where we frequently put the definitions of multiple procedures in a single file.
By all means experiment with M interactively, but
Prepare all scripts/functions in text files using your text editor
Keep the editor window open while you test your scripts/fcns, so that you can quickly make changes as needed, and reexecute without stopping/starting the editor
IMPORTANT
For functions, always code a testing script (driver) at the same time or better, before, you code the function!
For example, while coding the definition of somefcn(arg1,arg2)
in
the source file somefcn.m
, code a script file tsomefcn.m
that
has sample calls to the function:
somefcn(<somefcn-args-1>)
somefcn(<somefcn-args-2>)
.
.
.
As we have discussed, we will view a Matlab script as a "main program", i.e. the part of the code that executes at the highest level, typically without user intervention, to accomplish some overall task. If will typically not return one or more values to the invoking environment.
Your solutions to the lab quizzes are simple scripts, and the Matlab homework and especially your term projects will require you to write scripts that are much more akin to the typical "main programs" that one encounters in "real life" scientific computing (and programming in general).
There's not much else to say about scripts at this point ... we just have to write some!
Recall that the overview slides PDF cover some of this material.
type
commandAs mentioned above, we can display the definition of Matlab functions
or scripts using the type
command
Syntax
type <script-or-function-name>
Example
>> type greetings
function [] = greetings()
fprintf('Greetings, user %s!\n',getenv('LOGNAME'));
end
The name of this command can/will cause confusion when I'm coaching
you, and suggesting that you look at the definition of a function,
since its name of course refers to what you are generically
doing when sitting in front of a keyboard. So I will try to
say things like "Enter the command type thist
" rather than
simply "Try type thist
" but am apt to forget from time to time!
A Matlab function can have an arbitrary number 0, 1, 2, 3, ... of input arguments, or formal parameters, each of which can be a scalar, vector, matrix, higher dimensional array, ...
A Matlab function can have an arbitrary number 0, 1, 2 ... of output arguments, or return values, and each output can be a scalar, vector, scalar, vector, matrix, higher dimensional array, ...
Adopt usual "meta" notation:
<ss> denotes arbitrary sequence of M statements/commands.
Generally will have one statement per
line, but can have more using either ,
or ;
to separate
statements (;
suppresses output)
<inarg> = "input argument" (formal argument)
<outarg> = "output argument" (may sometimes call "return value")
function <name>(<inarg1>, <inarg2>, ..., <inargm>)
<ss>
end
function <outarg> = <name>(<inarg1>, <inarg2>, ..., <inargm>)
<ss>
end
function [ <outarg1>, <outarg2> ] = <name>(<inarg1>, <inarg2>, ..., <inargm>)
<ss>
end
function [ <outarg1>, <outarg2>, ... <outargn> ] = <name>(<inarg1>, <inarg2>, ..., <inargm>)
<ss>
end
NOTES
For all of the above forms, there can be 0 or more input arguments,
<inarg_i>
All of the inargs and outargs must be valid Matlab variable names
Commas are not required between the outargs but can be included, and the recommended coding style is to include them
If there are two or more outargs, they must be enclosed in
square brackets [ ]
.
Commas are required between inargs
All outargs must be assigned a value before the function returns (i.e. reverts control to the invoking environment). This can happen in one of two ways
return
statement is executed (explicit return); this is discussed below.CRUCIAL
Assignment of the outargs is the mechanism by which all Matlab functions return values
If there are multiple outargs, then to "capture" all of them upon return from the function, the function invocation must be on the RHS of an assignment statement with a row vector of names on the LHS, e.g.
[out1, out2] = fcn2(in1, in2)
otherwise only the first outarg is returned.
CODING STYLE: Use of statement terminators
Will usually want to end each statement in <ss>
(i.e. in the
body of the function) with a ;
so that output doesn't appear in
the command window as the function executes.
However, removing the ;
from selected lines provides a
quick/convenient way of enabling tracing of that statement for,
e.g., the purposes of debugging
IMPORTANT
In the final form of the code that you will submit for the Matlab homework and your term project, a
;
terminator will be required at the end of each statement unless otherwise specified. That is, the scripts and functions can not display any output on the screen when they are run other than that which is requested (or in the case of your term projects, deemed essential).
IMPORTANT
See the notes HERE for a detailed description of how Matlab functions return values.
It is crucial that you understand how the value-return mechanism works, particularly since it is different from how Maple operates, and some of you will confuse the two at first.
myadd
Description
myadd
takes two scalar inargs,sc1
andsc2
, and returns one scalar outarg having the valuesc1 + sc2
Implementation
Create a file /phys210/$LOGNAME/matlab/myadd.m
that
contains the following 3 lines
function res = myadd(sc1, sc2)
res = sc1 + sc2;
end
Be sure to end each line in the function definition with a ;
to
suppress the output that normally would be generated - in this case
there is only one such line
Also note the use of indentation to show which statements are contained within the body of the function.
Start up a Matlab session if you don't have one running.
In Matlab, type
>> myadd(2,3)
and you should see
ans =
5
Note how in the definition of the function we assign the outarg
res
the value sc1 + sc2
, and since res
is defined to be the (single)
inarg in the function header, this is the value that is returned
from the function call.
We can assign myadd's return value to a variable as follows
>> val = myadd(3.0, pi)
val =
6.1416
IMPORTANT
To reiterate the point made above, note that we will adhere to the following protocol:
When defining Matlab functions we will
Define only ONE function per source file (.m
file)
Ensure that the name of the function and the name of the file match, e.g.
myadd.m contains the definition of myadd
foo.m contains the definition of foo
.
.
.
If you do not follow this protocol---in particular if you include more than one function definition per file---then Matlab will not be able to find all of the necessary functions, and error messages will be issued.
For example, let's assume that myadd.m
contains an extra definition
for a function mysub as follows
function res = myadd(sc1, sc2)
res = sc1 + sc2;
end
function res = mysub(sc1, sc2)
res = sc1 - sc2;
end
Invoking myadd
still works
>> myadd(3.0,pi)
ans = 6.1416
But calling mysub
doesn't --- instead, an error message appears
>> mysub(3,2)
Undefined function 'mysub' for input arguments of type 'double'.
QUESTION
Where should the definition of mysub go?
myaddsub
Description
myaddsub
takes two scalar inargs,sc1
andsc2
, and returns TWO scalar outargs with values,sc1 + sc2
,sc1 - sc2
Implementation
In your Matlab directory create a file myaddsub.m
containing the 4 lines
function [res1, res2] = myaddsub(sc1, sc2)
res1 = sc1 + sc2;
res2 = sc1 - sc2;
end
IMPORTANT
Note the [ ]
enclosing the two output arguments, res1
and res2
Now use the function in Matlab.
First try
>> myaddsub(2, 3)
ans = 5
Note how only a single value is returned.
Now try
>> [val1, val2] = myaddsub(2,3)
val1 = 5
val2 = -1
and we see that two values are returned and assigned to the variables
val1
and val2
.
Again, note that in the definition of the function we must assign values to the outargs in order for the function to return the desired results.
myvec
Description
myvec
takes one integer inargi1
and returns two row vectors,1:i1
andi1:-1:1
(i1
should be >= 1, but we won't test for that)
Implementation
Create the file myvec.m
containing
function [vec1, vec2] = myvec(i1)
vec1 = [1:i1];
vec2 = [i1:-1:1];
end
Now use the function, and be sure to use an assignment statement that has a vector with two names on the left hand side to ensure that we capture both of the output arguments (each of which is a vector)
>> [v1, v2] = myvec(5)
The output should be
v1 =
1 2 3 4 5
v2 =
5 4 3 2 1
Here we see what again happens if we try to call a function that hasn't
been defined in the file <fcn>.m
, where <fcn>
is the name of the function.
>> myvce(5)
Undefined function 'myvce' for input arguments of type 'double'.
Use the Matlab type
command to display the definition of a function
First, try it for a user-defined function
>> type myadd
function res = myadd(sc1, sc2)
res = sc1 + sc2;
end
While for a built-in function, we will see ...
>> type length
'length' is a built-in function.
Working in your Matlab directory, create and test functions as follows (you can do the testing interactively).
NOTE THE FOLLOWING
myadd3
Define in myadd3.m
in your Matlab directory.
Description
myadd3
takes 3 inargs (input args), x, y and z and returns their sum (one value)
Example invocation
>> myadd3(3, 5, 9)
myop4
Define in myop4.m
Description
myop4
takes 4 inargs (you choose the names!) and returns their sum and product (two values)
Example invocation
>> [val1, val2] = myop4(10, 4, 8, 16)
Note that when you test this function, you should be careful to assign the return values to a two-element vector of variable names as shown above to ensure that both outargs are being computed properly.
myarray2
Define in myarray2.m
Description
myarray2
takes 2 input args,m
andn
, and returns two values:1) A uniformly spaced row vector of length 10, with first element =
m
, last element =n
2) A uniformly spaced column vector of length 10, with first element =
n
, last element =m
Example invocation
>> [vr, vc] = myarray2(10, 20)
error
functionMatlab has a built-in function error
that, in its basic
form, operates essentially identically to the Maple version.
Syntax
error(<diagnostic_string>)
As is the case in Maple, if this function is executed within a function,
the message is printed and the function exits immediately and does not return
any values. However, in contrast to Maple, invocation of error
also causes
the entire program that is executing to stop. This has implications for
function-testing. If we use error
to detect various error conditions
in a function and then code a script to test the error checking, then we
can only test one invalid call at a time. E.g. if the script is coded to
have a sequence of calls with erroneous input, such as
somefcn(invalid1)
somefcn(invalid2)
somefcn(invalid3)
and somefcn
calls error
in all three cases, then execution of the script
will always stop after the first call. One workaround is then to use
"commenting out" to test the calls sequentially, i.e. run the script
with
somefcn(invalid1)
%somefcn(invalid2)
%somefcn(invalid3)
then
%somefcn(invalid1)
somefcn(invalid2)
%somefcn(invalid3)
then
%somefcn(invalid1)
%somefcn(invalid2)
somefcn(invalid3)
NOTE
We can use all of the control structures interactively, and will do so below.
However we will almost always in the context of programming per se, i.e. when coding scripts and functions.
In contrast to Maple, which has a special Boolean type (true and false), Matlab follows the C-language approach of
Returning the integers:
0 for false
1 for true
when evaluating relational or logical expressions
Treating the value 0 (integer OR floating point) as false, and any non-zero value as true in contexts where relational/logical expressions are expected (e.g. if statements)
That is, although 0 is the unique "false value", and although comparisons and logical operations will always return 0 or 1, there is no unique "true value"
Among other things this means that
Results from relational and logical operations can be used in arithmetic statements (which can be sometimes be useful, but should be considered (++))
Arbitrary statements that return a scalar value can be used where relational/logical expressions are expected (++)
Operator Definition
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
== Equal
~= Not equal
Note the use of "tilde-equal" for not equal versus
<>
in Maple and !=
in C/C++ and others.
These work in the usual fashion for scalars, but we need to be careful when arrays are compared (++)
Examples
>> a = 1; b = 2; c = 3;
>> a < 3
ans = 1
>> b > c
ans = 0
>> a == c
ans = 0
>> b ~= c
ans = 1
Example (++)
>> 32 * (a < 3) + 16 * (b == c) + 8 * (a == a)
ans = 40
Operator Definition
& Logical AND
| Logical OR
~ Logical NOT
Note that these are single character expressions, NOT 'and', 'or' and 'not' as in maple
Examples
>> a = 1; b = 2; c = 3;
>> (a < b) & (b < c)
ans = 1
>> (a == 2) | (a == 3)
ans = 0
>> ~(a < b)
ans = 0
(++)
>> ~30
ans = 0
>> ~~30
ans = 1
NOTES
There is a precedence order for all of the arithmetic and logical operators, but, as was the case for Maple, it is best to simply use parentheses to ensure you get the order you want.
As mentioned in the introduction to Matlab programming slides, there
are also "short-circuit" forms of the and and or operator, &&
and ||
,
respectively. I will try to avoid their use in my code, and I recommend
that you do so as well.
DEFINITIONS
<Bexpr> = Boolean expression (should be a scalar), also known
as a conditional expression
<ss> = Statement sequence
GENERAL FORM
if <Bexpr1>
<ss>
elseif <Bexpr2>
<ss>
elseif <Bexpr3>
<ss>
.
.
.
else
<ss>
end
NOTES
DON'T use then
after the if
in Matlab, i.e. there is no then
in Matlab
Use elseif
, not elif
(as in Maple).
There can be an arbitrary number of elseif
clauses (0 or more).
The else
clause is optional.
The if
statement is terminated with end
(M uses end to terminate
most control structures as well as function definitions).
Examples
Again, we will type these statements interactively to demonstrate their use but in practice they will most often be used in scripts and functions.
Simplest form
>> a = 2; b = 3;
>> if a < b
a + b
end
ans = 5
Next simplest form
>> a = 2; b = 3;
>> if a == b
a + b
else
a - b
end
ans = -1
Form using elseif
>> aa = 2;
>> if aa == 1
10
elseif aa == 2
20
else
30
end
ans = 20
Note that Matlab also has a case
statement (++)
for
statementDEFINITIONS
<lvar> = loop variable
<vector-expression> = expression that defines ROW vector
<ss> = statement sequence
GENERAL FORM
for <lvar> = <vector-expression>
<ss>
end
For loop: TYPE 1
<vector-expression>
generated using colon notation:
<first> = first value of <lvar>
<step> = lvar increment (step)
<last> = last value of <lvar>
for <lvar> = <first> : <step> : <last>
<ss>
end
or, if the loop variable increment is 1
for <lvar> = <first> : <last>
<ss>
end
As the loop executes, <lvar>
takes on the values
<first>, <first> + <step>, <first> + 2 * <step>, ...
and where the last value of <lvar>
is always <= <last>
<first>, <step>, <last>
don't have to be integers, but usually will
want them to be to avoid possible problems with roundoff errors
Examples
>> for k = 1 : 3
k
end
k = 1
k = 2
k = 3
>> for k = 4 : -1 : 2
k
end
k = 4
k = 3
k = 2
>> for k = 1 : 4 : 14
k
end
k = 1
k = 5
k = 9
k = 13
>> for k = 2 : 2
k
end
k = 2
>> for k = 2 : 1
k
end
Note that there was is no output in the last example.
For loop: TYPE 2
<vector-expression>
created using any other command/expression that
defines/returns a row vector
for <lvar> = <vector-expression>
<ss>
end
Examples
>> for k = [1 7 13 sqrt(2)]
k
end
k = 1
k = 7
k = 13
k = 1.4142
>> for a = linspace(2.0, 3.0, 6)
a
end
a = 2.2000
a = 2.4000
a = 2.6000
a = 2.8000
a = 3
Note what happens if we use a column vector as <vector-expression>
...
>> for a = linspace(2.0, 3.0, 6)'
a
end
a =
2.0000
2.2000
2.4000
2.6000
2.8000
3.0000
... i.e. the body of the loop is only executed once, and during that
single pass, the loop value a
is assigned
the entire vector.
IMPORTANT!
DO NOT modify the loop variable within a for loop.
Unlike some other programming languages, in Matlab you can do this without generating a syntax or run-time error, but the results are unlikely to be what you expect/want.
BE VERY CAREFUL ABOUT THIS POINT!
while
statement (++)DEFINITIONS
<Bexpr> = Boolean / conditional expression
<ss> = statement sequence
GENERAL FORM
while <Bexpr>
<ss>
end
NOTE
The while loop executes until <Bexpr>
evaluates to 0 (false). If
<Bexpr>
is 0 upon initial entry to the loop, the body of
the loop does NOT execute.
In other words, while <Bexpr>
is true the looping continues.
It is up to the programmer (i.e. you) to do something within the
loop so that, eventually, <Bexpr>
evaluates to 0 (false), or your
program will be stuck in the proverbial "infinite loop"
Example
>> q = 1
while q <= 16
q = 2 * q
end
q = 2
q = 4
q = 8
q = 16
q = 32
Note how the last assignment is 'q = 32'; this is because the test that determines whether the loop continues or not is 'q <= 16', Thus when q is assigned the value 16, the test still succeeds at the next iteration, so the last statement executed in the loop is q = 2 * 16
All of the above loops can be nested, i.e. we can have loops within loops
Example
>> for ii = 1 : 2
for jj = 3 : -1 : 1
[ii jj]
end
end
ans =
1 3
ans =
1 2
ans =
1 1
ans =
2 3
ans =
2 2
ans =
2 1
Note that the inner loop (loop variable jj) executes "most rapidly"; for each iteration through the outer loop, ii = 1 , 2 in succession, the inner loop executes, jj = 3, 2, 1 in succession
break
statement (++)break
causes an immediate exit from the (innermost) loop where it is
executed
Example (contrived!)
>> q = 1
while q <= 16
q = 2 * q
if q > 3
break
end
end
q = 2
q = 4
NOTE
If a break
statement is encountered outside of any loop in a script
or function, it terminates the execution of the file.
continue
statement (++)continue
is used within a loop to "short circuit" the execution of the
loop body, and proceed to the next iteration
Example
(the M rem command is equivalent to mod in Maple, so rem(n,2) = 0 or 1 for n even or odd, respectively)
>> for ii = 1:5
jj = ii
if rem(ii,2) == 0
continue
end
jj = -ii
end
jj = 1
jj = -1
jj = 2
jj = 3
jj = -3
jj = 4
jj = 5
jj = -5
return
statementOrdinarily, a Matlab function returns (reverts control to invoking environment) when the end of the function definition is reached. This is the case for all of the functions that we have defined/studied thus far.
At times, it is convenient to be able to exit the function before
end of the definition: for example, we may want the function to check
one or more of its input arguments for validity, and return immediately
should a bad input be detected.
The Matlab return statement provides this functionality. Its syntax is simply
return
and when this statement is encountered --- anywhere in a function definition --- the function will exit immediately
IMPORTANT
It is crucial that all of the function's output arguments are assigned a value before any return statement is encountered. Thus, e.g., when we write functions that do check their input arguments for validity, we should include assignment statements that a set all of the outargs to some values before any other statements in the body of the function.
Example
function rval = errorreturn(a, b)
% errorreturn returns the sum of its two inargs, providing that the first
% is strictly positive, otherwise it prints an error message and
% exits using the return statement.
% Assign a "default" value to the output argument to ensure that it
% IS defined before the function returns.
rval = NaN;
if a <= 0
% Print the error message and return
fprintf('errorreturn: First argument must be > 0');
return;
end
% Return the normal value
rval = a + b;
end
Now use this function first with valid arguments ...
>> errorreturn(2.0, 3.0)
ans = 5
... and then with invalid ...
>> errorreturn(-2.0, 3.0)
errorreturn: First argument must be > 0
ans = NaN
There is no limit to the number of return statements in a given function, although it is good programming style to try to keep them to a minimum
Also, return can also be used in a script: when encountered in that context, control will typically revert to the command prompt (assuming that the script was started from the command prompt)
Here's another example which shows the use of return
to
exit a function that is performing some computation iteratively,
i.e. in a loop:
function val = taylorsin(x, tol, kmax)
% taylorsin Computes an approximation to sin(x) using Taylor series. [PHYS210-Hw3]
%
% Input arguments
%
% x: The value of x at which the approximation is to be computed.
% tol: The tolerance for the computation. The function will
% return the approximation when the magnitude of the current
% term being summed is <= this value.
% kmax: The maximum number of terms that will be summed.
%
% Output argument
%
% val: The approximate value of sin(x).
%
% Also illustrates the use of the return statement to exit a function
% immediately (i.e. before the end of the function definition).
% Initialize the output argument.
val = 0;
for k = 1 : kmax
% Compute k-th term in series.
term = (-1)^(k - 1) * x^(2*k - 1) / factorial(2*k - 1);
% Update the approximation.
val = val + term;
% If the magnitude of the current term is smaller than
% the tolerance, exit the procedure using the return statement.
if abs(term) <= tol;
return;
end
end
% If execution reaches this point then convergence to the requested
% tolerance has not been achieved using the specified maximum
% number of terms. Set the output argument to NaN and return.
val = NaN;
end
Following our established protocol,
be sure to define each function in a separate .m
file
in your Matlab directory, with a filename that matches the
function name.
Your final forms of the definitions should have semi-colons at the end of every statement to suppress the output from their execution when the function is called.
However, as noted previously you may find it useful to omit the semi-colons until you have your functions debugged since this provides an easy way to see exactly what is being computed as the function executes.
Whenever you make changes to any .m
file, be sure to save it,
but note that you don't have to "reload" or "re-read" anything
in the Matlab session (as you need to do in Maple); you simply
type the name of the function/script and the updated definition
will be used.
myifC
Define in myifC.m
DESCRIPTION
myifC
takes 3 inargs and returns the largest of them (you
may recall that one of the exercises in your study of Maple
programming was to write this function).
Remember that Matlab is case sensitive, so be careful naming the file that contains this function definition.
myiffor
Define in myiffor.m
DESCRIPTION
myiffor
takes 3 inargs, j1, j2, j3, all of them integers and returns
one value
If j1 is positive, it returns a row vector of length j2, each of whose elements is j3
If j1 is negative it returns a column vector of length l2, each of whose elements is j3
If j1 is 0 it returns 0
IMPORTANT
Although you can implement this function without using for loops, the purpose of the exercise is to give you practice in programming with loops, so do NOT create the vectors using the : operator or the linspace command.
HINT
Recall that array elements can be defined "on the fly" in Matlab, so for example
>> for ii = 1 : 5
vv(ii) = ii
end
defines the elements
vv(1)
vv(2)
vv(3)
vv(4)
vv(5)
one by one as the loop executes.
tfcns
Test your work by creating a Matlab script file called tfcns.m
that contains appropriate calls to the two functions.
Note that a script can call any number of functions; Matlab will look for the definitions as needed (i.e. you only need to write one testing script)
Again, until a function is debugged you may find it useful not to end the statements in the function body with a semi-colon, so that you see an "execution trace"---however, the final versions of the functions should include the semi-colons.
The statements in the testing script should not end with a semi-colon, or you will not be able to see the results of your testing!
As usual, once you have entered some code into the file tfcns.m
and saved it, you can execute the script using
>> tfcns
Open a terminal window and execute the following command:
% addpath-hw3
(By the time you type the p
the command should probably complete
by entering TAB)
You should see output like the following:
addpath-hw3: Updated contents of /home/phys210d/Documents/MATLAB/startup.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Startup file for Matlab ... Commands in this file are
% executed at the start of every Matlab session
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
addpath('/home/phys210/matlab');
addpath('/phys210/phys210d/matlab');
addpath('/phys210/phys210d/hw3/a1');
addpath('/phys210/phys210d/hw3/a2');
addpath('/phys210/phys210d/hw3/a3');
addpath('/phys210/phys210d/hw3/a4');
addpath('/phys210/phys210d/project');
The script modifies your Matlab startup file
~/Documents/MATLAB/startup.m
so that the subdirectories in which you will code your solutions to Homework 3, as well as your term project are included in the Matlab path.
save
and load
functionsSince Matlab was expressly designed to expedite calculations with matrices---and, more generally, for arrays of arbitrary dimension---it is not surprising that it makes it straightforward for users to read and write arrays from and to files.
Specifically, say that we have an m
by n
matrix a
that we
want to store as a plain-text (a.k.a.ASCII) file named a.dat
.
For example:
>> a = reshape([1:24], 4, 6);
>> [m, n] = size(a)
m = 4
n = 6
We can do this with the Matlab save function as follows:
>> save('a.dat', 'a', '-ascii');
Even if we don't terminate the statement with a semi-colon, Matlab
will not generate any output if the file-write was successful;
i.e. no news is good news. Note that all of the arguments that
are passed to save
, including that which names the
array that is to be saved, must be strings. These are literal strings
in the above invocation---but they could equally well be string-valued
Matlab variables. E.g.
>> filename = 'a.dat';
>> arrayname = 'a';
>> option = '-ascii';
>> save(filename, arrayname, option);
has precisely the same effect. The '-ascii'
argument is required
should we want to create a plain-text file. If we omit it, then
Matlab will store the array contents in a special "binary" format
(i.e. non-human-readable) and you won't, for example, be able to
examine the file contents using your text editor, or more
etc.
For convenience, particularly in interactive work, save
can
also be invoked as a command, in which case the arguments do
not have to be strings, and are separated by whitespace, not
commas. So the following also does exactly the same thing
as the first two calls:
>> save a.dat a -ascii
For the case of 1 and 2D arrays the data is stored exactly as one
would expect, i.e. each line contains one row of the matrix, so
the number of lines in the file (m
) matches the number of
rows of the
matrix (m
) and, similarly, the number of white-space
separated values on each line of the file (n
) matches the
number of columns of the array (n
). This formatting
also means that it is easy to read the file into other programs,
such as spreadsheet applications.
Reading an array from a text file that has been created using the
save
function/command as above or, more generally, which consists
of an arbitrary number of lines, each of which has the same number
of white-space-separated values is equally as straightforward using
the load
function.
For example, to read the values of the file a.dat
as a matrix that
is assigned to the variable a1
we use
>> a1 = load('a.dat');
Here, we must use load
as function, supplying the name of the
file as a string. load
returns the values that it reads, as a
2D array/matrix in this case, so we use it on the left hand side
of the assignment to the target variable a1
.
The course demonstration script
tsaveload
provides a simple but complete
example that
save
NOTE
If you executed any of the above save
commands while we worked
through the notes, the file a.dat
will have been created and you
will probably want to remove it.
I'll take this opportunity to point out that there's a handy
function called system
which has the syntax
system(<command string>)
and which passes its argument to the shell to execute as a command in the Matlab working directory. So
>> system('rm a.dat')
ans = 0
removes the file. The value 0
that is returned means that
the command was successful. (In the shell 0
means success and
any non-zero value means failure, the rationale being that there
is only one way for a command to succeed, but many ways for
it to fail in general).
If we-reexecute the call to system
, then the error message from
bash
is echoed in the Matlab command window, and the return
value is 1
, indicating that the command failed.
system('rm a.dat')
rm: cannot remove 'a.dat': No such file or directory
ans = 1
The more command enables/disables output paging. This is analogous to
the bash command more
:
q
to quit.By default, paging is disabled at startup
Turn paging on
>> more on
Turn paging off
>> more off
Try the following
>> more on
>> eye(100)
>> more off
>> eye(100)
disp
functionThis function produces simple output, with no user control over appearance.
The form of the output is essentially the same seen with interactive
definition/use of vbls/expressions, except without the
<whatever> =
SYNTAX
disp(<expr>)
where <expr>
is a single Matlab expression, i.e. something
that can be assigned to a variable
Example
>> a = [1:2:11]
a =
1 3 5 7 9 11
>> disp(a)
1 3 5 7 9 11
You can supply a character string to disp
, which is useful for producing
explanatory/diagnostic/tracing output in a function.
Example
>> disp('This is a message')
This is a message
fprintf
functionWe briefly saw the Maple version of this function. Here, the user has complete control over the appearance of the output, and more than one quantity can be output with a single function call:
SYNTAX
fprintf(<template>, <expr>, <expr>, <expr> ...)
where <template>
is a string that provides information about the
number of additional arguments (<expr>
's) that are expected,
but, more importantly, specifies how they should appear in the output
(i.e. how they will be "formatted").
Examples
>> fprintf('This is pi in floating point format: %f\n', pi);
This is pi in floating point format: 3.141593
>> fprintf('This is 10000 * pi in exponential format: %e\n', 10000 * pi);
This is 10000 * pi in exponential format: 3.141593e+04
>> fprintf('Value 1: %g Value 2: %g\n', exp(1), exp(1)*10^-12);
Value 1: 2.71828 Value 2: 2.71828e-12
>> fprintf('This is an integer value: %g\n', 100);
This is an integer value: 100
>> string = 'foo';
>> fprintf('This is a string in angle brackets: <%s>\n', string);
This is a string in angle brackets: <foo>
Observe how all the characters in the templates, except for
%f
%e
%g
%s
and
\n
are copied verbatim to the output
%f, %e, %g
and %s
are known as format specifications or
format operators.
When fprintf executes, it replaces each of the format specifications with a new string. Each of these strings is the result of the conversion of the corresponding value to a string, as follows:
%f -> converts a value using the usual floating point representation
%e -> converts a value using scientific (exponential) notation
%g -> converts a value using %f or %e, dependent on the magnitude
to the value, to give the most readable result
%s > converts a string (i.e. simply replaces %s with the string)
Although Matlab does not generally distinguish between integers and floating
point values, it "knows" when a quantity is an integer, and the
%g
conversion will display the value without a decimal point.
IMPORTANT
The \n
(backslash n) stands for new line, and will
generate a newline character whenever it is encountered in the template.
You will usually want to include one of these at the end of each
template string. If you don't, then the command-prompt will
appear "jammed" against the output
>> fprintf('I forgot the backslash-n');
I forgot the backslash-n>>
The %g
operator is particularly useful for routine display for numerical
values.
You can control how many decimal places appear with the %g, %e and %f conversions---here are two examples:
>> fprintf('Pi to 8 decimal places: %.8f\n', pi);
Pi to 8 decimal places: 3.14159265
>> fprintf('Pi to 12 decimal places, exponential notation: %.12e\n', pi);
Pi to 12 decimal places, exponential notation: 3.141592653590e+00
This may all seem a little confusing, but, as usual, experience will help
You can use fprintf
to output a quantity that has multiple values,
i.e. an array. In this case, fprintf processes each value in
turn, recycling the template as necessary
Examples
>> fprintf('4 values: %g %g %g %g\n', linspace(1, 15, 8));
4 values: 1 3 5 7
4 values: 9 11 13 16
>> fprintf('4 values: %g %g %g %g\n', linspace(1, 13, 7));
4 values: 1 3 5 7
4 values: 9 11 13 >>
In this last example, since there were only 7 values to output,
fprintf
did not encounter a newline before the input values
were exhausted, so there is no newline before the prompt
fprintf
, fopen
and fclose
to output to a file (++)fprintf
can also be used to output quantities to a text file.
If is useful in cases where the type of output that save
produces
doesn't exactly suit your purposes.
The demo script
tfprintf
illustrates this usage of fprintf
, along
with that of two other built in functions:
fopen
: Opens a file for writing (or reading), returning a
file handle that is subsequently used as an argument to fprintf
and fclose
fclose
: Closes a file.Display the definition of tfprintf
:
>> type tfprintf
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Illustrates use of fprintf to output data to a file.
%
% Requires use of additional built in functions:
%
% fopen: Opens file
% fclose: Closes file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% First, open 'tfprintf.dat' for writing.
%
% First (string) argument to fopen specifies name of file.
% Second (string) argument to fopen specifies type of access,
% 'w' means write.
%
% Return value is an integer 'file descriptor' that is then
% used in 'fprintf' calls. If return value is < 0, then
% open failed (as could happen, for example, if you were trying
% to open a file in a directory for which you do not have
% write access.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid = fopen('tfprintf.dat', 'w');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bail out if can't open file for write ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if fid < 0
fprintf('Could not open ''tfprintf.dat'' for write.\n');
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Now use fprintf to output integers from 1 to 10, their squares
% and cubes as three columns ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1 : 10
fprintf(fid,"%g %g %g\n", i, i^2, i^3);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Close file ... until the file is closed, there is no guarantee
% that what you think you've written to the file is actually
% there!
%
% Note that the file descriptor, NOT the file name is the argument
% passed to fclose ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fclose(fid);
In order to run the demonstration, you should open a terminal session, change to the directory in which you want to save the file, and then start Matlab in the background from the command line.
For example,
% cdm
% matlab &
Then execute the script in the Matlab command window:
>> tfprintf
Unless there was a problem creating or writing to the file, the script will do its job silently.
Now return to the terminal window,
look for the file tfprintf.dat
, and examine its contents.
% cdm
% cat tfprintf.dat
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
sprintf
function (++)sprintf
is a function, also inspired by the C
version,
whose operation and syntax is essentially identical to that
of fprintf
.
The difference is that rather than displaying the formatted output to the command window or a file, the output is returned as a Matlab string.
Example 1
Create the name for a data file that includes the value of a variable:
>> n = 10;
>> filename = sprintf('mydata_%d.dat', n)
filename =
mydata_10.dat
Example 2
Create a title for a plot that includes the values of several values
(from bounce.m
, use type bounce
to see the full definition
of that function):
>> titlestr = sprintf('Step: %d Time: %.1f Number of bounces: %d', ...
fix(t / deltat), t, nbounce);
IMPORTANT
In contrast to fprintf
you will almost never want to end
the format string (the first input argument) with a newline \n
. This
is particularly the case if you are going to use the string that
sprintf
returns as a filename. You do not want to create
a filename which contains a new line!
input
functionWhen programming, you may want the user (typically you) to enter some input interactively and have it assigned to a variable.
We won't do this (much) in the lab exercises / homeworks, but you may find the facility useful for your projects, especially in the development phase.
We can use the input
function for this purpose.
SYNTAX
<var> = input(<prompt string>)
or
input(<prompt string>)
In both cases script/function execution pauses until the Enter key is depressed.
The input must be something that can be assigned to a Matlab variable (for our purposes a scalar, vector, array or string), or nothing (i.e. only the Enter key is pressed). Otherwise, an error message will be generated, and the command will re-solicit input
In the second variation the input is simply "thrown away":
however, the
this form is still useful for suspending execution so that
the user can examine output etc. before the program/fcn continues; see
plotex
for an example.
Examples
>> scalarin = input('Enter a single number: ');
Enter a single number: 5
scalarin = 5
>> vectorin = input('Enter a vector: ');
Enter a vector: [1 2 3 4]
vectorin =
1 2 3 4
>> stringin = input('Enter a string: ')
Enter a string: 'foobar'
stringin = foobar
Note that in this last example, the string must be enclosed in quotes
>> wrongin = input('Enter some invalid input: ')
Enter some invalid input: xyz
Undefined function or variable 'xyz'.
Enter some invalid input:
As noted above, when the supplied input is invalid, the input command reexecutes:
Here's an example where the input value is not assigned to anything
>> for i = 1 : 5
input('Enter anything to continue: ')
end
Enter anything to continue:
Enter anything to continue:
Enter anything to continue:
Enter anything to continue:
Enter anything to continue:
fscanf
, function (++)fscanf
, fopen
and fclose
to input from a file (++)fscanf
is the input counterpart to fprintf
.
We will illustrate its
usage here using the script
tfscanf
which inputs the values from the file created by the script
tfprintf
described above, and then outputs them to the command window.
Display the definition of tfscanf
>> type tfscanf
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Illustrates use of fscanf to input data from a file.
%
% Requires use of additional built in functions:
%
% fopen: Opens file
% fclose: Closes file
%
% Note that there are many different ways that fscanf can be called,
% some of which allow data stored in a file in a particularly
% organized fashion (e.g. as columns) to be read with little coding
% effort.
%
% This script illustrates a general technique that can be used
% in cases where the data to be read is not necessarily structured,
% e.g. as an array.
%
% Refer to online documentation or seek help from the instructor
% and/or TAs should you wish to read from files as part of your
% term project, and you are having difficulty doing so.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% First, open 'tfprintf.dat' for reading.
%
% First (string) argument to fopen specifies name of file.
% Second (string) argument to fopen specifies type of access,
% 'r' means read.
%
% Return value is an integer 'file descriptor' that is then
% used in 'fprintf' calls. If return value is < 0, then
% open failed, as could happen, for example, if file does not
% exist, or if you don't have permission to read the file.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid = fopen('tfprintf.dat', 'r');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bail out if can't open file for write ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if fid < 0
fprintf('Could not open ''tfprintf.dat'' for read.\n');
fprintf('Try running script ''tfprintf'' first.\n');
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Arguments to fscanf:
%
% First: file descriptor
% Second: template string (specifies integer values)
% Third: size of array that is to be read --- in this case
% [3,Inf] means 'read all values in the file into a
% matrix with 3 rows and as many columns as necessary'
%
% Return value:
%
% Array of values read
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
vals = fscanf(fid, '%g %g %g', [3,Inf]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Transpose vals to match the appearance of the data in the file (i.e.
% so the matrix has 3 columns and a number of rows = to the number
% of lines in the file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
vals = vals';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the number of lines in the file (number of columns in vals)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
szvals = size(vals);
nlines = szvals(1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Output the data with descriptive information
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k = 1 : nlines
fprintf('k=%g k^2=%g k^3=%g\n', vals(k,1), vals(k,2), vals(k,3));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Close file ...
%
% Note that the file descriptor, NOT the file name is the argument
% passed to fclose ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fclose(fid);
To run the demonstration first execute 'tfprintf' to generate the data file that 'tfscanf' will read ...
>> tfprintf
... then run tfscanf
>> tfscanf
k=1 k^2=1 k^3=1
k=2 k^2=4 k^3=8
k=3 k^2=9 k^3=27
k=4 k^2=16 k^3=64
k=5 k^2=25 k^3=125
k=6 k^2=36 k^3=216
k=7 k^2=49 k^3=343
k=8 k^2=64 k^3=512
k=9 k^2=81 k^3=729
k=10 k^2=100 k^3=1000
plot
function.Matlab has extremely powerful plotting facilities, and this is certainly one of the reasons the language has become so popular
(In contrast, octave's plotting capabilities, which make use of gnuplot, are relatively rudimentary. However, in order to maintain maximum compatibility between Matlab/octave these notes, most of the sample scripts/functions that I provide will be restricted to plotting functions that are supported in octave.)
You will use plotting functions extensively in the Matlab homework, as well as in your term project work. As usual, you can use Matlab's help system, as well as searches for online material to learn about features that aren't covered explicitly in the labs.
We will now take a quick look at the plot
function which is used to
make 2D (x-y) plots,
The most basic usage involves creating two equal-length vectors of x and y values and then plotting them against each other; here we make a plot of cos(x) vs x for x = 0 .. 3 pi / 2, using 1000 equally spaced values of x
>> x = linspace(0, 3*pi/2, 1000);
>> y = cos(x);
>> plot(x,y);
When you enter the plot
command a simple plot should appear on
your screen, in a new window labelled Figure 1.
Note that plot
doesn't care whether the arguments are row vectors or
column vectors, as we can easily verify
First, clear the plot window using the clf
(clear figure) command,
and recall that the transpose operator (') transforms a row vector to
a column vector and vice versa
Replot using column vectors ...
>> clf
>> plot(x',y')
... or one row, one column ...
>> clf
>> plot(x,y')
NOTE
Only numerical values can be plotted using the 'plot' function.
In particular, there is no facility for directly plotting a function
as there is in Maple and gnuplot. E.g. plot(sin(w), w)
will not work unless w
has already been defined, presumably as
a vector of values.
>> plot(sin(w), w)
Undefined function or variable 'w'.
There are two demonstration scripts available,
tplot
and
plotex
whose specific purpose is to illustrate a few more elements of
2D Matlab plotting.
Additionally, several of the other course demonstration scripts
and functions perform plotting tasks. One way to identify them
is to use the Unix grep
command with the -l
option:
% cd ~phys210/matlab
% grep -l 'plot[ ]*(' *.m
fcncaller.m
nbodyplot.m
plotex.m
.
.
.
tpolyfit.m
tprint.m
tsaveload.m
ttaylorsin.m
Now, return to the Matlab command window and
display the definition of tplot
:
>> type tplot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Demonstrates basic use of Matlab plot function for making
% x-y plots.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Clear the figure window
clf
% Generate vector of x coordinates
x = linspace(-2*pi,2*pi,1000);
% Evaluate and store two different functions at x values
% Note use of element-wise multiplication operator
y1 = cos(3*x) .* sin(x);
y2 = sin(2*x) .* cos(x/3);
% Plot the two functions using a red line and small blue circles,
% respectively
plot(x, y1, 'r', x, y2, 'ob');
% Give the plot a title, axes label and legend (these commands
% need to come AFTER the plot command
title('Plot of two of my favorite functions');
xlabel('x');
ylabel('f(x)');
legend('cos(3x) sin(x)', 'sin(2x) cos(x/3)', 'location', 'best');
% Save the plot as a JPEG image
print('tplot.jpg', '-djpeg');
First, use the close
command to close the figure window if it's
still open.
>> close
Now, let's make sure that Matlab is executing in our Matlab directory.
As we have seen, one way to ensure that this is the case is to start
Matlab from the command line in a terminal window whose working directory
is /phys210/$LOGNAME/matlab
. However, this is a good juncture to point out
that Matlab conveniently implements some commands that map directly
onto their Unix counterparts and among these are
pwd
cd
ls
So type pwd
to
see what Matlab's current working directory is,
>> pwd
ans =
/home2/phys210f
then
>> cd /phys210/<your-login-name>/matlab
>> pwd
>> ls
hello.m myadd.m myaddsub.m myvec.m q1.m
to change to your Matlab directory, verify that the cd
command was
successful, and get a directory listing: if the listing looks
garbled, try the Windows/DOS equivalent, dir
.
(Note that Matlab cd
without any arguments will not change to your
home directory---it leaves the working directory unchanged. However,
cd .. does change to the parent directory.)
Now run the script:
>> tplot
Again, the Figure 1
window should appear, showing
a single plot displaying the two functions, a title,
labels on the axes and a legend. The script also uses
the print
function/command to save the
the plot as a JPEG image in the file tplot.jpg
. If you
generate another directory listing, you should see image file
in it:
>> ls
hello.m myadd.m myaddsub.m myvec.m q1.m tplot.jpg
Recall that one way to view image files from the terminal command line
(not the Matlab command line) is with the display
command. So
in a terminal window execute
% cdm
% display tplot.jpg
Let's now move on to the second demonstration script, plotex
.
Display its contents.
>> type plotex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Simple examples of 2D plotting in Matlab.
%
% Use 'help plot' for more information about the plot command.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
more off;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Example 1: Basic plot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('The following is a plot of\n\n');
fprintf(' sin(x)*sin(3x) for 0 <= x <= 2 pi, and using\n\n');
fprintf(' - 1000 points uniformly distributed in the interval\n');
fprintf(' - default plotting style (line)\n');
fprintf(' - default line color (blue)\n');
fprintf(' - default annotations (no title, axes labels or legend)\n\n');
% 'figure(<n>)' directs plotting output to the <n>-th plotting
% window, opening that window as necessary. By default, plots
% will appear in figure window 1, so this command doesn't do
% anything---the subsequent calls to figure do though.
figure(1);
% 'clf' clears the graphics window. Also not necessary at this point,
% but included for illustrative purposes.
clf;
% Generate the x vector.
x = linspace(0, 2*pi, 1000);
% Simplest invocation of 'plot': supply two vector arguments, which are
% the x and y coordinates of the points to be plotted. Note the use
% of element-by-element operations to generate the y vector.
plot(x, sin(x) .* sin(3*x));
% Pause execution until user enters something.
input('Type ''Enter'' to continue: ');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Example 2: Basic plot with non-default plot style, axes labels and
% title.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('The following is a plot of\n\n');
fprintf(' sin(x)*sin(3x) for 0 <= x <= 2 pi, using\n\n');
fprintf(' - 1000 points uniformly distributed in the interval\n');
fprintf(' - points plotting style, with small green circles for the points\n');
fprintf(' - a title and axes labels\n\n');
fprintf('Note that the new figure window that opens (Figure 2) will likely\n');
fprintf('be positioned directly on top of Figure 1. This is the default\n');
fprintf('behaviour of Matlab---slightly annoying, but one gets used to\n');
fprintf('manually rearranging multiple windows so that they are all visible.\n');
% Open the second figure window and clear it.
figure(2);
clf;
x = linspace(0, 2*pi, 1000);
% The third (optional) argument to plot specifies the plotting style;
% in this case 'og', which means plot using points with a circle
% symbol at each point (o), and with color green (g).
plot(x, sin(x) .* sin(3*x), 'og');
% Define axes labels.
xlabel('x');
ylabel('sin(x) sin(3x)');
% Define title.
title('A simple plot');
% Pause execution until user enters something.
input('Type ''Enter'' to continue: ');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Example 3: Multiple plots in a single figure, with title, axes
% labels and legend.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('The following is a plot of\n\n');
fprintf(' sin(x)*sin(3x) AND cos(5x)*cos(2x) for 0 <= x <= 2 pi, using \n\n');
fprintf(' - 1000 points uniformly distributed in the interval\n');
fprintf(' - red +''s for the first data set, a cyan line for the second \n');
fprintf(' - a title, axes labels and legend\n\n');
% Open the third figure window and clear it.
figure(3);
clf;
x = linspace(0, 2*pi, 1000);
% This illustrates another how to make multiple plots on a single
% figure/graph. The 'hold on' command tells Matlab
% NOT to clear the graphics window when a plot command is
% issued, which it otherwise would by default.
hold on;
plot(x, sin(x) .* sin(3*x), '+r');
plot(x, cos(5*x) .* cos(2*x), '-c');
% Define axes labels.
xlabel('x');
ylabel('displacement');
% Define title.
title('A slightly more complex plot');
% Define legend, the 'location', 'best' pair positions the
% legend so as to obscure the minimum amount of the plot.
legend('sin(x) sin(3x)', 'cos(5x) cos(2x)', 'location' , 'best');
% Pause execution until user enters something.
input('Type ''Enter'' to continue: ');
% And we're done!
fprintf('Done with the demo!\n');
% Print a cheesy little countdown, then
% close all the figure windows.
fprintf('Closing all figure windows in 5 .. ');
% pause(<s>) pauses program execution for <s> seconds.
pause(0.9);
fprintf('4 .. ');
pause(0.9);
fprintf('3 .. ');
pause(0.9);
fprintf('2 .. ');
pause(0.9);
fprintf('1 .. ');
pause(0.9);
fprintf('\n');
close all;
Now, execute the script
>> plotex
The script will output commentary, generate three separate plots in three separate figure windows, then close the figure window.
Enter the following
>> type demohelp
function demohelp()
% demohelp Demonstrates interfacing a fcn to lookfor/help
%
% Input arguments: None
%
% Return values: None
%
% All 'demohelp' does is echo a message that it was invoked.
%
% ---------------------------------------------------------
% 1) Interface to lookfor
%
% The first comment line following the function header
% is known as the H1 line. Matlab searches this line for
% <keyword> when
%
% >> lookfor <keyword>
%
% is executed and, if found, displays the H1 line, with
% some standard rearrangement/formatting. For example,
% the output from
%
% >> lookfor help
%
% will include
%
% demohelp - Demonstrates interface to help/lookfor
%
% 2) Interface to help:
%
% When
%
% >> help <function>
%
% is executed, any text in contiguous comment lines following the
% function header will be displayed.
%
% The comment characters per se are stripped from the
% output.
% ---------------------------------------------------------
disp('demohelp: You invoked me!');
% The comment block above will be displayed when
% 'help demohelp' is executed, but this block will not.
end
The lookfor
command, whose syntax is
lookfor <keyword>
returns a list of functions/scripts that have something to do
with <keyword>
Execute
>> lookfor help
sl_saveas_data - Data in this object should only be accessed by ...
demohelp - Demonstrates interfacing a fcn to lookfor/help
helprpt - Audit a file or folder for help
.
.
.
Note the entry for 'demohelp' that appears near the top of the output. The synopsis is simply the contents of the H1 line, slightly reformatted
Now request help for 'demohelp'
>> help demohelp
demohelp Demonstrates interfacing a fcn to lookfor/help
Input arguments: None
Return values: None
All 'demohelp' does is echo a message that it was invoked.
---------------------------------------------------------
1) Interface to lookfor
The first comment line following the function header
is known as the H1 line. Matlab searches this line for
<keyword> when
>> lookfor <keyword>
is executed and, if found, displays the H1 line, with
some standard rearrangement/formatting. For example,
the output from
>> lookfor help
will include
demohelp - Demonstrates interface to help/lookfor
2) Interface to help:
When
>> help <function>
is executed, any text in contiguous comment lines following the
function header will be displayed.
The comment characters per se are stripped from the
output.
---------------------------------------------------------
Notice how the information displayed by the 'help' command is simply the contents of the contiguous block of comments that follow the function header, except that the initial '%' characters are stripped from the output
Finally, call the function ...
>> demohelp
demohelp: You invoked me!
Typing a '%' at the beginning of each line in a comment block can get tedious, so Matlab has support for multiline comments, which have the syntax ...
%{
<arbitrary comment content>
%}
For example ...
%{
This
is
a
multi-line
comment
%}
This construct can also be useful for "commenting out" (disabling) multiple lines of code in a function/script definition, which is a practice that is commonly adopted by programmers in the development/debugging process.
However, as I have emphasized before in the context of Maple programming you should try to minimize the use of this technique as it can easily lead to confusion as to what a function/script is actually doing, which in turn can lead to an increase, rather than decrease, in total development time.
Unfortunately, multiline comments will not
interface as expected with the help
command in Matlab (although they
do in octave).
Thus if you want a comment block that will be displayed when
help <function name>
is executed, you will need to stick to
using %
at the beginning of each line in the block
The individual elements of the arrays that we have used thus far in Matlab must all be scalars (i.e. single numbers)
There is another type of array, called a cell array, whose elements can be arbitrary Matlab quantities, including scalars, arrays strings, or even other cell arrays (and each element can be can be a different type of object).
Cell arrays are very handy for many programming tasks in Matlab, and, should you have time, you are encouraged to become familiar with their use. Some of you may find them useful for your projects: the simple ray tracing optics simulation spring comes to mind.
Unlike regular arrays, cell arrays cannot be defined "on the fly";
they must be created with some specified dimensions using the
builtin cell
function. (However, once defined, additional values
will be added automatically when referenced as is the case for
normal arrays.)
>> help cell
CELL Create cell array.
CELL(N) is an N-by-N cell array of empty matrices.
CELL(M,N) or CELL([M,N]) is an M-by-N cell array of empty
matrices.
CELL(M,N,P,...) or CELL([M N P ...]) is an M-by-N-by-P-by-...
cell array of empty matrices.
CELL(SIZE(A)) is a cell array the same size as A containing
all empty matrices.
See also ONES, ZEROS, STRUCT, DEAL, PAREN.
Overloaded methods:
distributed/cell
codistributor2dbc/cell
codistributor1d/cell
codistributed/cell
Reference page in Help browser
doc cell
Let's create a cell array with dimensions 1 x 4 (i.e. a length-4 row vector of cells), and then assign values to it:
>> cc = cell(1,4)
cc =
[] [] [] []
The value [ ] is to be interpreted as in the other contexts where we have seen it, i.e. as the empty array.
Now let's assign row vectors of varying lengths to the individual
elements of cc
.
IMPORTANT
Cell arrays are indexed with { } (braces, curly brackets), both for assignment and retrieval of values.
Note that as we make the assignments, the values that Matlab echoes show only the structure of the cells, not the actual contents (double means a standard Matlab floating point value):
>> cc{1} = 1:2
cc =
[1x2 double] [] [] []
>> cc{2} = 1:4
cc =
[1x2 double] [1x4 double] [] []
>> cc{3} = 1:6
cc =
[1x2 double] [1x4 double] [1x6 double] []
>> cc{4} = 1:8
cc =
[1x2 double] [1x4 double] [1x6 double] [1x8 double]
The contents of a cell are addressed (referenced) using the
curly braces, { }
:
For example, we can retrieve the contents of the 3rd cell via ...
>> cc{3}
ans =
1 2 3 4 5 6
... and set the 1st value using
>> cc{1} = 'I used to be a vector of length 2, now I am a string.'
cc =
[1x53 char] [1x4 double] [1x6 double] [1x8 double]
Again, the output from the assignment shows only the structure of the cells, not their contents. However, the expected value can be retrieved using
>> cc{1}
ans =
I used to be a vector of length 2, now I am a string.
Cell arrays can be multidimensional --- for example, if the cell function is called with a single argument, N, a N x N array of cells is created:
>> dd = cell(2)
dd =
[] []
[] []
Elements of dd
can then be assigned/retrieved using the usual
syntax for multi-d arrays, but again using { }
for indexing
>> dd{1,1} = 'a'; dd{1,2} = 1:5:2; dd{2,1} = eye(2); dd{2,2} = [1:4]';
Display the contents of a specific element of the cell array:
>> dd{2,2}
ans =
1
2
3
4
Display the contents of the entire array:
>> dd{:,:}
ans =
a
ans =
1 0
0 1
ans =
1
ans =
1
2
3
4
Again, note how we can "mix and match" various types of objects in the different cells.
Though it really constitutes a breach of protocol, I assert that it is OK for you to work on the first problem of Homework 3 without reading through all of the instructions in detail.
HOWEVER, you should read through those instructions carefully before you proceed to the remaining problems and you should read through the entire description of the first question before you begin it.
Note that for this problem set I have already created the requisite subdirectories:
/phys210/$LOGNAME/hw3/a1
/phys210/$LOGNAME/hw3/a2
/phys210/$LOGNAME/hw3/a3
/phys210/$LOGNAME/hw3/a4
Provided that you have completed today's mandatory lab exercise
(see above if you haven't), you will be able to execute any scripts and
functions that you define in .m
files within those directories
from within a Matlab session started any way that you wish (i.e. you
will not have to start Matlab with the working directory positioned
in whichever subdirectory contains the code that you are writing).
If you finish the first problem with time remaining, I suggest that you move on to the second!