LICENSE : Article is licensed under GNU FDL Game, Set, Match : GNU Octave Tinkering and Extending Octave Muthiah Annamalai [[email protected]] GNU Octave is a scientific computation tool, used by engineers, and scientists to solve equations, analyze functions, plot and view data, while writing scripts to automate the same. GNU Octave is an interpreter, for Octave language. This article will show you how to use GNU Octave, and extend it so that it fits the problem you will solve. We will take up a simple case study of a real world problems, and show extensions to GNU Octave. GNU Octave & a little bit of history GNU Octave has the potential to make lots of the 're inventing the wheel' kind of problems solved like magic. GNU Octave, its set of libraries and architecture will enable you to make the most out of free software for your work and play. Octave is a complete package, which conceptualizes the matrix as the elementary data type, and assumes the same for solving engineering problems. Octave is free software, released under GNU GPL. Octave is very good in solving problems in linear algebra, vector processing, solving ODE [Ordinary Differential Equations], and other problems cast into the linear algebra problem statement. Essentially, Octave makes life very easy for scientists, and solves problems quickly. Learning GNU Octave is very simple, with the given manual, and info pages. GNU Octave is very friendly to the novice and the expert alike, and informs you of every possible mistake with friendly tips, and error messages. Essentially, Octave makes life very easy for scientists, and solves problems in very little time.Learning GNU Octave is very simple, with the given manual, and info pages. Simpler still, for those folks that want to move away from other proprietary products. Octave was originally intended to be companion software for an undergraduatelevel textbook on chemical reactor design being written by James B. Rawlings of the University of WisconsinMadison and John G. Ekerdt of the University of Texas. GNU Octave is written and maintained by John W Eaton, from Chemical Engineering Dept' University of Wisconsin. GNU Octave was intended to be a clone of a proprietary product, something on the lines of the GNU replacing UNIX. Using Octave, your magic lamp Simple everyday stuff using Octave. Using Octave for everyday calculations, is little more than child's play. Starting octave from your command line is easy; just type [src]$ octave For more options, try 'octave help', and 'man octave' at the command line. Creating a matrix Rows are separated by ';'. Columns are separated by ' ' or ','. eg: to declare a matrix A = | 1 2 | | 2 1 | we define in Octave A = [ 1 2; 2 1 ]; Solving a linear equation could be as simple as writing x=A^1*B Lets solve the system of equations Ax =B. Now we want to find vector x, given matrix A, and B. Let the equations be x + 2y = 4 (1) 2x + y = 5 (2) Then matrix A,B are defined as follows. octave:1> A=[1 2;2 1] A = 1 2 2 1 octave:2> B=[4; 5] B = 4 5 octave:3> x=A^1*B x = 2 1 Working with matrices. [octave]$ octave q octave:1> x=[1 2;3 4]; %comments in Octave begin with a % symbol octave:2> x,det(x) %calculate the determinant of x. x = 1 2 3 4 ans = 2 octave:3> x^1 ans = %calculate 'inverse' of matrix. 2.00000 1.00000 1.50000 0.50000 octave:4> x*x^1 %gives matrix product, of x and its inverse: an identity matrix. ans = 1.00000 0.00000 0.00000 1.00000 octave:5> x' %x' gives x transpose. the same as transpose(x). x = 1 3 2 4 Indexing matrices. You can access matrix elements using the subscripts like this. x(1,1) to get elements of row 1, column 1. Indexing of matrices starts from 1 unlike in standard programming languages. You can access elements of a particular row{column} using the notation x(row_no, : ) { x(:,col_no) }. eg: x(1,:) %prints elements of row 1. ans = 1 3 x(:,2) %prints elements of col 2. ans = 3 4 This indexing mechanism is very useful if we want to access rows, without writing loops, like in C/C++. %We could write summation formula in Octave very easily like this. To get a square of elements of vector v ,we use : y=v.*v; The operators .*, .\, are used to work on individual elements of the vector/matrix to do the respective sum product, or division. This listing shows a simple indexing function to read the members of a matrix. %stepping through a 2D array. %image=round(rand(10,10)*10); image=zeros(10,10); [r,c]=size(image); for i=1:r; for j=1:c; image(i,j)=i+j+image(i,j); end end image Support for complex numbers octave:6> x=3+4i ,real(x) , imag(x),typeinfo(1+5j) %gives real,imaginary parts of complex scalar. x = 3 + 4i ans = 3 ans = 4 ans = complex scalar octave:7> abs(x) %gives modulus value of complex number ans = 5 octave:8> arg(x) , arg(x)*180/pi %argument in radian, degrees. %argument of complex number. ans = 0.9270 ans = 53.130 Octave supports built in constants like pi, e, Nan, NaN, true, false. Try typing 'help' at the Octave prompt, and you will get a nice Octave help informing you of the builtin functions, variables, operators, reserved words, builtin constants, mapper functions , etal. Drawing 3 sine waves with phase difference. hold off t=pi:0.1:pi; for i=1:3; y=sin(2*pi*0.5*t+360/i +45); plot(t,y) hold on end hold off %Plotting with line styles. t=0:0.1:pi*2; plot (t, cos(t), "@3;cos(t);") hold on plot(t, sin(t), "+4;sin(t);"); Bar graphs, contours. [x,y]=bar(1:10,rand(1,10)); %draws a bar graph<br/> plot(x,y) To plot contours of the 3D function we give X,Y,Z arguments like this contour(1:10,1:10,rand(10,10).*10) To draw polar graphs theta=0:0.1:2*pi; polar(theta,2*exp(0.5*theta))%draws a log spiral As you will observe, adding '%' symbols in the input line, marks the rest of the line as comments. A semi colon at the end of a statement suppresses the output. To get help on some command, type help <command name>. eg: help polar will give help information on how to use 'polar' function. Scripts The Octave programming language supports the imperative programming style,like in C/C++. It is just that since matrix, and vector types are also fundamental types here, it makes the whole idea of programming with Octave attractive. To add two matrices in C/C++ we would have to use a two level nested loops,and add them. Not to mention memory allocation, and management. The same could be done in Octave as simple as x=y+z. By the same token, operations like matrix inversion, matrix determinant , products can also be easily performed. List of Octave keywords / reserved words. all varargs end unwind_protect gplot break catch continue endif return else endwhile try elseif for all varargs end unwind_protect unwind_protect_cleanup function end_unwind_protect while end_try_catch global endwhile endfor Writing your first 'Hello World' script in Octave. Open an editor of your choice, and type in program. Save it as hello.m #! /usr/bin/octave q %lets say hello to GNU Octave i=1; while(i < 11) if(i==1) str="time"; else str="times"; end printf("%s %d %s\n","Ive Said Hello",i,str); i++; end %end of hello.m make script executable. $ chmod +x ./hello.m Now invoke it $./hello.m Octave Scripting example. Octave functions go within files, and they are named identically. Lets say we want an Octave function for finding the length of a string, so we would do it like this: function len=strlen(string_ip) end len=length(string_ip); and name the file as strlen.m , which makes it a function file. Script files on the other hand, do not begin with the 'function' keyword. %solving cubic roots of unity. x^3=1; %x^N=(cos(2*pi*k/N) + sin(2*pi*k/N)j) %for each value of k=[0,N1] %calculate the value of the formula function rslt=NthRootsUnity(N) %checks out if there are enough arguments to proceed. if nargin < 1 disp('usage: NthRootsUnity(order)\n Solves the X^n = 1 problem') return end for iter=0:N rslt(iter+1)=cos(2*pi*iter/N) + sin(2*pi*iter/N).*i; end end The idea of using nargin, is to make the script robust, when no arguments are passed to it. Thus we may secure our code, against erroneous execution by using 'nargin' variable. To check the type of the arguments, typeinfo() function may also be used. Operators in Octave. Apart from the standard logical operators [and & &,or ||,not !],standard arithmetic operators [assignment/equality =,post/pre increment ++,post/pre decrement ,+= ,= ,/= ,*= , It is possible to have multiple return values. The builtin function size() return both the row length and column length of the given matrix. Though recursion is not encouraged, it is supported. As Octave is an interpreted language, making Octave functions recursive, only sweats the processor, and reduces efficiency. Choose maintaining your own stacks, or even better writing custom functions, if you want recursion. %prototype of size() must be like this function [r,c]=size(matrix) r=rows(matrix) c=columns(matrix) end Now that you can use a few inbuilt functions,or from external'm' file, and dynamically loaded '.oct' files from the distribution, we still might not have all the functionality we need from Octave. What if you wanted to draw pixel graphics from Octave to an Image ? The solution presents itself; we either code a new image library in Octave for saving to formats, or port an existing library [eg: ImageMagick, GD, LibPng etc] to Octave. We will see more of this in section 4. Well that brings us to writing custom functions. We may use functions, that are external (not builtin) to the octave interpreter. These can either be Octave language functions present in the directory, or dynamic loaded functions that are present as .oct file in the directory. These functions are loaded into your workspace by Octave, as and when you call them, using dynamic loading library like dl. To port functions to Octave, we need to understand the working of the Octave architecture, and type system to flex our powers to [re]use third party libraries from Octave. We will show you how to make new functions, and even new libraries accessible from GNU Octave. Architecture of Octave The blueprint of the genie.Octave explored, inside out. GNU Octave is written in C++. Octave includes a type system for the computing environment, and supports many mathematical primitives like scalar, vector, matrix, and complex number types. The Octave type system forms the core of the Octave functionality, and how it provides a uniform interface to the variables, and functions from the Octave interpreter. You will see how real concepts like polymorphism, and encapsulation help simplify the design of a visibly complex idea: a uniform interface to all types. The other half of Octave is the interpreter for the Octave language. The Octave language, has a shelllike structure, and keywords. A lexical analyzer and a parser are included within, that create an abstract syntax tree [AST] from the Octave interpreter input line or the source file, and pass it to the interpreter which does the bulk of the work. We will confine our interest to extending the functionality of types provided by GNU Octave, rather than extend the Octave language or hack around its language implementation. At leisure you may also lookinto the internal implementation of a few GNU Octave builtin commands, its pipe to GNU Plot. The type system is built on an semiabstract type called "octave_value" , [a self referential structure], which provides virtual functions for the types, default member function actions, and standard type registration code,and header definitions for implementing derived types. This octave_value sits on the top of all derived objects,where it provides the choice to override the virtual function to suit the derived type or simply use the default virtual function implementations. By this all objects will have to support the same function call interface, so that every type is handled equally. The type system due to its inheritance model can be explained by this tree diagram [see figure]. Complex types and simple types support the same API, with extensions built for the nonstandard functions a type may require. You will see that C++ templates are extensively used within Octave type system implementation. Base types like octave_value, octave_scalar, octave_base_scalar go on to build types like octave_matrix , octave_complex, and octave_complex_matrix . Thus we see the whole type system acts to identify. Need for Octave Type System ● Introspection The type of the object can be found at runtime.This dynamic binding is called as RTTI in C++, but its implemented manually by Octave, not the C++ library, leading to Octave itself being portable across many different platforms. ● Polymorphism We can build types that have the same interface, but behave differently. For example we may need a scalar type that counts some modulo n, then we may simply derive from the octave_base_scalar and override its operations and member functions. ● Reuse You save programmer time by reusing the defined types, and extending them to your needs. For example the array type is a template. So types of complex array, vector, scalar, boolean arrays are simply available to the programmer, without extra work;thanks to type system. An Octave type An Octave type consists of some boiler plate code, that does operations like registering the type with Octave interpreter, define an allocator for this type, and have type_id, and type_name accessors functions. Much of every Octave type has the same worker functions like 1.print prints type to stdout, 2.save/load to save and read the type to/from a file,in ASCII format, or even serializing the object. 3.is_[WANTED_TYPE_NAME]_type this kind of functions are to query the object for itstype. We may choose to implement them to return a boolean value. Generally variants of this function are like is_matrix_type, is_numeric_type, is_scalar_type, where you will substitute WANTED_TYPE_NAME with the type names like 'string', 'matrix' etc. 4. [NEW_TYPE_NAME]_value this class of functions try to change the current type into a new type. We may choose to convert the same, or return an error. Typical function available are like string_value, range_value, map_value, matrix_value, uint_value. Unary operators, binary operators Octave supports special operations to your type when you specify unary operators. We may add two matrices by the + operators. Likewise you could use different operators to suit the need of a type. Binary operators, and unary operators can be customized to how they work with your custom types. With this functionality we could use +,,*,/ operators with a custom type octave_image to represent rotations, addition, subtraction, zooming of images. Thus operators declared for a type are available to the Octave system via the Octave interpreter. We may declare function using the particular unary operator with the our type as follows. friend octave_value do_binary_op (binary_op op, const octave_value & a, const octave_value & b); friend octave_value do_unary_op (unary_op op, const octave_value & a); Operators must be defined and installed within the registering logic. Octave Type System, inheritance model. Type identification Every Octave type has an the Octave type id and a type name which is used for runtime introspection. Each octave type implements the functions register_type() string type_name() string class_name() int static_type_id() where in you may use functions like typeinfo() within the Octave interpreter to understand the variable's type. A typical function might use code like this to check types within the interpreter. if(typeinfo(x) == "matrix") %do processing else %report error endif Extending Octave How to make full use of Octave libraries for your work and extend the functionality that GNU Octave provides. Also you may extend your application/program, by embedding the Octave interpreter within your application. This is similar to GIMP which embeds Scheme, and you can use Octave to script your application from Octave. To embed Octave, within your program, you have to link against the shared Octave libraries. #include <iostream> #include <octave/octave.h> using namespace std; int main(int argc,char *argv[]) { int embedded; octave_main(argc,argv,embedded=0); return embedded; } Setting the embedded flag to 1 indicates the octave_main() Octave interpreter is running in the background. You may choose to make it an interactive session if you set embedded to 0. Now the value of embedded controls if the Octave interpreter goes into the readevalwrite loop of the program, or just waits for the program to supply it with input. Compile the program as a stand alone executable with the command. [octave]$ mkoctfile embed.cpp linkstandalone o embed [octave]$ ./embed q #this sets the Octave to start quietly. embed:1> version ans = 2.1.50 embed:2> exit [octave]$ You may easily embed the Octave engine within your application,and if you also wrap the application API to Octave, you could easily script the application in Octave. So you could automatelots of stuff! Ive really not tried this, but it is feasible. Extending Octave. Octave has lots of custom functions in the '.m' scripts, and functions that come by default, installed at /usr/share/octave/$VERSION/m/. Sometimes, home made solutions are the best, and could choose to extend Octave functionality for one of these reasons. ● Speed Optimization ● Custom Functions ● Library Function Speed Optimization: Octave language function/script is slow. This is very true. For large loops, iterations, and recursive solutions, its worthwhile moving code to custom functions, or using different solution, as the overhead of using large loops within Octave language itself is too high. Time for execution of routines that are written as extensions, are 5 to 6 times faster than the equivalent Octave functions. Custom Functions: You want a functionality that is not present with Octave. Assuming you need an ANN function for use from Octave, and currently none exists. Actually, you have a choice here. You could use write custom functions to export the ANN functionality to Octave, and call the functions from here, or ask some one else to do it! Library Functions: You want a whole library for use within Octave. Say you need to use Image Processing primitives for use in Octave, from a library [GD]. Then you could generate the library bindings for Octave, using the code generators, for automatically generating the glue code/ custom functions. Your first custom extension: Octave extensions are loaded dynamically when you invoke the function. Octave, will look for shared objects, or dynamically linked files, with the same name, and then load the function into memory from that SO/DLL file. Afterward the function is evaluated. To write a simple octave extension, just do this. /* magichash.cpp */ #include<ostream> #include<octave/oct.h> #include<vector> #include<string> using namespace std; DEFUN_DLD(magichash, //Function Name args, //input arguments , //output arguments "A Magic Hash Generation Functions:")//document string { string strval; static int hash=0; if((args.length() < 1 ) || !args(0).is_string()) { cout<<"Usage: magichash(string)"<<endl; return octave_value(); } strval=args(0).string_value(); cout<<"Im Magic Hash"<<endl; for(int i=0;i<strval.length();i++) { hash=(int)strval[i]+hash; hash=hash%0xffff; } return octave_value(hash); } /* mkoctfile magichash.cpp -o magichash.oct */ [octave]$ octave -q octave:1> magichash("wow") Im Magic Hash ans = 349 [octave]$ Now you could guess that this function tries to generate a hash for an object based on previous state, and the current object. We will want a function that takes only a simple string, and returns a [something like a!]hash for that string. To write this function we ought to fill up the whole function withinthe DEFUN_DLD macro with the arguments like function name, input arguments,output arguments, description. This exports the function name into the shared object. Now the arguments 'input' with the name 'args' if of the type octave_value_list, which holds a list of input arguments. You can use all the member functions, of the octave_value_list type, found in /usr/include/octave$VERSION/octave/ovlist.h and each element of this list is of the type octave_value, whose member functions we will use to find out the type of the input variable. We actually check if there are enough arguments, and if the argument is of the type string. The octave_value, being a polymorphic type, we could easily get the value it contained, and extract the string. octave_value Member functions are listed in ov.h. finally we just do our operation, and then return the value to octave, as an octave_value() or a derived type of octave_value() You can use types of Matrix, Vector, Array, Cell etc,from within the dynamic loaded functions, and do linear operations on them, while returning the values. This is very useful when people want to write fast algorithms for random number generators, signal samplers etc. You call this octave on steroids. There are lots of useful code written to extend Octave using this custom functions, like plPlot library used for advanced graphing/plotting, gsl: gnu scientific libraries, tcltk GUI bindings, libjpeg,libpng extensions etc. Octave Internal Architecture & dynamic loading with GTK. Our group , OctaveGTK is working on GTK bindings for Octave, whose architecture is give in the diagram. It also gives you an idea of how the whole dynamic loading works in Octave. Calls are routed to the destination library from Octave, as if it were real telephone calls, from one telephone exchange to another; the Octave function calls executing C library functions. Now you can see the arrows leaving Octave run time enter the GTK+ runtime and come back with the return value from the C runtime, into Octave. Handling callbacks becomes a bit tricky, along with memory management, which OctaveGTK team is working on. Personally I wanted to use the GD library with Octave, as I thought GD library API was very simple to do Image drawing, read/modify/write operations. So at school, I wrote gdOctave, for some image processing tasks at hand. Like most other language bindings, gdOctave generates the extensions functions for GD, using the code generator. It reads the function definitions from the GD header file, and auto generates the functions which call the native GD functions, while managing type conversions of Octave and C types, either way. GDOctave is a simple example of extending Octave for use with different libraries. The advantage GD gives you is, that you can easily perform operations on Images without worrying about the binary format, file types, etc, and just bother about processing it,in a interpreted environment. Image creating using GDOctave extensions from Octave. You can get GD Octave from http://freshmeat.net/projects/gdoctave/ and try using it for your imaging needs. That I've shown you how to glue new code into Octave, as well as embedding existing libraries within Octave, you can easily try a few hacks of your own. Conclusion: Where next Now that you've read and felt the power of Octave, to use it and extend it is your next task. To use Octave, just open your terminal and start doing things right away. Read the manual, info and help pages as you progress through the learning curve of Octave. To install Octave you can get the sources/binaries from the site www.octave.org, and install it. Octave generally comes prepackaged with major distributions like Fedora Core, Mandrake, Debian, so users needn't bother about the installation itself. Many of Octave extensions are collected at one single point, the OctaveForge package. Get the octaveforge package from http://octaveforge.sourceforge.net/. Try and look into the Octave extensions for, Image, Audio, Symbolic Algebra, and Calculus to Econometrics, Plotting packages, which people have contributed. Developers, willing to contribute to Octave, can look into the source code and extra packages like octaveforge, and get the tarballs from the sites, given in the reference section. You can write new extensions, and also mail the changes on Octaves mailing lists. You must consider signing up with the Octave mailing lists, and watch the progress. You would also like to know about similar packages that are free or free for noncommercial use like lush, Q, scilab. Scilab, from INRIA France, is very attractive nonfree, noncommercial software that offers similar computation aids for the problems. Thats all Octave neophytes! Its game, set and match to interactive scientific computing: Octave. Bibliography 1.www.octave.org : primary site, for latest tarballs, and Octave sources. 2. wiki.octave.org : wiki web, that host documents on hacking Octave. 3. http://octaveforge.sourceforge.net/ : extra Octave packages for signal,audio, image processing, symbolic computing, econometrics etal 4. http://freshmeat.net/projects/gdoctave/ : gdoctave gd library binding for Octave. 5. [email protected]: Developers mailing list 6. [email protected]: End users help list; has moderate traffic. 7. Octave Manual: invoke this by typing $]info octave 8. octaveconfig: script for developers to discover octave installation paths, version etc 9. mkoctfile: Octave extension programs are easily compiled using the 'mkoctfile' script invoked as $]mkoctfile magic.cpp o magic.oct 10. "The Octave Interpreter, and possibilities of using it to implement an Octave to C++ compiler": Jens Rucknagel, Technical University of Ilmenau, www.tuilmenau.de, [email protected] 11. http://octavegtk.sourceforge.net/ : octavegtk bindings project. 12. http://freshmeat.net/projects/gdoctave/ : gdoctave gd library binding for Octave. Muthiah Annamalai, is an Engineering student from NITTrichy, India expecting to graduate this year, 2005. When Muthu's is not writing free software, or technical articles in programming or engineering, he plays cricket, writes poetry, and likes to cook spicy food.
© Copyright 2025 Paperzz