Documente Academic
Documente Profesional
Documente Cultură
Chapter
VI. Computation
The McGrawHill
Companies, 2011
37
Using Octave
We present a very brief introduction to the open-source, free mathematical language known
as Octave. Octave replicates many of the features of the commercial package Matlab. We
decided to use it in this book because it is free and has many functions that can be accessed
from the web. Almost all the syntax of Octave corresponds to that of Matlab, so students
may eventually migrate to Matlab if they so wish (or go from Matlab to Octave as well).
One of the advantages of Octave is that it runs on the Windows, Macintosh, and
Linux platforms. The binary program may be downloaded from http://www.gnu.org/
software/octave/. The index of functions may be accessed at http://www.gnu.org/
software/octave/doc/interpreter/Function-Index.html#Function - Index.
Installation is easy. Plotting in Octave is undertaken using GnuPlot, another free, opensource, and widely used graphics package. GnuPlot is automatically installed when you
install Octave.
We hope that the reader will install Octave and then use the program code provided in
the book and answer keys to try out the derivatives models under study. This is the best way
to learn and retain the ideas of the hundreds of pricing models we present. Here are some
simple commands that are useful to get you started using Octave.
37.1
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
the program le. Usually, the convention for naming program les is that they end in .m,
so for example, you may have a program le called prog.m.
So, you can call the program code in prog.m by using the following command:
>> prog
The system will automatically assume the .m le extension.
For Loops
Writing loops uses the [for ... end] wrapper. Here is a loop that computes the factorial of
the number n.
octave:1> n=6; fact=1; for j=1:n; fact = fact*j; end; fact
fact = 720
Briey, this is what we programmed. We initialized n = 6. Then we initialized the factorial
fact to be unity. The loop ran over index j from 1 to n, each time multiplying the previous
value of fact by the next value of j. When the loop was nished, we just typed fact without
a semicolon at the end to get the result. When you type a statement with the semicolon, it
suppresses displaying the result.
We could also have done the same less economically as follows:
octave:2> n=6;
octave:3> fact=1;
octave:4> for j=1:n; fact = fact * j; end;
octave:5> fact
fact = 720
While Loops
Loops may also be implemented using the [while ... end] statements. Here is the same
example as above, implemented differently:
octave:10> n=6; fact=1; j=n; while j>0; fact=fact*j; j=j-1; end; fact
fact = 720
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
947
uses a double equal-to sign, not just one. The recursive function call is in line 5. Save this
function le in the working directory, and then call the program as follows:
octave:3> fact(6)
ans = 720
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
37.2
x];
The function ones(m,n) creates a matrix of ones of dimension m rows and n columns.
Finally, we run the regression as follows:
octave:19> ols(y,x)
ans =
0.25025
0.44932
This returns the required values from the regression, which are a=0.25025 and b=0.44932.
Help
All canned functions in Octave come with a help function. For example, if we wanted to
know how to specify the regression syntax, we could have typed
help ols
and we would have obtained the following:
octave:20> help ols
ols is the user-defined function from the file
/sw/share/octave/2.1.53/m/statistics/base/ols.m
-- Function File: [BETA, SIGMA, R] = ols (Y, X)
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
949
Integration
There are standard numerical integration routines in Octave. The most common one is the
function quad, which uses a quadrature approach. As an example, we will integrate the
normal probability density function over the range (a, +a) as follows:
octave:25> a =
ans = 0.68269
octave:26> a =
ans = 0.95450
octave:27> a =
ans = 0.99730
octave:28> a =
ans = 0.99994
octave:30> a =
ans = 1.00000
octave:31> a =
ans = 1.00000
1; quad(normal_pdf(x),-a,a)
2; quad(normal_pdf(x),-a,a)
3; quad(normal_pdf(x),-a,a)
4; quad(normal_pdf(x),-a,a)
5; quad(normal_pdf(x),-a,a)
6; quad(normal_pdf(x),-a,a)
Hence, we have done the integration many times, going from 1-sigma to 6-sigma, and we
can see that the area under the normal curve increased until we reached unity.
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
Suppose instead that we wanted to do the same integration mechanically without using
the canned quadrature routine. In other words, we want to approximate the integral by a
discrete sum, i.e.,
a
a
(x) d x
(x) x
a
x=a
For example, say we want to do this over the range from (3, +3). First, we create a discrete
small step size, say x = 0.01.
octave:32> dx = 0.01;
Next, we create a vector of discrete values over the entire support, at intervals of x. This
is done as follows:
octave:33> x = [-3:dx:3];
This creates a vector of values {3, 2.99, 2.98, . . . , 2.99, 3}. Finally, we implement the
discrete sum, using the sum function, as follows:
octave:34> sum(normal_pdf(x) * dx)
ans = 0.99734
Note that when we call the normal probability density function and pass to it an entire
vector of values, it returns back a vector of function values. As we can see, the result is
quite accurate and is almost the same as what was obtained using the quadrature function.
In order to increase accuracy, we may take x = 0.001 instead. Here is the result using the
new value:
octave:35> dx = 0.001;
octave:36> x = [-3:dx:3];
octave:37> sum(normal_pdf(x) * dx)
ans = 0.99730
Now we get exactly the same answer as with the quadrature routine.
37.3
X1
1.75552
2.48603
4.28121
4.72918
3.16090
0.31241
1.79625
0.77824
1.14772
2.97055
X2
1.43763
3.30246
4.08831
3.91513
1.32696
0.79171
5.44980
9.00096
8.05371
4.22001
Note that in Octave, you can have only numeric values in a le. We will load the data into
a matrix as follows:
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
951
1.43763
3.30246
4.08831
3.91513
1.32696
0.79171
5.44980
9.00096
8.05371
4.22001
The load function stores the data in a matrix that has the name of the input le without
its sufx. Hence, the data matrix in memory is called mydata. The program only reads in
lines that do not have a % sign in front of them. Hence, when creating the data le, you can
have a header line but comment it out so that it is not read in. The load function will also
not work with non-numeric data.
If we want to store the variables separately, we can always slice pieces off the main
data matrix as follows:
octave:43> x1 = mydata(:,1)
x1 =
1.75552
2.48603
4.28121
4.72918
3.16090
0.31241
1.79625
0.77824
1.14772
2.97055
The slice took all rows and the rst column of mydata and stored it in a vector x1. If we
wanted rows 35 and columns 12, we would do the following:
octave:44> mydata(3:5,1:2)
ans =
4.2812
4.7292
3.1609
4.0883
3.9151
1.3270
4.0883
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
4.7292
3.1609
3.9151
1.3270
Sorting
Say we want to sort the mydata matrix in the order of the rst column. This is done using
the sort function as follows:
octave:47> x = mydata(:,1)
x =
1.75552
2.48603
4.28121
4.72918
3.16090
0.31241
1.79625
0.77824
1.14772
2.97055
octave:48> [S,I] = sort(x)
S =
0.31241
0.77824
1.14772
1.75552
1.79625
2.48603
2.97055
3.16090
4.28121
4.72918
I =
6
8
9
1
7
2
10
5
3
4
We began by extracting the rst column of the data and storing it in a variable x. Next we
called the sort function, which returns two columns of data: S, which is the sorted column
of data, and I the index of the sort. The index returns the positions of the elements of
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
953
the sorted column instead of the sorted values. Since the sixth element is the smallest, it
appears rst in the vector I. Likewise, the fourth element is the largest and appears last.
We now use the index vector to obtain the sorted list of the second column of data as
follows:
octave:49> x2 = mydata(:,2)
x2 =
1.43763
3.30246
4.08831
3.91513
1.32696
0.79171
5.44980
9.00096
8.05371
4.22001
octave:50> x2(I)
ans =
0.79171
9.00096
8.05371
1.43763
5.44980
3.30246
4.22001
1.32696
4.08831
3.91513
Note that we wanted the second column of data in the sort order based on the rst column
of data. Hence, we used the statement x2(I), which means to return the elements of x2
indexed by I. Hence, the sixth element of x2 appears rst, and the fourth element appears
last.
Finding
The find command is very useful to extract slices of data based on some criterion. This is
best illustrated with an example. We use the same mydata from above. Suppose we wanted
to collect all values of x2 (the second column of data) when the value of x1 (the rst column
of data) is greater than 3. First lets print out mydata one more time:
octave:51> mydata
mydata =
1.75552
2.48603
4.28121
4.72918
3.16090
1.43763
3.30246
4.08831
3.91513
1.32696
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
0.31241
1.79625
0.77824
1.14772
2.97055
0.79171
5.44980
9.00096
8.05371
4.22001
We can see that there are only three cases in which the values in the rst column are greater
than 3, i.e., the elements 3, 4, and 5. We use the following commands to obtain the index
set of these elements:
octave:52> x1 = mydata(:,1);
octave:53> I = find(x1>3);
octave:54> I
I =
3
4
5
The function find contains a mathematical condition (x1>3) and returns an index vector
containing the element numbers that satisfy the criterion. Next we use this index vector just
as we had done in the previous section to obtain these specic elements of x2.
octave:55> x2(I)
ans =
4.0883
3.9151
1.3270
We obtain the desired subvector based on the index set. If we want to know how many
elements there are, we simply use the function length:
octave:56> length(I)
ans = 3
What if we run the find command on the entire matrix?
octave:57> find(mydata>3)
ans =
3
4
5
12
13
14
17
18
19
20
The result is self-explanatory. However, note that the numbering (indexing) is column by
column.
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
37.4
955
Equation Solving
Equation solving is a useful tool. In many cases in nance, we need to nd roots of equations
in parts of our numerical analyses. The following example demonstrates how easy it is to
undertake this in Octave:
octave:59> fsolve(2*x^2-12*x+3,1)
ans = 0.26139
We solved the equation 2x 2 12x + 3 = 0 and passed the starting value of 1. What if we
used a different starting value?
octave:59> fsolve(2*x^2-12*x+3,6)
ans = 5.7386
We get a different answer, which is not surprising, since the equation is a quadratic and there
are two solutions. The example highlights the care required in numerical work because one
needs to make sure that the root we obtain is the one we require.
37.5
Screenshots
Figure 37.1 is a screen shot demonstrating how to call the normal distribution probability
density function and plot it with a background grid. The gure also shows the commands
needed to generate the plot.
FIGURE 37.1
Generating a Normal
Probability Density
Plot
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
Figure 37.2 is a screen shot showing how to program nested loops and then plot a 3-D
graph.
Figure 37.3 is a screen shot showing the use of various statistical functions.
Figure 37.4 is a screen shot showing how to solve a system of simultaneous equations
using matrix algebra. This solves the matrix equation AX = B. Check the result yourself
by typing: A*X.
FIGURE 37.2
Nested Loops and 3-D
Plots
FIGURE 37.3
Basic Statistical
Functions
SundaramDas:
Derivatives: Principles and
Practice
VI. Computation
The McGrawHill
Companies, 2011
FIGURE 37.4
Solving a System of
Equations
957