Octave Tutorial
Octave Tutorial
Octave Tutorial
1
www.octave.org
2
MATLAB°TheR Mathworks, www.mathworks.com
3
Multidisciplinary Design Project
1
Contents
1 Introduction 4
1.1 What is Octave? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 What Octave is not . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Who uses Octave? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Why not use a ‘normal’ highlevel language, e.g. C++ . . . . . . . . . . . . 4
2 Simple calculations 5
2.1 Starting Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Octave as a calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Built-in functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5 Plotting graphs 17
5.1 Improving the presentation . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.2 Multiple graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.3 Multiple figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.4 Manual scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.5 Saving and printing figures . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
7 Control statements 25
7.1 if...else selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.2 switch selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.3 for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
7.4 while loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2
7.5 Accuracy and precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
11 Solving Ax = b 40
11.1 Solution when A is invertible . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
11.2 Gaussian elimination and LU factorisation . . . . . . . . . . . . . . . . . . . 41
11.3 Matrix division and the slash operator . . . . . . . . . . . . . . . . . . . . . 41
11.4 Singular matrices and rank . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.5 Ill-conditioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
11.6 Over-determined systems: Least squares . . . . . . . . . . . . . . . . . . . . 44
11.7 Example: Triangulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
12 More graphs 45
12.1 Putting several graphs in one window . . . . . . . . . . . . . . . . . . . . . 45
12.2 3D plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
12.3 Changing the viewpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
12.4 Plotting surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
12.5 Images and Movies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
14 Complex numbers 53
14.1 Plotting complex numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
14.2 Finding roots of polynomials . . . . . . . . . . . . . . . . . . . . . . . . . . 54
16 Further reading 55
17 Acknowledgements 56
3
1 Introduction
1.1 What is Octave?
Octave is an open-source interactive software system for numerical computations and
graphics. It is particularly designed for matrix computations: solving simultaneous equa-
tions, computing eigenvectors and eigenvalues and so on. In many real-world engineering
problems the data can be expressed as matrices and vectors, and boil down to these forms
of solution. In addition, Octave can display data in a variety of different ways, and it
also has its own programming language which allows the system to be extended. It can
be thought of as a very powerful, programmable, graphical calculator. Octave makes
it easy to solve a wide range of numerical problems, allowing you to spend more time
experimenting and thinking about the wider problem.
4
software in languages like C++ sometimes begin by prototyping any mathematical parts
using Octave, as that allows them to test the algorithms quickly.
Octave is available on the MDP Resource CD and can be downloaded from www.octave.org
if required.
2 Simple calculations
2.1 Starting Octave
If not already running start Octave, (see start → Programs → Octave on the MDP
CD.) or type in a xterm window
octave
After a pause, a logo will briefly pop up in another window, and the terminal will
display the header similar to this:
GNU Octave, version 2.1.57 (i386-pc-linux-gnu).
Copyright (C) 2004 John W. Eaton.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTIBILITY or
FITNESS FOR A PARTICULAR PURPOSE. For details, type ‘warranty’.
octave:1>
and you are now in the Octave environment. The octave:1> is the Octave prompt,
asking you to type in a command.
If you want to leave Octave at any point, type quit at the prompt.
octave:##> 2+2
5
are evaluated first, then powers, then multiplication and division, and finally addition and
subtraction. Try a few examples.
octave:##> exp(1)
ans = 2.7183
Here is a longer expression: to calculate 1.2 sin(40◦ + ln(2.42 )), type
ans = 0.76618
• The trigonometric functions (for example sin) work in radians. The factor π/180
can be used to convert degrees to radians. pi is an example of a named variable,
discussed in the next section.
Using these functions, and the usual mathematical constructions, Octave can do all
of the things that your normal calculator can do.
6
cos Cosine of an angle (in radians)
sin Sine of an angle (in radians)
tan Tangent of an angle (in radians)
exp Exponential function (ex )
log Natural logarithm (NB this is loge , not log10 )
log10 Logarithm to base 10
sinh Hyperbolic sine
cosh Hyperbolic cosine
tanh Hyperbolic tangent
acos Inverse cosine
acosh Inverse hyperbolic cosine
asin Inverse sine
asinh Inverse hyperbolic sine
atan Inverse tangent
atan2 Two-argument form of inverse tangent
atanh Inverse hyperbolic tangent
abs Absolute value
sign Sign of the number (−1 or +1)
round Round to the nearest integer
floor Round down (towards minus infinity)
ceil Round up (towards plus infinity)
fix Round towards zero
rem Remainder after integer division
Table 1: Basic maths functions
7
3.1 Named variables
In any significant calculation you are going to want to store your answers, or reuse values,
just like using the memory on a calculator. Octave allows you to define and use named
variables. For example, consider the degrees example in the previous section. We can
define a variable deg to hold the conversion factor, writing
deg =0.017453
Note that the type of the variable does not need to be defined, unlike most high level
languages e.g. in C++. All variables in Octave are floating point numbers.7 Using this
variable, we can rewrite the earlier expression as
ans =0.76618
which is not only easier to type, but it is easier to read and you are less likely to make
a silly mistake when typing the numbers in. Try to define and use variables for all your
common numbers or results when you write programs.
You will have already have seen another example of a variable in Octave. Every time
you type in an expression which is not assigned to a variable, such as in the most recent
example, Octave assigns the answer to a variable called ans. This can then be used in
exactly the same way:
new =2.2985
Note also that this is not the answer that would be expected from simply performing
3 × 0.76618. Although Octave displays numbers to only a few decimal places (usually
five)8 , it stores them internally, and in variables, to a much higher precision, so the answer
given is the more accurate one.9 In all numerical calculations, an appreciation of the
rounding errors is very important, and it is essential that you do not introduce any more
errors than there already are! This is another important reason for storing numbers in
variables rather than typing them in each time.
When defining and using variables, the capitalisation of the name is important: a is a
different variable from A. There are also some variable names which are already defined and
used by Octave. The variable √ ans has also been mentioned, as has pi, and in addition i
and j are also defined as −1 (see Section 14). Octave won’t stop you redefining these
7
Or strings, but those are obvious from the context. However, even strings are stored as a vector of
character ID numbers.
8
MATLAB normally displays to 4 or 5 decimal places
9
Octave stores all numbers in IEEE floating point format to double (64-bit) precision. The value of
ans here is actually 0.766177651029692 (to 15 decimal places).
8
as whatever you like, but you might confuse yourself, and Octave, if you do! Likewise,
giving variables names like sin or cos is allowed, but also not to be recommended.
If you want to see the value of a variable at any point, just type its name and press
return. If you want to see a list of all the named functions, variables10 you have created
or used, type
octave:##> who
dispatch
rem
deg new
You will occasionally want to remove variables from the workspace, perhaps to save
memory, or because you are getting confusing results using that variable and you want to
start again. The clear command will delete all variables, or specifying
clear name
will set Octave to display numbers to fifteen+ significant figures, which is about the
accuracy of Octave’s calculations. If you type help format you can get a full list of the
options for this command. With format long set, we can view the more accurate value
of deg:
octave:##> deg
deg =.0174532925199433
9
The second line here returns Octave to its normal display accuracy.
Octave displays very large or very small numbers using exponential notation, for
example: 13142.6 = 1.31426 × 104 , which is displayed by Octave as 1.3143e+04. You
can also type numbers into Octave using this format.
There are also some other kinds of numbers recognised, and calculated, by Octave:
Complex numbers (e.g. 3+4i) Are fully understood by Octave, as discussed further
in Section 14
Infinity (Inf) The result of dividing a number by zero. This is a valid answer to a
calculation, and may be assigned to a variable just like any other number
Not a Number (NaN) The result of zero divided by zero, and also of some other oper-
ations which generate undefined results. Again, this may be treated just like any
other number (although the results of any calculations using it are still always NaN).
Using binary is ideal for computers since it is just a series of ones and zeros, which can
be represented by whether particular circuits are on or off. A problem with representing
numbers in a computer is that each number can only have a finite number circuits, or bits,
assigned to it, and so can only have a finite number of digits. Consider this example:
ans = 5.5511e-017
The result is very small, but not exactly zero, which is the correct answer. The reason
is that 0.2 cannot be exactly represented in binary using a finite number of digits (it is
0.0011001100 . . . ). This is for exactly the same reasons that 1/3 cannot be exactly written
as a base 10 number. Octave (and all other computer programs) represent these numbers
with the closest one they can, but repeated uses of these approximations, as seen here,
can cause problems. For this reason, you should think very carefully before checking that
a number is exactly equal to another. It is usually best to check that it is the same to
within a tolerance. We will return to this problem throughout this tutorial.
10
octave:##> save anyname
it will save the entire workspace to a file called anyname.mat in your current directory
(note that Octave automatically appends .mat to the end of the name you’ve given it).
You can then quit Octave, and when you restart it, you can type
which will restore your previous workspace, and you can carry on from where you left off.
You can also load and save specific variables. The format is
For example, if you wanted to save the deg variable, to save calculating it from scratch
(which admittedly is not very difficult in this case!), you could type
This will save the variable into a file called degconv.mat You can reload it by typing
Octave will also load data from text files, which is particularly useful if you want to plot
or perform calculations on measurements from some other source. The text file should
contain rows of space-separated numbers.
help commandname
11
On some systems the emacs key bindings are acknowledged, e.g. <ctrl>p =↑, <ctrl>n=↓, <ctrl>f=→,
< ctrl>b=←
11
For example:
Overloaded function
gsqrt(galois,...)
12 If
you don’t know the name of the command you want, there are a number method
to find if it exists. Typing help -i at the prompt will give a list of all the main areas
of help.
More detailed information on a topic can be obtained by moving the cursor of the
item of interest and pressing <return>. The list can be navigated using the key bindings
Up, Next, Previous. etc. Or directly from the prompt, e.g. to find out about arithmetic
functions type;
Use the letter ‘q’ to quit from the help system and return to the Octave command
prompt.
Note that often the help information gives an indication of which area to search for fur-
ther information, in the help sqrt example it is suggested to search the ‘Linear Algebra’
area, e.g.
Take some time browsing around the help system and anyone line help/manuals to get
an idea of the commands that Octave provides.13
12
MATLAB help messages tend to be shorter, but always indicate the command in UPPER CASE.
Don’t copy these exactly—Octave and MATLAB commands are almost always in lower case, e.g. the
square root function is sqrt(), not SQRT()
13
MATLAB has some additional search facilities including the function lookfor which allows the user to
search the help database
12
3.7 Cancelling a command
If you find yourself having typed a command which is taking a long time to execute (or
perhaps it is one of your own programs which has a bug which causes it to repeat endlessly),
it is very useful to know how to stop it. You can cancel the current command by typing
Ctrl-C
which should (perhaps after a small pause) return you to the command prompt.
octave:##> a=[1 4 5]
a =
1 4 5
octave:##> b=[2,1,0]
b =
2 1 0
octave:##> c=[4;7;10]
c =
13
4
7
10
A list of numbers separated by spaces or commas, inside square brackets, defines a row
vector. Numbers separated by semicolons, or carriage returns, define a column vector.
You can also construct a vector from an existing vector by including it in the definition,
for example
octave:##> a=[1 4 5]
a =
1 4 5
octave:##> d=[a 6]
d =
1 4 5 6
octave:##> e=2:6
e =
2 3 4 5 6
The colon tells Octave to create a vector of numbers starting from the first number,
and counting up to (and including) the second number. A third number may also be
added between the two, making a : b : c. The middle number then specifies the increment
between elements of the vector.
octave:##> e=2:0.3:4
e =
2.0000 2.3000 2.6000 2.9000 3.2000 3.5000 3.8000
Note that if the increment step is such that it can’t exactly reach the end number, as
in this case, it generates all of the numbers which do not exceed it. The increment can
also be negative, in which case it will count down to the end number.
octave:##> v = 1:1000
14
zeros(M, N ) Create a matrix where every element is zero. For
a row vector of size n, set M = 1, N = n
ones(M, N ) Create a matrix where every element is one. For
a row vector of size n, set M = 1, N = n
linspace(x1, x2, N ) Create a vector of N elements, evenly spaced
between x1 and x2
logspace(x1, x2, N ) Create a vector of N elements, logarithmically
spaced between 10x1 and 10x2
Table 2: Vector creation functions
Press the space bar to see the next page of values and use the ‘q’ key to quit the
display and return to the Octave command prompt. You can also use the ‘b’ key to scroll
backwards up throught the values being displayed.
It is sometimes convenient to turn off this pagination facility, for example when dis-
playing intermediate values during a long calculation. This can be achieved using the
command. As you would expect, pagination can be turned back on again using
octave:##> more on
octave:##> a=[1:2:6 -1 0]
a =
1 3 5 -1 0
octave:##> a(3)
ans =
5
15
The colon notation can also be used to specify a range of numbers to get several elements
at one time
octave:##> a(3:5)
ans =
5 -1 0
octave:##> a(1:2:5)
ans =
1 5 0
octave:##> a * 2
ans =
2 6 10 -2 0
The same is also true for division. You can also add the same number to each element by
using the + or - operators, although this is not a standard mathematical convention.
Multiplying two vectors together in Octave follows the rules of matrix multiplication
(see Section 9), which doesn’t do an element-by-element multiplication.14 If you want to
do this, Octave defines the operators .* and ./, for example
a1 b1 a1 b1
a2 .* b2 = a2 b2
a3 b3 a3 b3
Note the ‘.’ in front of each symbol, which means it’s a element-by-element operation.
For example, we can multiply each of the elements of the vector a, defined earlier, by a
different number:
octave:##> a.*b
ans =
14
Recall that the only vector products mathematically defined are the dot and cross product, both of
which represent particular operations on two vectors, neither of which just multiply the elements together
and return another vector.
16
1 6 15 -4 0
The element-by-element ‘to the power of’ operator .^ is particularly useful. It can be
used to raise a vector of numbers to a power, or to raise a number to different powers,
depending on how it is used:
octave:##> b .^ 2
ans =
1 4 9 16 25
octave:##> 2 .^ b
ans =
2 4 8 16 32
The first example squares each element of b; the second raises 2 to each of the powers
given in b.
All of the element-by-element vector commands (+ - ./ .* .^) can be used between two
vectors, as long as they are the same size and shape. Otherwise corresponding elements
cannot be found and an error is given.
Most of Octave’s functions also know about vectors. For example, to create a list of
the value of sine at 60-degree intervals, you just need to pass a vector of angles to the sin
function:
octave:##> angles=[0:pi/3:2*pi]
angles =
0 1.0472 2.0944 3.1416 4.1888 5.2360 6.2832
octave:##> y=sin(angles)
y =
0 0.8660 0.8660 0.0000 -0.8660 -0.8660 -0.0000
5 Plotting graphs
Octave has powerful facilities for plotting graphs via a second open-source program
GNUPLOT15 , however some of the range of plotting options are restricted compared with
MATLAB The basic command is plot(x,y), where x and y are the co-ordinates. If given
just one pair of numbers it plots a point, but usually you pass vectors, and it plots all
the points given by the two vectors, joining them up with straight lines.16 The sine curve
defined in the previous section can be plotted by typing
octave:##> plot(angles,y)
15
www.gnuplot.org
16
The two vectors must, naturally, both be the same length.
17
1
0.8
0.6
0.4
0.2
−0.2
−0.4
−0.6
−0.8
−1
0 1 2 3 4 5 6 7
A new window should open up, displaying the graph, shown in Figure 1. Note that it
automatically selects a sensible scale, and plots the axes.
At the moment it does not look particularly like a sine wave, because we have only
taken values one every 60 degrees. To plot a more accurate graph, we need to calculate y
at a higher resolution:
octave:##> angles=linspace(0,2*pi,100);
octave:##> y=sin(angles);
octave:##> plot(angles, y);
The linspace command creates a vector with 100 values evenly spaced between 0 and
2π (the value 100 is picked by trial and error). Try using these commands to re-plot the
graph at this higher resolution. Remember that you can use the arrow keys ↑ and ↓ to go
back and reuse your previous commands.
Strings in Octave (such as the names for the axes) are delimited using apostrophes
(’).
18
w whitew . point - solid
m magenta o circle : dotted†
c cyan x x-mark -. dashdot†
r red + plus -- dashed†
g green * star
b blue s square†
y yellow† d diamond†
k black† v triangle (down)†
^ triangle (up)†
< triangle (left)†
> triangle (right)†
p pentagram†
h hexagram†
Table 3: Colours and styles for symbols and lines in the plot command (see help plot).. (†N.B. Only
available in MATLAB)
Graph of y=cos(x)
1
0.8
0.6
0.4
0.2
Value
−0.2
−0.4
−0.6
−0.8
−1
0 1 2 3 4 5 6 7
Angle
Figure 2: Graph of y = sin(x), marking each sample point with a red circle.
In some circumstances the command replot has to called to enable the graph to
update.
A grid may also be added to the graph, by typing
octave:##> grid on
Figure 2 shows the result. You can resize the figure or make it a different height and
width by dragging the corners of the figure window.
octave:##> plot(angles,y,’:’,angles,cos(angles),’-’)
19
1
0.8
0.6
0.4
0.2
−0.2
−0.4
−0.6
Sine
Cosine
−0.8
−1
0 1 2 3 4 5 6 7
where the extra three arguments define the cosine curve and its line style. You can
add a legend to the plot using the legend command:
where you specify the names for the curves in the order they were plotted. If the
legend doesn’t appear in a sensible place on the graph, you can pick it up with the mouse
and move it elsewhere. You should be able to get a pair of graphs looking like Figure 3.
Thus far, every time you have issued a plot command, the existing contents of the
figure have been removed. If you want to keep the current graph, and overlay new plots
on top of it, you can use the hold command. Using this, the two sine and cosine graphs
could have been drawn using two separate plot commands:
octave:##> plot(angles,y,’:’)
octave:##> hold on
octave:##> plot(angles,cos(angles),’g-’)
If you want to release the lock on the current graphs, the command is (unsurprisingly)
hold off.
octave:##> figure
the next plot command will produce a graph in a new figure window. For example,
20
80 5
4
60
40
2
20
1
0 0
−1
−20
−2
−40
−3
−60
−4
−80 −5
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
Figure 4: Graph of y = tan(x) with the default scaling, and using axis([0 7 -5 5])
typing
will plot the tangent function in this new window (see Figure 4(a)).17
If you want to go back and plot in the first figure, you can type
octave:##> figure(0)
octave:##> figure(2)
the graph is rescaled as shown in Figure 4(b). Note the two sets of brackets in the axis
command—the normal brackets which surround the argument passes to the function, and
the square brackets which define the vector, which is the argument.
Octave, combined with GnuPlot, allows direct interaction with the graphics window,
e.g. to zoom in drag a box around the area of interest with the right mouse button pressed
17
In Matlab the command figure brings up a new figure window immediately whereas in Octave the
new window may not appear until you issue a plot command.
21
Mouse Actions
Table 4: Mouse and Keybinds for interaction with 2D graphs, (LMB - Left Mouse Button, RMB - Right
Mouse Button), see also table 8.
and select with the left mouse button. Details of other mouse actions and key bindings
(when the graphic window is selected) are shown in table 4.18
octave:##> print(‘graph1.eps’,’-deps’)
to save an encapsulated postscript version of the graph to a file graph1.eps.
octave:##> print(‘graph1.png’,’-dpng’)
to save an PNG format image
18
In MATLAB access to graphics commands is via icons and menus surrounding the graph window
22
6 Octave programming I: Script files
If you have a series of commands that you will want to type again and again, you can
store them away in a Octave script. This is a text file which contains the commands,
and is the basic form of a Octave program. When you run a script in Octave, it has the
same effect as typing the commands from that file, line by line, into Octave. Scripts are
also useful when you’re not quite sure of the series of commands you want to use, because
its easier to edit them in a text file than using the cursor keys to recall and edit previous
lines that you’ve tried.
Octave scripts are normal text files, but they must have a .m extension to the filename
(e.g. run.m). For this reason, they are sometimes also called M-files. The rest of the
filename (the word ‘run’ in this example) is the command that you type into Octave to
run the script.
You can create a script file in any text editor (e.g. emacs, notepad), and you can start up
a text editor from within Octave by typing
octave:##> edit
This will start up the emacs editor in a new window.19 If you want to edit an existing
script, you can include the name of the script. If, for example, you did have a script called
run.m, typing edit run, would open the editor and load up that file for editing.
In the editor, you just type the commands that you want Octave to run. For example,
start up the editor if you haven’t already and then type the following commands into the
editor (but first delete any lines that emacs may have left)
The percent symbol (%) identifies a comment, and any text on a line after a % is ig-
nored by Octave. Comments should be used in your scripts to describe what it does,
both for the benefit of other people looking at it, and for yourself a few weeks down the
line.
Select File → Save Buffer As... from the editor’s menu, and save your file as
rectsin.m. You have now finished with the editor window, but you might as well leave it
open, since you will no doubt need the editor again.
19
edit can be configured to start up the text editor of your choice.
23
Rectified Sine Wave
1
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0 1 2 3 4 5 6 7 8 9 10
t
octave:##> rectsin
A figure window should appear showing a rectified sine wave. However, if you typed
the script into the editor exactly as given above, you should also now see in the Octave
command window:
error: ‘labelx’ undefined near line 6 column 2
error: near line 6 of file ‘/mnt/hda7/Octave/retsin.m’
which shows that there is an error in the script.20 Octave error messages make more
sense if they are read from bottom to top. This one says that on line 6 of rectsin.m, it
doesn’t know what to do about the command ‘labelx’. The reason is, of course that the
command should be ‘xlabel’. Go back to the editor, correct this line, and then save the
file again. Don’t forget to save the file each time you edit it.
Try running the corrected script by typing rectsin again, and this time it should
correctly label the x-axis, as shown in Figure 5.
octave:##> what
m-files in current directory /mnt/hda7/Octave/tutorial
20
If you spotted the error when you were typing the script in, and corrected it, well done!
24
rectsin.m
The Octave help system will also automatically recognise your scripts. If you ask for
help on the rectsin script you should get
Octave assumes that the first lines of comments in the M-file are a description of the
script, and this is what it prints when you ask for help. You should add help lines to the
top of every script you write to help you search through the scripts you write.
7 Control statements
Thus far the programs and expressions that we have seen have contained simple, sequen-
tial operations. The use of vectors (and later matrices) enable some more sophisticated
computations to be performed using simple expressions, but to proceed further we need
some more of the standard programming constructs. Octave supports the usual loops
and selection facilities.
if expression
statements
elseif expression
statements
else
statements
end
This is slightly different to the syntax in seen C++: brackets () are not needed around
the expression (although can be used for clarity), and the block of statements does not
need to be delimited with braces {}. Instead, the end command is used to mark the end
of the if statement.
While control statements, such as if, are usually seen in Octave scripts, they can
also be typed in at the command line as in this example:
25
symbol meaning example
== equal if x == y
~= not equal if x ~= y
> greater than if x > y
>= greater than or equal if x >= y
< less than if x < y
<= less than or equal if x <= y
& AND if x == 1 & y > 2
| OR if x == 1 | y > 2
~ NOT x = ~y
Table 5: Boolean expressions
octave:##> if a > b
c=3
else
c=4
end
c =
4
If you are typing them in at the command prompt, Octave waits until you have typed
the final end before evaluating the expression.
Many control statements rely on the evaluation of a logical expression—some statement
that can be either true or false depending on the current values. In Octave, logical
expressions return numbers: 0 if the expression is false and 1 if it is true:
octave:##> 1==2
ans =
0
a complete set of relational and logical operators are available, as shown in Table 5. Note
that they are not quite the same as in C++.
switch x
26
case x1 ,
statements
case x2 ,
statements
otherwise,
statements
end
In a switch statement, the value of x is compared with each of the listed cases, and if
it finds one which is equal then the corresponding statements are executed. Note that,
unlike C++, a break command is not necessary—Octave only executes commands until
the next case command. If no match is found, the otherwise statements are executed,
if present. Here is an example:
octave:##> a=1;
octave:##> switch a
case 0
disp(’a is zero’);
case 1
disp(’a is one’);
otherwise
disp(’a is not a binary digit’);
end
a is one
The disp function displays a value or string. In this example it is used to print strings,
but it can also be used with variables, e.g. disp(a) will print the value of a.
27
octave:##> for n=1:5
nf(n) = factorial(n);
end
octave:##> disp(nf)
1 2 6 24 120
Note the use of the semicolon on the end of the line in the for loop. This prevents
Octave from printing out the current value of nf(n) every time round the loop, which
would be rather annoying (try it without the semicolon if you like).
while expression
statements
end
For example,
octave:##> x=1;
octave:##> x
x =
1.1102e-016
28
Consider this example:
So, while the two numbers are fine by themselves, because they are of such different
magnitudes their sum cannot be exactly represented.
This is exactly what is happening in the case of our while loop above. Octave (and
most computers) are accurate to about fifteen significant figures, so once we try to add
1 × 10−16 to 1, the answer requires a larger number of significant figures than are available,
and the answer is truncated, leaving just 1.
There is no general solution to these kind of problems, but you need to be aware that
they exist. It is most unusual to need to be concerned about the sixteenth decimal place
of an answer, but if you are then you will need to think very carefully about how you go
about solving the problem. The answer is to think about how you go about formulating
your solution, and make sure that, in the solution you select, the numbers you are dealing
with are all of of about the same magnitude.
29
8.1 Example 1: Sine in degrees
Octave uses radians for all of its angle calculations, but most of us are happier working
in degrees. When doing Octave calculations you could just always convert your angle
d to radians using sin(d/180*pi), or even using the variable deg as defined in Section
3.1, writing sin(d*deg). But it would be simpler and more readable if you could just
type sind(d) (‘sine in degrees’), and we can create a function to do this. Such a function
would be defined by creating a file sind.m containing just the following lines:
function s = sind(x)
%SIND(X) Calculates sine(x) in degrees
s = sin(x*pi/180);
This may seem trivial, but many functions are trivial and it doesn’t make them any
less useful. We’ll look at this function line-by-line:
Line 1 Tells Octave that this file defines a function rather than a script. It says that
the function is called sind, and that it takes one argument, called x. The result of
the function is to be known, internally, as s. Whatever s is set to in this function is
what the user will get when they use the sind function.
Line 2 Is a comment line. As with scripts, the first set of comments in the file should
describe the function. This line is the one printed when the user types help sind. It
is usual to use a similar format to that which is used by Octave’s built-in functions.
Line 3 Does the actual work in this function. It takes the input x and saves the result of
the calculation in s, which was defined in the first line as the name of the result of
the function.
End of the function Functions in Octave do not need to end with return (although
you can use the return command to make Octave jump out of a function in the
middle). Because each function is in a separate M-file, once it reaches the end of the
file, Octave knows that it is the end of the function. The value that s has at the
end of this function is the value that is returned.
which shows that the function has been recognised by Octave and it has found the help
line included in the function definition. Now we can try some numbers
30
octave:##> sind(0)
ans =
0
octave:##> sind(45)
ans =
0.7071
31
2
line 1
1.5
0.5
-0.5
-1
-1 0 1 2 3 4
Figure 6: A unit, one second pulse created from two unit steps, using the function ustep.
Lines 2-5 Are the description of the function. This time the help message contains several
lines.
Line 6 The first argument to the ystep function, t, will usually be a vector, rather than
a scalar, which contains the time values for which the function should be evaluated.
This line uses the size function, which returns two values: the number of rows and
then the number of columns of the vector (or matrix). This gives an example of how
functions in Octave can return two things—in a vector, of course. These values are
used to create an output vector of the same size, and to check that the input is a
vector.
Lines 7-10 Check that the input t is valid i.e. that it is not a matrix. This checks that
it has either one row or one column (using the result of the size function). The
error function prints out a message and aborts the function if there is a problem.
Line 11 As the associated comment says, this line creates the array to hold the output
values. It is initialised to be the same size and shape as the input t, and for each
element to be zero.
Line 12 For each time value in t, we want to create a value for y. We therefore use a for
loop to step through each value. The length function tells us how many elements
there are in the vector t.
Lines 13–15 According to our definition, if t < t0 , then the step function has the value
zero. Our output vector y already contains zeros, so we can ignore this case. In the
other case, when t ≥ t0 , the output should be 1. We test for this case and set y, our
output variable, accordingly.
As in most high level languages, all variables created inside a function (m, n and k in
this case) are local to the function. They only exist for the duration of the function, and
do not overwrite any variables of the same name elsewhere in Octave. The only variables
which are passed back are the return values defined in the first function line: y in this
case.
Type this function into the editor, and save it as ustep.m. We can now use this
function to create signal. For example, to create a unit pulse of duration one second,
starting at t = 0, we can first define a time scale:
32
octave:##> t=-1:0.1:4;
and then use ustep twice to create the pulse:
octave:##> plot(t, v)
octave:##> who
dispatch
*** currently compiled functions:
t v
we can confirm that the variables m and n defined in the ustep function only lasted as
long as the function did, and are not part of the main workspace. Any other variable listed
e.g. y variable will still have the value from an earlier definition, e.g. y by the rectsin
script, rather than the values defined for the variable y in the ustep function. Variables
defined and used inside functions are completely separate from the main workspace.
To enter this matrix into Octave you use the same syntax as for vectors, typing it in row
by row:
octave:##> A=[5 7 9
-1 3 -2]
33
A =
5 7 9
-1 3 -2
alternatively, you can use semicolons to mark the end of rows, as in this example:
A final alternative is to build up the matrix row-by-row (this is particularly good for
building up tables of results in a for loop):
octave:##> A*B
ans =
19 -7
-4 -3
octave:##> B*C
ans =
2 4 6
-8 -6 -4
1 2 3
octave:##> A*C
error: operator *: nonconformant arguments (op1 is 2x3, op2 is 2x3)
error: evaluating binary operator ‘*’ near line 11, column 2
34
You might like to work out these examples by hand to remind yourself what is going on.
Note that you cannot do A*C, because the two matrices are incompatible shapes.24
When just dealing with vectors, there is little need to distinguish between row and
column vectors. When multiplying vectors, however, it will only work one way round. A
row vector is a 1 × n matrix, but this can’t post-multiply a m × n matrix:
octave:##> x=[1 0 3]
x =
1 0 3
octave:##> A*x
error: operator *: nonconformant arguments (op1 is 2x3, op2 is 1x3)
error: evaluating binary operator ‘*’ near line 12, column 2
octave:##> A’
ans =
5 -1
7 3
9 -2
octave:##> A*x’
ans =
32
-7
In this last example the x’ command changes our row vector into a column vector, so it
can now be pre-multiplied by the matrix A.
35
A very important matrix is the identity matrix. This is the matrix that, when multi-
plying any other matrix or vector, does not change anything. This is usually called I in
formulæ, so the Octave function is called eye. This only takes one parameter, since an
identity matrix must be square:
octave:##> I = eye(4)
I =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
we can check that this leaves any vector or matrix unchanged:
octave:##> I * [5; 8; 2; 0]
ans =
5
8
2
0
The identity matrix is a special case of a diagonal matrix, which is zero apart from the
diagonal entries:
−1 0 0
D = 0 7 0
0 0 2
You could construct this explicitly, but the Octave provides the diag function which
takes a vector and puts it along the diagonal of a matrix:
octave:##> diag([-1 7 2])
ans =
-1 0 0
0 7 0
0 0 2
The diag function is quite sophisticated, since if the function is called for a matrix, rather
than a vector, it tells you the diagonal elements of that matrix. For the matrix A defined
earlier:
octave:##> diag(A)
ans =
5
3
Notice that the matrix does not have to be square for the diagonal elements to be defined,
and for non-square matrices it still begins at the top left corner, stopping when it runs
out of rows or columns.
Finally, it is sometimes useful to create an empty matrix, perhaps for adding elements
to later. You can do this by defining the matrix with an empty pair of braces:
octave:##> E = []
E =
[]
36
9.4 Building composite matrices
It is often useful to be able to build matrices from smaller components, and this can easily
be done using the basic matrix creation syntax:
You just have to be careful that each sub-matrix is the right size and shape, so that the
final composite matrix is rectangular. Of course, Octave will tell you if any of them have
the wrong number of row or columns.
octave:##> t=0:0.2:1;
octave:##> freq=[sin(t)’ sin(2*t)’, sin(3*t)’]
freq =
0 0 0
0.1987 0.3894 0.5646
0.3894 0.7174 0.9320
0.5646 0.9320 0.9738
0.7174 0.9996 0.6755
0.8415 0.9093 0.1411
Here the nth column of the matrix contains the (sampled) data for sin(nt). The alternative
would be to store each series in its own vector, each with a different name. You would
then need to know what the name of each vector was if you wanted to go on and use the
data. Storing it in a matrix makes the data easier to access.
octave:##> J = [
1 2 3 4
5 6 7 8
11 13 18 10];
octave:##> J(1,1)
ans =
37
1
octave:##> J(2,3)
ans =
7
octave:##> J(1:2, 4) %Rows 1-2, column 4
ans =
4
8
octave:##> J(3,:) %Row 3, all columns
ans =
11 13 18 10
The : operator can be used to specify a range of elements, or if used just by itself then it
refers to the entire row or column.
These forms of expressions can also be used on the left-hand side of an expression to
write elements into a matrix:
octave:##> J(3, 2:3) = [-1 0]
J =
1 2 3 4
5 6 7 8
11 -1 0 10
38
eye Create an identity matrix
zeros Create a matrix of zeros
ones Create a matrix of ones
rand Create a matrix filled with random numbers
diag Create a diagonal matrix, or extract the diagonal of the given matrix
inv Inverse of a matrix
det Determinant of a matrix
trace Trace of a matrix
eig Calculate the eigenvectors and eigenvalues of a matrix
rank Calculate an estimate of the rank of a matrix
null Calculate a basis for the null space of a matrix
rref Perform Gaussian elimination on an augmented matrix
lu Calculate the LU decomposition of a matrix
qr Calculate the QR decomposition of a matrix
svd Calculate the SVD of a matrix
pinv Calculate the pseudoinverse of a matrix
Table 6: Basic matrix functions and decompositions
octave:##> A = [
3 0 4
0 1 -1
2 1 -3];
octave:##> inv(A)
ans =
0.1429 -0.2857 0.2857
0.1429 1.2143 -0.2143
0.1429 0.2143 -0.2143
octave:##> A*inv(A) %Check the answer
ans =
1.0000 0.0000 -0.0000
0 1.0000 0
0 0.0000 1.0000
Again, note the few numerical errors which have crept in, which stops Octave from
recognising some of the elements as exactly one or zero.
The determinant of a matrix is a very useful quantity to calculate. In particular, a zero
determinant implies that a matrix does not have an inverse. The det function calculates
the determinant:
octave:##> det(A)
ans =
-14
39
11 Solving Ax = b
One of the most important use of matrices is for representing and solving simultaneous
equations. A system of linear equations is
a11 x1 + a12 x2 + · · · + a1n xn = b1
a21 x1 + a22 x2 + · · · + a2n xn = b2
.. .
. = ..
am1 x1 + am2 x2 + · · · + amn xn = bm
where the aij and bi are known, and we are looking for a set of values xi that simultaneously
satisfy all the equations. This can be written in matrix-vector form as
a11 a12 · · · a1n x1 b1
a21 a22 · · · a2n x2 b2
.. .. .. .. .. = ..
. . . . . .
am1 am2 · · · amn xn bm
or
Ax = b
In this representation, A is the matrix of coefficients, b are the constants, and x is the
vector of parameters that we want to find.
Since Octave is designed to process matrices and vectors, it is particularly appropriate
to use it to solve these forms of problems.
40
11.2 Gaussian elimination and LU factorisation
Calculating the inverse of a matrix is an inefficient method of solving these problems, even
if Octave can still invert large matrices a lot more quickly than you could do by hand.
From the IB Linear Algebra course, you should be familiar with Gaussian elimination, and
LU factorisation (which is just Gaussian elimination in matrix form).26 These provide a
more efficient way of solving Ax = b, and Octave makes it very easy to use Gaussian
elimination by defining this as the meaning of matrix division for invertible matrices.
octave:##>A\b ans =
2.8000 0.2000
Note that this is not a standard notation and in written mathematical expressions you
should still always write A−1 b.
You should recall that matrix multiplication is not commutative i.e. AB 6= BA. This
means that, while the solution to AX = B is given by X = A−1 B, the solution to XA = B is
X = BA−1 , and these two expressions are different. As a result, Octave also defines the /
(forward slash) operator which performs this other variety of matrix division. The former
case, however, is more likely, and it is usually the backslash that you will need to use. The
two slash operators are summarised in Table 7.
Table 7: Summary of Octave’s slash operators. These use Gaussian elimination if the matrix is invertible,
and finds the least squares solution otherwise.
u+v+w =2
2u + 3w = 5
3u + v + 4w = 6
26
The rref function will perform Gaussian elimination if you give it an augmented matrix [A b], or
the lu function in Octave will perform the LU factorisation of a matrix (see the help system for more
information).
41
This is again an equation of the form Ax = b. If you try to solve this in Octave using
the slash operator, you get
octave:##>A=[1 1 1
> 2 0 3
> 3 1 4];
octave:##>b=[ 2 5 6]’;
octave:##>x=a\b;
warning: matrix singular to machine precision, rcond = 1.15648e-17
warning: attempting to find minimum norm solution
x =
0.69048
-0.11905
1.09524
octave:##>a*x ans =
1.6667
4.6667
6.3333
So the solution given is not a solution to the equation! Y In this case the matrix A is
singular as OCTAVE had warned. This means that it has a zero determinant, and so
is non-invertible. (Even if there had not been a warning you should perhaps have been
suspicious, anyway, from the size of the numbers in x. This is also seen when checking the
determinant which gives a near-zero number, e.g.
octave:##>det(A)
ans = 5.5511e-16
When the matrix is singular it means that there is not a unique solution to the equations.
But we have three equations and three unknowns, so why is there not a unique solution?
The problem is that there are not three unique equations. The rank function in Octave
estimates the rank of a matrix—the number linearly of independent rows or columns in
the matrix:
octave:##> rank(A)
ans =
2
So there are only two independent equations in this case. Looking at the original equations
more carefully, we can see that the first two add to give 3u + v + 4w = 7, which is
clearly inconsistent with the third equation. In other words, there is no solution to this
equation. What has happened in this case is that, thanks to rounding errors in the
Gaussian elimination, Octave has found an incorrect solution.
42
The moral of this section is that the slash operator in Octave is very powerful and
useful, but you should not use it indiscriminately. You should check your matrices to
ensure that they are not singular, or near-singular.27
11.5 Ill-conditioning
Matrices which are near-singular are an example of ill-conditioned matrices. A problem is
ill-conditioned if small changes in the data produce large changes in the results. Consider
this system: · ¸µ ¶ µ ¶
1 1 1 2
=
1 1.01 1 2.01
for which Octave displays the correct answer:
1.00000
1.00000
Let us now change one of the elements of M by a small amount, and see what happens:
octave:##>M(1,2)=1.005;
octave:##>x=M\b
x =
-0.0100000
2.0000000
Changing this one element by 0.5% has decreased X(1) by approximately 101%, and
increased X(2) by 100%! The sensitivity of a matrix is estimated using the condition
number, the precise definition of which is beyond the scope of this tutorial. However, the
larger the condition number, the more sensitive the solution is to numerical errors. In
Octave, the condition number can be found by the cond function:
octave:##> cond(M)
ans = 402.01
A rule of thumb is that if you write the condition number in exponential notation a × 10k ,
then you last k significant figures of the result should be ignored. Octave works to about
fifteen significant figures, so the number of significant figures that you should believe is
(15 − k). In this example, the condition number is 4 × 102 , so all of the the last 2 decimal
places of the solution should be dropped i.e. the result is perfectly valid.28 For the singular
27
Some singular matrices can have an infinity of solutions, rather than no solution. In this case, the
slash operator gives just one of the possible values. This again is something that you need to be aware of,
and watch out for.
28
This assumes that the values entered into the original matrix M and vector b were accurate to fifteen
significant figures. If those values were known to a lesser accuracy, then you lose k significant figures from
that accuracy.
43
matrix A from earlier, which gave the spurious result, cond gives a condition number of
2.176 × 1016 . In other words, all of the result should be ignored!29
In Octave you can again use the \ operator. For invertible matrices it is defined to
solve the equation using Gaussian elimination, but for over-determined systems it finds
the least squares solution. The pseudoinverse can also be calculated in Octave using the
pinv function, as demonstrated in the following example.
2x − y = 2
x+y =5
6x − y = −5
and these are plotted in Figure 7. However, because of various errors, there is not one
common point at which they meet.
The least squares solution to the intersection point can be calculated in Octave in a
number of different ways once we have defined our matrix equation:
-0.094595
2.445946
octave:##>x=pinv(A)*b
x =
29
The condition number for this singular matrix again shows one of the problems of numerical compu-
tations. All singular matrices should have a condition number of infinity.
44
20
15
10
x+y=5
5
y
6x − y = −5
2x − y = 2
−5
−10
−4 −3 −2 −1 0 1 2 3 4
x
Figure 7: Three lines and the least squares estimate of the common intersection point
-0.094595
2.445946
octave:##>x = A\b
x =
-0.094595
2.445946
All of these, of course, give the same solution. This least squares solution is marked on
Figure 7 with a ‘*’.
12 More graphs
Octave provides more sophisticated graphing capabilities than simply plotting 2D Carte-
sian graphs, again by using GNUPlot. It can also produce histograms, 3D surfaces, con-
tour plots and polar plots, to name a few. Details of all of these can be found in the help
system, additional information can be found in the GNUPlot manual.
The select argument specifies the current graph in the array. These are numbered from
the top left, working along the rows first. The example below creates two graphs, one on
top of the other, as shown in Figure 8.
45
1
0.5
−0.5
−1
−10 −8 −6 −4 −2 0 2 4 6 8 10
0.8
0.6
0.4
0.2
−0.2
−0.4
−10 −8 −6 −4 −2 0 2 4 6 8 10
Figure 8: Example of the subplot command, showing a sine and sinc curve one above the other.
12.2 3D plots
Octave provides a wide range of methods for visualising 3D data. The simplest form of
3D graph is plot3, which is the 3D equivalent of the plot command. Used for plotting
points or drawing lines, this simply takes a list of x, y and z values. The following example
plots a helix, using a parametric representation.30
octave:##> t = 0:pi/50:10*pi;
octave:##> x = sin(t); y = cos(t); z = t;
octave:##> plot3(x, y, z);
The graph is shown in Figure 9. The xlabel and ylabel commands work as before, and
now the zlabel command can also be used. When plotting lines or points in 3D you can
use all of the styles listed in Table 3.
46
35
30
25
20
z
15
10
0
1
0.5 1
0.5
0
0
−0.5
−0.5
−1 −1
y
x
Mouse Actions
Table 8: Mouse and Keybinds for interaction with 3D graphs, (LMB - Left Mouse Button, MMB - Middle
Mouse Button), see also table 4.
The matrices X and Y then contain the x and y coordinates of the sample points. The
function can then be evaluated at each of these points. For example, to plot
47
surf mesh
1 1
0 0
−1 −1
3 3
4 4
2 2
3 3
1 2 1 2
meshz contour
3
1
2.5
0
2
−1 1.5
3
4
2
3
1
1 2 2 2.5 3 3.5 4
Figure 10: Examples of the same saddle-shaped surface visualised using different Octave commands. (The
4 graphs are plotted in the same figure using the command subplot(2,2,i ).)
surf is only one of the possible ways of visualising a surface. Figure 10 shows, in the
top left, this surface plotted using the surf command, and also the results of some of the
other possible 3D plotting commands.
octave:##>load cued
octave:##>colormap(gray(64)) % Tell Octave to expect a greyscale image
octave:##>image(a)
The image command displays this matrix as an image; the colormap command tells
Octave to interpret each number as a shade of grey, and what the range of the numbers
is.32 N.B. Octave uses Imagemagick, by default, as the display program giving the user
full access to file format conversion and printing.
Octave can also create and display movies, but unlike MATLAB this is awkward. It
is hoped to enhance the functionality in this area shortly.
32
Try colormap(jet) for an example of an alternative interpretation of the numbers (this is the default
colormap). The colormap is also used to determine the colours for the height in the 3D plotting commands.
48
13 Eigenvectors and the Singular Value Decomposition
After the solution of Ax = b, the other important matrix equation is Ax = λx, the solutions
to which are the eigenvectors and eigenvalues of the matrix A. Equations of this form crop
up often in engineering applications, and Octave again provides the tools to solve them.
octave:##>A=[1 3 -2
> 3 5 1
> -2 1 4];
octave:##>eig(A)
ans =
-1.5120
4.9045
6.6076
In order to obtain the eigenvectors, you need to provide two variables for the answer:
octave:##>[V,D]=eig(A)
V =
D =
The columns of the matrix V are the eigenvectors, and the eigenvalues are this time re-
turned in a diagonal matrix. The eigenvectors and eigenvalues are returned in this format
because this is then consistent with the diagonal form of the matrix. You should recall
that, if U is the matrix of eigenvectors and Λ the diagonal matrix of eigenvalues, then
A = UΛU−1 . We can easily check this using the matrices returned by eig:
octave:##> V*D*inv(V)
ans =
1.0000 3.0000 -2.0000
3.0000 5.0000 1.0000
-2.0000 1.0000 4.0000
49
13.2 The Singular Value Decomposition
Eigenvectors and eigenvalues can only be found for a square matrix, and thus the decom-
position into UΛU−1 is only possible for these matrices. The Singular Value Decomposition
(SVD) is a very useful technique, which provides a similar decomposition for any matrix.
The specifics are covered in the IB Linear Algebra course, but an outline of the outcome
of the decomposition is given here.
The SVD takes an m × n matrix A and factors it into A = Q1 ΣQT2 , where
• Q1 is an m × m orthogonal matrix whose columns are the eigenvectors of AAT
• Q2 is an n × n orthogonal matrix whose columns are the eigenvectors of AT A
• Σ is an m × n diagonal matrix whose elements are the square roots of the eigenvalues
of AAT and AT A (both have the same eigenvalues, but different eigenvectors)
This is better shown graphically:
QT2
A Q1 Σ ·
· · ·
·
=
m m
m n
· · n · · · m · · · n · · ·
· · n · ·
The most important part of this decomposition to consider is the matrix Σ, the diagonal
matrix, whose elements are called the singular values, σi :
σ1
σ2
..
. 0
Σ= σr
0
..
0 .
0
Being part of a diagonal matrix, these only multiply particular columns of Q1 or Q2 .33 The
size of the singular value tells you exactly how much influence the corresponding rows and
columns of Q1 and QT2 have over the original matrix. Clearly, if a singular value is tiny,
very little of the corresponding rows and columns get added into the matrix A when it is
reconstituted. It is quite common for a matrix to have some zero eigenvalues, as shown
above. These zero elements on the diagonal indicate correspond to rows or columns that
give no extra information. This indicates, of course, that not all of the matrix is useful—
that it is rank deficient. Or, in terms of simultaneous equations, that not all the equations
are independent.
The SVD is a very useful tool for analysing a matrix, and the solutions to many
problems can simply be read off from the decomposed matrices. For example, the null-
space of the matrix (the solution to Ax = 0) is simply the columns of Q2 which correspond
33
The singular values Σ of course multiply the rows of QT2 , and hence the columns of the un-transposed
version, Q2 .
50
to the zero singular values. The SVD is also highly numerically stable—matrices which
are slightly ill-conditioned stand more chance of working with SVD than with anything
else.
octave:##> A=[1 3 -2 3
> 3 5 1 5
> -2 1 4 2];
octave:##> svd(A)
ans =
8.9310
5.0412
1.6801
S =
V =
51
-0.661559 0.047326 0.109729
-0.079700 -0.885056 -0.455551
-0.683516 -0.135631 0.307898
octave:##> U*S*V’ % Check Answers
ans =
Note that Octave automatically orders the singular values in decreasing order.
octave:##> [U,S,V]=svd(A)
U =
S =
9.52552 0.00000
0.00000 0.51430
0.00000 0.00000
V =
-0.61963 -0.78489
-0.78489 0.61963
If we then consider the multiplication A = U*S*V’, we can see that the last column of U
serves no useful purpose—it multiplies the zeros in S, and so might as well not be there.
Therefore this last column may be safely ignored, and the same is true of the last row of
S. What we are then left with is matrices of the following form:
A Q1
· · Σ QT2
· · · ·
=
m
m n n
· · · n · · n ·
· n · · n ·
Octave can be asked to perform this ‘economy’ SVD by adding ‘,0’ to the function
argument (NB this is a zero, not the letter ‘O’):
52
octave:##> [U,S,V]=svd(A,0)
U =
-0.22985 0.88346
-0.52474 0.24078
-0.81964 -0.40190
S =
9.52552 0.00000
0.00000 0.51430
V =
-0.61963 -0.78489
-0.78489 0.61963
This is highly recommended for matrices of this shape, since it takes far less memory and
time to process.
14 Complex numbers
Apart from matrix and vector computations, Octave also supports many other math-
ematical and engineering concepts, and among these are complex numbers. Complex
numbers can be typed into Octave exactly as written, for example
octave:##> z1=4-3i
z1 = 4 - 3i
√
Alternatively, both i and j are initialised by Octave to be −1 and so (if you’ve not
redefined them) you can also type
octave:##> z2 = 1 + 3*j
z2 = 1 + 3i
You can perform all the usual arithmetic operations on the complex numbers, exactly
as for real numbers:
octave:##> z2-z1
ans = -3 + 6i
octave:##> z1+z2
ans = 5
octave:##> z2/z1
ans = -0.20000 + 0.60000
octave:##> z1^2
ans = 7 - 24i
53
Octave also provides some functions to perform the other standard complex number
operations, such as the complex conjugate, or the modulus and phase of the number,
and these are shown in Table 9. Other functions which have mathematical definitions for
complex numbers, such as sin(x) or ex , also work with complex numbers:
octave:##> sin(z2)
ans = 8.4716 + 5.4127i
octave:##> exp(j*pi) %Should be 1
ans = -1.0000e+00 + 1.2246e-16i
octave:##> exp(j*2)
ans = -0.41615 + 0.90930i
octave:##> cos(2) + j*sin(2) %Should be the same as e^2i
ans = -0.41615 + 0.90930i
x5 + 2x4 − 5x3 + x + 3 = 0
would be represented as
octave:##> c = [1 2 -5 0 1 3];
54
5
−1
−2
−3
−4
−5
−5 −4 −3 −2 −1 0 1 2 3 4 5
Figure 11: Graphical representation of the complex numbers z1 = 4 − 3i and z2 = 1 + 3i using the plot
command.
octave:##> roots(c)
ans =
-3.44726 + 0.00000i
1.17303 + 0.39021i
1.17303 - 0.39021i
-0.44940 + 0.60621i
-0.44940 - 0.60621i
16 Further reading
This tutorial has introduced the basic elements of using Octave. The main document
for the use of Octave is the OCTAVE manual which is included in the MDP distribution
and can be obtained from http://www.octave.org. A print version is also available with
profits going to further development of the code.
In addition there is the on-line help and lists of available functions at
http://octave.sourceforge.net/index and included on the MDP resources.
In addition searching for octave + tutorial on the web reveals a number of on-line
tutorials.
55
Also most of the MATLAB tutorials and textbooks are also relevant, including:
• Getting Started with MATLAB: A Quick Introduction for Scientists and Engineers,
R. Pratap, Oxford University Press, 2002
17 Acknowledgements
This document has been produced as a tutorial to accompany the version of Octave sup-
plied on the Cambridge-MIT Institute (CMI) 34 funded Multidisciplinary Design Project
(MDP) Resource CD 35 .
The text of this tutorial has been adapted from the student notes developed by Dr. Paul
Smith from the Cambridge University Engineering Department for a 2nd year Introduction
to Matlab course. Conversion from Paul Smith’s original to this current document has be
relative easy with in many cases needing only to exchange
• Octave for Matlab in the text
• the prompt and precise format of the answers given in the example scripts
• removal of specific course administration.
However in a number of cases there are significant differences, e.g. graphical performance
(Gnuplot is assumed to be the output plugin for Octave), where changes have had to be
made.
Any success of this tutorial is a major result of the background work carried out by Tim
Froggatt in setting up the MDP resource distribution and requests from Gareth Wilson,
the author of the RED Tools web interface for Octave scripts, for additional information
and scripts.
Significant reference has been made to the resources generated and maintained by John
Eaton and his team at www.octave.org. As indicated above, the tutorial is heavily based
on Paul Smith’s original in which he acknowledges advice and help from Roberto Cipolla,
Richard Prager, Hugh Hunt, Maurice Ringer, David Mansergh and Martin Szummer.
34
CMI - www.cambridge-mit.org
35
MDP - http://www-mdp.eng.cam.ac.uk
56