A Plotting Application for GNU Octave

114 downloads 152805 Views 3MB Size Report
ments for the award of Bachelor of Engineering, in the school of Electrical, Computer .... Application Programming Interface - A generic interface, usu-.
A PLOTTING APPLICATION FOR GNU OCTAVE ABHINAY MUKUNTHAN

BACHELOR OF ENGINEERING (COMPUTER ENGINEERING)

October, 2007

SUPERVISOR: Dr DANIEL FRANKLIN

Abstract

GNU Octave is an interpreted language for science and engineering, similar to Matlab. It uses various third party applications to provide a complete scientific package. One of these applications, gnuplot, is an old but capable plotting application. Unfortunately, it does not have a user-friendly interface. It also lacks several features of modern plotting applications, such as Matlab’s plotting interface. The main objective of this thesis is to create a new plotting application for Octave in Qt, a cross-platform graphical widget toolkit. The application is intended to be part of a future initiative to create a complete cross-platform GUI for Octave. To date, the plotting framework has been completed. The interface between Octave and the application has also been completed and 2D cartesian plots can now be obtained. Several features such as a “grid” and “zoom” have been implemented. The underlying framework has been tested thoroughly for bugs, and has been refactored several times to improve efficiency. This report discusses the design methodology behind the application, its implementation, as well as the results of benchmarks performed on the application.

i

Statement of Originality

I, Abhinay Mukunthan, declare that this thesis, submitted as part of the requirements for the award of Bachelor of Engineering, in the school of Electrical, Computer and Telecommunications Engineering, University of Wollongong, is wholly my own work unless otherwise referenced or acknowledged. The document has not been submitted for qualification or assessment at any other academic institution.

Signature

........................

Print Name

........................

Student ID Number . . . . . . . . . . . . . . . . . . . . . . . . Date

........................

ii

Contents Abstract

i

Statement of Originality

ii

List of Figures

vi

List of Tables

viii

Glossary of Terms

ix

1 Introduction

1

1.1

Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.2

Aim of the Thesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.3

Report Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

2 Literature Review 2.1

2.2

2.3

2.4

3

Introduction to Scientific Plotting . . . . . . . . . . . . . . . . . . . .

3

2.1.1

Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3

2.1.2

GNU Octave . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

Matlab’s Type ystem . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

2.2.1

Handle Graphics . . . . . . . . . . . . . . . . . . . . . . . . .

5

2.2.2

Functions for “Handle Graphics” . . . . . . . . . . . . . . . .

5

2.2.3

Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

Octave’s Type System . . . . . . . . . . . . . . . . . . . . . . . . . .

6

2.3.1

Extending Octave with C++ . . . . . . . . . . . . . . . . . .

7

2.3.2

Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

Analysis of Existing Plotting Applications for Octave . . . . . . . . .

8

iii

2.5

2.4.1

Gnuplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.4.2

Grace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.4.3

Octplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.4.4

Other plotting applications . . . . . . . . . . . . . . . . . . . . 15

2.4.5

Comparison of existing Plotting Applications . . . . . . . . . . 15

Introduction to GUI programming . . . . . . . . . . . . . . . . . . . . 16 2.5.1

GUI Toolkits . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.5.2

Choosing a Toolkit . . . . . . . . . . . . . . . . . . . . . . . . 17

2.5.3

Multitasking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Application Architecture 3.1

3.2

3.3

3.4

9

20

Initialising the Application . . . . . . . . . . . . . . . . . . . . . . . . 20 3.1.1

Process vs Thread . . . . . . . . . . . . . . . . . . . . . . . . 20

3.1.2

Qt and Threads . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Using Handle Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2.1

Analysis of Handle Graphics in Matlab . . . . . . . . . . . . . 22

3.2.2

Handle Graphics in Oqtplot . . . . . . . . . . . . . . . . . . . 22

Architecture of Oqtplot . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.3.1

The root Class . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.3.2

Communication between Octave and Oqtplot . . . . . . . . . 24

3.3.3

Assigning Handles . . . . . . . . . . . . . . . . . . . . . . . . 25

3.3.4

Manipulating Objects

3.3.5

The plot() function . . . . . . . . . . . . . . . . . . . . . . . 28

. . . . . . . . . . . . . . . . . . . . . . 26

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4 Implementation and Performance

31

4.1

Key Features Implemented . . . . . . . . . . . . . . . . . . . . . . . . 31

4.2

Screenshots of Implemented Functions . . . . . . . . . . . . . . . . . 33

4.3

Performance Benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3.1

Test 1: A 2,000,000 point plot . . . . . . . . . . . . . . . . . . 35

4.3.2

Test 2: 10 cumulative plots of 2,000,000 points each . . . . . . 36

4.3.3

Conclusions from Benchmarks . . . . . . . . . . . . . . . . . . 36

5 Conclusions and Future Work

37 iv

5.1

5.2

Thesis Progress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 5.1.1

Architecture Design . . . . . . . . . . . . . . . . . . . . . . . . 37

5.1.2

Feature Implementation . . . . . . . . . . . . . . . . . . . . . 37

5.1.3

Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Future Recommendations

. . . . . . . . . . . . . . . . . . . . . . . . 38

Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 A Original Project Specifications

41

B Project Plan

42

C Supervisor Signatures

43

D Software Documentation

45

D.1 Structure of Oqtplot . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 D.2 The Oqtplot API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 D.3 Communication with the root class . . . . . . . . . . . . . . . . . . . 46 D.3.1 Analysis of the

oqtfigure () function . . . . . . . . . . . . 46

D.4 A simple activity diagram . . . . . . . . . . . . . . . . . . . . . . . . 47

v

List of Figures 2.1

A representation of the “Handle Graphics” Class Model . . . . . . . .

5

2.2

Example of a class in the Octave Type System . . . . . . . . . . . . .

7

2.3

Screenshot of gnuplot, displaying two plots on a canvas . . . . . . . .

9

2.4

Screenshot of gnuplot, displaying two plots on two canvases . . . . . . 10

2.5

Comparison of gnuplot, Grace and Octplot’s subplot functions . . . . 11

2.6

Screenshot of Grace, showing two plots on a canvas . . . . . . . . . . 12

2.7

Screenshot of Octplot displaying two plots on a canvas . . . . . . . . 13

2.8

Screenshot of Octplot two plots on two canvases. . . . . . . . . . . . . 14

2.9

2D and 3D plot with Octaviz . . . . . . . . . . . . . . . . . . . . . . 15

2.10 Creation of a Process and a Thread . . . . . . . . . . . . . . . . . . . 19 3.1

Design and usage of the oqtHandle class . . . . . . . . . . . . . . . . 23

3.2

Handle Graphics in Oqtplot . . . . . . . . . . . . . . . . . . . . . . . 23

3.3

Root Class in Oqtplot . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.4

Connection Diagram between Octave and Oqtplot . . . . . . . . . . . 25

3.5

A sample set of Objects and Handles . . . . . . . . . . . . . . . . . . 25

3.6

Adding a curve in Oqtplot . . . . . . . . . . . . . . . . . . . . . . . . 26

4.1

Simple screenshot of Oqtplot . . . . . . . . . . . . . . . . . . . . . . . 32

4.2

Screenshot showing Zoom tool in use with several concurrent plots . . 33

4.3

Screenshot showing Data cursor in use with a normal grid . . . . . . 34

4.4

Screenshot showing minor grid in use . . . . . . . . . . . . . . . . . . 34

B.1 Gantt Chart for the Project . . . . . . . . . . . . . . . . . . . . . . . 42 C.1 Supervisor signatures for Autumn session . . . . . . . . . . . . . . . . 43 C.2 Supervisor signatures for Spring session . . . . . . . . . . . . . . . . . 44 vi

D.1 Activity diagram for the plot() function . . . . . . . . . . . . . . . . 48

vii

List of Tables 2.1

Feature Matrix of Gnuplot, Octplot, Grace and Matlab . . . . . . . . 16

4.1

Timing results for plotting 2,000,000 points from various applications (in seconds) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2

Timing results for 10 cumulative plots from various applications (in seconds) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

viii

Glossary of Terms API

Application Programming Interface - A generic interface, usually in source-code provided to a programmer by a library.

Class

An abstracted data type, with attributes and functions

Command-line

An application that interacts with the user only via text commands

Cygwin

An implementation of several POSIX standards for Windows

FLTK

An LGPL Licensed cross-platform GUI programming toolkit based on C++

GNU

Acronym for GNU is Not Unix. A GPL licensed operating system which hosts several projects including Octave

GPL

The GNU Public License - A popular open-source license

GTK+

A GPL Licensed cross-platform GUI programing toolkit, based on C

GUI

Graphical User Interface

LGPL

A modified version of the GPL, allowing static linking to closed-source applications

Motif

A non-GPL Unix-based GUI programming toolkit

Octave

An interpreted language similar in form and function to Matlab, part of the GNU project

Open-source

Refers to any source code that is freely available to anyone to modify and distribute

Platform

An operating system, with a unique native API, such as Windows and POSIX (Linux/Mac OS X)

ix

Pointer

A data type, which points to an arbitrary variable address in memory, allowing it to represent any data type

POSIX

Portable Operating System Interface - A set of standards specified by the IEEE to define the API for the variants of Unix

Qt

A GPL Licensed cross-platform GUI programming toolkit, based on C++

Qwt

Qt Widgets for Technical Applications. A set of plotting widgets for Qt

Socket

A method of inter-process communication. Can be implemented in a variety of ways such as Unix Domain Sockets or Internet(TCP/UDP) Sockets

TCP

Transfer Control Protocol - An Internet Protocol used to transfer data as bytes, which may be used on a local computer

Type System

A system of storing any data, as different types, including user defined classes

x

Chapter 1 Introduction

1.1

Overview

GNU Octave [1] is a free and open-source alternative to Matlab. It currently uses a third party application named gnuplot [2], to generate 2D and 3D plots. Gnuplot is a scientific plotting package, developed by Thomas Williams and Colin Kelley with an emphasis on being small and portable while still supporting several input interfaces such as the command line or a simple GUI wrapper. [3]. While it is a very capable plotting application, it does not have a modern GUI. Any modification to a displayed plot, needs to be applied from the interface of choice, which in this case is the Octave command-line. This requires the user to learn and use text commands for simple tasks, such as labelling the axes or changing the colour of a plot. Additionally, the command-line must be used for other operations such as saving displayed plots.

1.2

Aim of the Thesis

The main aim of this thesis is the creation of a modern plotting application for Octave. The term modern is not easily definable. Hence, it is helpful in this instance to use an application such as Matlab as a benchmark.

1

CHAPTER 1. INTRODUCTION

2

Matlab is used commercially, and is generally considered a standard for scientific applications that deal with matrix algebra. Compatibility with Matlab is also one of the aims of the Octave project, and hence, a plotting application that is able to deliver on this aim is essential. Given the aim of this thesis, the name “Octplot” sounds appropriate. Unfortunately, a project with this name already exists [4]. Thus, a new name, “Oqtplot” was coined, referring to the fact that the application will be designed with the Qt widget toolkit. Henceforth, in this thesis the application will be referred to as Oqtplot.

1.3

Report Structure

Chapter 2, the Literature Review, will discuss Matlab’s type system and the “Handle Graphics” plotting architecture, followed by a look at Octave’s type system. This will be followed by an analysis of the various plotting applications available for Octave and a comparison of the existing systems. Graphical User Interfaces will be discussed towards the end. Chapter 3 will discuss the architecture of Oqtplot, and compare it with Matlab’s “Handle Graphics” plotting architecture, as well as discuss in detail several key aspects of the Oqtplot architecture. Chapter 4 will cover the current implementation of Oqtplot, and present benchmarks with competing applications. Finally, Chapter 5 will discuss conclusions from this thesis, including recommendations and future work.

Chapter 2 Literature Review This Literature Review will first briefly introduce scientific plotting followed by a discussion of Matlab and Octave’s type systems, and how they correlate to their existing plotting architectures. This will be followed by an analysis of the various plotting applications available for Octave. Finally, the basics of GUI programming will be covered.

2.1

Introduction to Scientific Plotting

Scientific Plotting is vital in fields such as Mathematics and Engineering. The ability to accurately study data is critical in experiments and analysis. At present, there are several applications that perform both data analysis and plotting. Matlab and Octave are both such applications, designed around the concept of Matrix algebra. They are the two applications most relevant to this thesis and will be discussed in this chapter.

2.1.1

Matlab

Matlab is a commercial application that has been in development for over 20 years. It is a very mature platform that is used extensively both in academia as well as the industry. It also has one of the most sophisticated plotting architectures, which will be studied in greater detail later in this chapter. 3

CHAPTER 2. LITERATURE REVIEW

4

The name Matlab refers to both the Matlab programming language, as well as the Matlab application. The application includes a command-line driven console, as well a collection of GUI extensions which allow the user to graphically manipulate data such as matrices and objects such as plots.

2.1.2

GNU Octave

GNU Octave is a free and open source alternative to Matlab. It was initially conceived around 1988 as an accompaniment for a textbook on chemical reactor design, at the University of Wisconsin [5]. It was developed further in 1992, leading to a full 1.0 release in 1994. It was licensed under the GPL, a free and open-source software license, as part of the GNU Project1 , hence the name “GNU Octave” [1]. Like Matlab, the name Octave has a dual meaning. Firstly, it represents the Octave programming language, which is mostly compatible with the Matlab programming language. Secondly, the Octave Interpreter, a command-line interface similar to the Matlab console, which executes Octave code. The Octave Interpreter can also be used to run user-defined functions written in Octave, or dynamically loaded functions written in C, C++ or Fortran among other languages [6].

2.2

Matlab’s Type ystem

Matlab’s type system allows for a limited degree of object oriented programming. It supports the use of classes as abstract data types, but does not allow direct access to member functions. For example, class attributes are set using a separate set() function. Matlab’s plotting architecture is closely related to its type system, in that all classes are modified with “handles”. An extension of this concept, called “Handle Graphics”, was added when Matlab’s plotting widget was introduced, to cope with the new GUI-centric approach to plotting. 1

The GNU Project, http://www.gnu.org

CHAPTER 2. LITERATURE REVIEW

2.2.1

5

Handle Graphics

“Handle Graphics” is an object-oriented plotting system used by Matlab [7] and more recently, Octplot. Figure 2.1 shows a slightly simplified version of the “Handle Graphics” class structure. All the objects in the “Handle Graphics” class structure are represented as “children” of the objects above them. Root

Figure

Axes

Image

UiControl

Line

Surface

UiMenu

Text

etc...

etc...

Figure 2.1: A representation of the “Handle Graphics” Class Model Each class seen in Figure 2.1 can only be invoked when an instance of its parent class has been created. An instance of the “root” class is created by default when Matlab is run, thus allowing other classes to be created. Each class also has a separate “handle”. The handle is a value of the specific class, depending on its properties. Each set of properties produces a unique handle, which is usually a floating point number. The handle is not necessarily meaningful to the user, as it is used internally by Matlab to keep track of the location of the object. The handle is also used by Matlab to manipulate the objects themselves. Hence, passing a handle of the axes to the delete() function, will delete the axes.

2.2.2

Functions for “Handle Graphics”

Matlab implements several functions for managing the “Handle Graphics” architecture [8]. The plotting functions themselves return the handle of the object when called. For example, the following piece of code gets the handle of the curve from the plot function and stores it in the variable plhandle.

CHAPTER 2. LITERATURE REVIEW

6

x = [0:0.01:20]; plhandle = plot(x, sin(x)); With this handle, the object can be manipulated with the set() function. For example, the statement set(plhandle, ‘color’, ‘red’) sets the color attribute of plhandle to red. Similarly, a get() function is available to find the value of a certain attribute, as can be seen in the example below. The value returned is an RGB value, indicating that the color attribute is indeed red. get(plhandle, ‘color’) ans = 1

2.2.3

0

0

Review

Handle Graphics is an extension of Matlab’s own type system. The set() and get() functions are applicable to almost every custom data type in Matlab. It is an elegant system in theory, and works well in practice.

2.3

Octave’s Type System

Octave’s type system is superficially similar to that used by Matlab; however, it is different in a number of important respects. The “handle” system used in Matlab is absent in Octave, thus making it harder to maintain compatibility with Matlab when creating a new class. Octave allows extensions to be written in several languages, such as C++ and Fortran [6], and loaded dynamically into the type system [6]. Functions can also be overloaded within Octave using the dispatch() function [9], thus allowing for the implementation of functions such as set() and get() to mimic those in Matlab.

CHAPTER 2. LITERATURE REVIEW

7 Legend

Octave Functions

Var Types Data

In−built functions

Built−in Items Scalar

User−defined Items

Matrix octave_value

Etc..

DEFUN_DLD() Class q Function create_q() Function callx_q()

Variable a Variable b

Function set() Constructor() dispatch()

Function x()

DEFUN_DLD()

Function seta()

Function qset()

Function setb()

Figure 2.2: Example of a class in the Octave Type System

2.3.1

Extending Octave with C++

Figure 2.2 shows an example of a sample class q, written in C++ and inserted into the Octave type system. In the Figure, class q has 2 variables and 4 functions. The constructor() initialises the class, while x() is an example of another function. The functions seta() and setb() set the values of a and b. In C++, the member functions of a class can be accessed via the instance of the class using the dot (.) operator, or the arrow (->) operator for pointers. However, in Octave, the member functions cannot be accessed directly. Other individual C++ functions need to be loaded into Octave’s list of functions, in order to create and manipulate the class. This can be seen in Figure 2.2. The qset(), callx q() and createq() functions are created independent of the class, and written in C++. They are then loaded into Octave using the DEFUN DLD() function in Octave. When called from Octave, the createq() function creates an instance of the class q and returns a pointer to that instance, wrapped in an octave value data type, to Octave’s data memory. This pointer can then be passed into different functions, such as callx q() and qset(), which utilise it to call the functions in the class in standard C++, as required. The set() function, is overloaded to call qset() when an object of type q is passed to it. This can be achieved with the built-in dispatch() function in Octave.

CHAPTER 2. LITERATURE REVIEW

2.3.2

8

Review

Octave’s type system, while similar to Matlab’s, does not support “handles”. It instead relies on the programmer to use the dispatch() function to overload customised functions, and hence mimic the functionality of Matlab functions such as set() and get(). Additionally, instead of passing a handle to a function, Octave usually passes an object pointer.

2.4

Analysis of Existing Plotting Applications for Octave

This section analyses the existing plotting applications for Octave. The applications covered will be: • Gnuplot[2] - The default plotting application for Octave; • Octplot[4] - An open-source alternative, based on the handle graphics method used in Matlab, and written in the FLTK2 Widget Toolkit; • Grace Plot[10] - Another open-source alternative, written in the Motif3 Widget Toolkit, a ; • GLPlot[11] - Another alternative, written in the GTK4 Widget Toolkit, which has not been developed since January 2004 and • Octaviz[12] - A 3D plotting application for Octave. GLPlot will not be covered in much detail, since it is currently unmaintained. Octaviz, being a 3D-oriented application, will not be covered in much detail either since the focus of this thesis is on 2D plotting. 2

Fast Light Toolkit, http://www.fltk.org Motif, http://www.opengroup.org/motif/ 4 The GIMP Toolkit, http://www.gtk.org 3

CHAPTER 2. LITERATURE REVIEW

9

Figure 2.3: Screenshot of gnuplot, displaying two plots on a canvas

2.4.1

Gnuplot

Gnuplot is a capable plotting system. It is a command-line application which has been developed independent of Octave. The architecture of Gnuplot can be better represented if it is looked at as an engine for plotting graphs. The engine can be accessed via the default command-line interface, or via a multitude of other interfaces, which includes Octave. Gnuplot’s support of graph types is its strongest feature. It supports almost all the types of 2D plots supported by Matlab, and supports a decent set of 3D plots as well. However, it provides an unfriendly interface and lacks several features, such as basic scaling and translation.

Interface The gnuplot interface is controlled entirely from the command-line. The interface consists only of the plot and the accompanying axes and labels. A screenshot of a sample gnuplot image is shown in Figure 2.3. As can be seen in Figure 2.3, there are no interface elements that allow plot manipulation. Gnuplot, when used with Octave, does not support scaling or translation

CHAPTER 2. LITERATURE REVIEW

10

Figure 2.4: Screenshot of gnuplot, displaying two plots on two canvases of the plot. While the newest version of Gnuplot (4.2) does support basic scaling, that particular function is not implemented in Octave at present. It also does not allow precise readings to be taken from the graph, a feature which is invaluable in several experiments. Furthermore, a GUI option to label the graphs is not provided. To label the above plot, for example, the following commands must be used; ylabel("This is the y axis") xlabel("This is the x axis") title("Graph of y=sin(x)")

While these commands are available in Matlab as well, the modern user interface should allow for a graphical means of editing labels. This is especially useful in instances where multiple plots are on the same canvas.

Multiple plots Currently, gnuplot does not support renaming a plot once another plot has been displayed. An example of this can be seen in Figure 2.4. In the Figure, the labels on the first canvas cannot be set since the second canvas has already been plotted. Gnuplot also does not support arbitrary number of plots per row/column. This

CHAPTER 2. LITERATURE REVIEW

11

feature is useful when plotting several plots at the same time. This can be better illustrated with an example. The following piece of code will produce different plots in gnuplot, Octplot and Grace. Matlab also supports this feature and produces a graph similar to Octplot. subplot(2,1,1); plot(x,y); subplot(2,2,3); plot(x,z); subplot(2,2,4); plot(x,q);

Figure 2.5 illustrates Octplot’s ability to plot an arbitrary number of plots per row/column. The above code instructs the plotting application to initially create 2x1 matrix of canvases, and a plot a figure on the first canvas. The application is then instructed to create 2 rows and 2 columns and plot to the first canvas on the second row. This is where the difference arises. Octplot, simply creates the canvas currently requested of it, ignoring the existing canvases. Gnuplot redraws the entire figure, when the row/column configuration is changed. Grace maintains the current plot, by shifting it to the new row/column layout. For example, if the plot was 2,1,1, it is moved to 2,2,1.

Figure 2.5: Comparison of gnuplot, Grace and Octplot’s subplot functions

2.4.2

Grace

Introduction Grace is a 2D plotting application which was created as a fork of Xmgr, a plotting application written in Motif, a toolkit for the Unix platform. While Grace comes with more features than gnuplot, it is not used by default with Octave. An im-

CHAPTER 2. LITERATURE REVIEW

12

Figure 2.6: Screenshot of Grace, showing two plots on a canvas plementation of Grace as an interface for Octave does exist in Octave-forge [13], a set of extra functions for Octave, which implement functions from various Matlab toolboxes. Grace has an excellent interface, which allows for almost all the features present in the Matlab plotting application. However, it suffers from several bugs, especially with multiple plots. Furthermore, the use of the Motif toolkit makes porting the software to platforms other than Unix/Linux difficult.

Interface Of all the applications discussed in this review, Grace has the most usable interface. The interface, seen in Figure 2.6, has an abundance of features. It supports scaling, and translation of the graph. It also allows for editing of the plot and the labels as options in the menus. The only drawback with the interface is the presence of the cryptic buttons seen on the left of Figure 2.6. However, these can be hidden if required. There is also an option to save the plots to different formats.

CHAPTER 2. LITERATURE REVIEW

13

Figure 2.7: Screenshot of Octplot displaying two plots on a canvas Multiple Plots In the process of testing Grace, several bugs were discovered with the implementation of multiple plots. They were seemingly random, and hence difficult to explain. One of the major bugs discovered was the inability to change the subplot mode correctly when a new figure was created with the figure() function. Furthermore, while switching between plots, the plot would often be plotted on the wrong canvas. Once again, this was a random error. A review of the list of bugs on the Grace forum revealed no knowledge of these issues. It is therefore likely that bugs exist in the Octave-forge implementation of the Grace-Octave interface.

2.4.3

Octplot

Introduction Octplot was created as a replacement for Gnuplot, specifically for Octave, based on the “Handle Graphics” method in Matlab. Octplot is written in “FLTK”, a C++ toolkit similar to Qt. It is being developed rapidly as an alternate 2D plotting

CHAPTER 2. LITERATURE REVIEW

14

Figure 2.8: Screenshot of Octplot two plots on two canvases. application for Octave, with 3D support planned in the future. Currently, Octplot supports almost all the command line functions of Octave. It is still in active development and is a promising candidate for the replacement of gnuplot, at least in the realm of 2D plots. However, Octplot still does not satisfy the requirement of being usable to the new user. Several items, such as saving plots and modifying labels, still require the user to be familiar with command-line.

Interface As can be seen in Figure 2.7, Octplot shares gnuplot’s minimalist interface. It has no visible buttons or other interface elements. However, unlike gnuplot, Octplot does have a usable scale (zoom) tool and a data cursor. An example of this can be seen in Figure 2.8.

Subplots Another advantage of Octplot, is the ability to create subplots with an arbitrary number of rows and columns. This was illustrated in figure 2.5, in section 2.4.1.

CHAPTER 2. LITERATURE REVIEW

15

Figure 2.9: 2D and 3D plot with Octaviz

2.4.4

Other plotting applications

GLPlot GLPlot is a plotting application for Octave, written in GTK+. It has not been maintained since January 2004. The source code provided on the site does not compile, since it requires packages that are no longer maintained. Thus, the application was not tested. The application does seem to have a usable interface, as judged from the screenshots on its homepage. However, the inability to compile it prevented the application from being covered in more detail.

Octaviz Octaviz is a 3D plotting application for Octave, programmed in VTK5 , an opensource 3D toolkit. Octaviz also provides minimal support for 2D plotting. Figure 2.9 shows sample plots from Octaviz. As can be seen, the interface is minimal, and the application is focused mainly on 3D rendering.

2.4.5

Comparison of existing Plotting Applications

Table 2.1 shows a simplified feature-matrix of gnuplot, Octplot and Grace. This table does not compare the types of graphs supported by the various applications, since that was not deemed a necessary aspect of this Thesis. A feature list of the 5

The Visualization Toolkit, http://www.vtk.org/

CHAPTER 2. LITERATURE REVIEW

16

Matlab plotting application is also displayed, to provide a point of comparison. As can be observed from Table 2.1, Matlab’s Plotting application is the most complete application among the four. While Grace comes closest in terms of features, it has a very buggy interface with Octave, and is prone to misinterpreting data. Octplot uses an implementation of the “Handle Graphics” system, which allows support for most of the features in Matlab. However, due to its user interface, access to these features remains on the command line.

Gnuplot Octplot Grace Matlab

Scale

Translate

Pan

Cursor

Subplots∗

X √

X

X

X √

X √



X √

X √







√ √

X √

Colours†

Labels √c

Saving √c

√c

√c

X √c

√c/g

√c/g

√g

√c/g

√c/g

√c/g

‘*’ subplots in this case refers to the ability to arbitrarily plot multiple plots. (Section 2.4.1) ‘†’ Colours refers to the ability to change colours after initial plotting ‘c’ refers to the ability to manipulate a parameter through the Octave command-line ‘g’ refers to the ability to manipulate a parameter through a GUI

Table 2.1: Feature Matrix of Gnuplot, Octplot, Grace and Matlab

2.5

Introduction to GUI programming

A GUI is essentially a method of viewing, accessing and modifying data displayed on a screen with a keyboard and/or a mouse. It is different from the command line, because it allows several tasks to be displayed and executed at the same time. In modern systems, the ability to perform multiple tasks is fully supported by most operating systems. In the scope of this thesis, the latter is very important, since it involves interacting with a graphical application mainly from the command-line. It is thus necessary to ensure that the command line is usable at the same time as the GUI, such that the user can still perform tasks on it while displaying a plot. This can be achieved through “multitasking”.

CHAPTER 2. LITERATURE REVIEW

2.5.1

17

GUI Toolkits

To simplify the process of programming on various platforms, several multi-platform toolkits exist. These toolkits aim to provide a unified Application Programming Interface (API) across different platforms. This makes it possible to port an application across platforms with minimal effort. Furthermore, most toolkits are created as a means of abstracting complicated system calls into a more unified human-readable set of commands. In the case of C++ based toolkits, it is made even easier due to the use of classes as abstract data types. This allows the toolkit to group similar modules, reducing redundancy and making it easier for the programmer to understand them.

2.5.2

Choosing a Toolkit

The Qt widget toolkit [14] was chosen for this project over toolkits such as GTK+6 or FLTK7 . The main reason for this choice was the excellent documentation provided [15], and the existence of an actively developed set of graphing libraries for Qt, named Qwt [16]. Qwt is equally well documented. Qt and Qwt are also open-source, and are based on C++, thus making integration with Octave simpler. Qt is also cross-platform, and compiles natively on Linux, Windows and Mac OS X. It also integrates with the native environment of each of the mentioned Operating Systems.

2.5.3

Multitasking

Threads and processes are the two main methods of allowing tasks to run simultaneously on a computer. Their implementations differ on every major platform. This section will focus only on POSIX-compliant [17] threads and processes, since the primary focus of this thesis is on Linux based systems, which are POSIX compliant. Furthermore, both Mac OS X and Windows (through Cygwin) [18], are POSIX compliant, thus simplifying the process of porting the application in the future. 6 7

Gimp Toolkit, http://www.gtk.org Fast Light Toolkit, http://www.fltk.org

CHAPTER 2. LITERATURE REVIEW

18

Key features of Processes On a POSIX system, a process is created by means of a fork() system call. When this call is performed by a process, memory is copied from the parent process to the newly “forked” child. This allows the child process to access any data that was available to the parent before the fork() command was issued. Communication between a parent and child process is only possible through various inter-process communication (IPC) methods. The most commonly used method is a socket. There are three commonly used types of sockets, each with a similar API [19]. These are TCP sockets, UDP sockets and Unix Domain sockets. All the aforementioned sockets are similar in that they require the data to be abstracted in a specific structure and sent as a byte stream.

Key features of Threads On a POSIX system, a thread is created by calling the pthread create() system call. Threads are much lighter than processes since they share memory with the parent process [20]. This prevents the unnecessary duplication of memory, and also does away with the need for IPC, since threads can be controlled using shared memory. Threads however, have an inherent problem of synchronisation. Since threads share data and run concurrently with the parent process, there is a strong possibility of the thread and parent attempting to access the same data at the same time. This can lead to memory leaks, and other unforeseen errors. POSIX threads offer two data types that aid in thread synchronisation, mutexes and conditions [21]. The name mutex is an abbreviation of “mutually exclusive”. A mutex can only exist in a locked or unlocked state. When a mutex is locked by a certain thread, any other thread wishing to lock it is blocked, and as a result, waits for the mutex to be unlocked before proceeding. Condition variables, are similar to mutexes and are used in conjunction with them. A condition variable is used block a thread, until a signal is received from another thread. This is helpful in situations where a thread needs to voluntarily be blocked until certain data is ready.

CHAPTER 2. LITERATURE REVIEW

19 pthread_create()

Memory

Memory

x=1

x=1

y="hello" Process A

z=[0,1,2;2,1,0]

y="hello" Process A

z=[0,1,2;2,1,0]

Thread A

mutex socket

condition fork() x=1 y="hello" Process B

z=[0,1,2;2,1,0]

Legend pre−existing data and processes data after fork()/ pthread_create()

(i) Process creation and communication

(ii) Thread creation and communication

Figure 2.10: Creation of a Process and a Thread Comparing Threads and Processes Figure 2.10 gives a simplified comparison the creation of a process and a thread [20]. Thread creation can be 10-100 times faster than process creation [20]. Threads also utilise shared memory, making inter-process communication redundant. However, they are difficult to manage, as great care must be taken to synchronise threads, and prevent memory leaks. Processes, on the other hand are slower to create, but easier to manage. Transferring data between processes is inherently slower than between threads, since data needs to be copied across a socket, or a similar mechanism. Not only does this create a lot of overhead, it also forces the unnecessary duplication of data.

Chapter 3 Application Architecture This chapter focuses on the class design of Oqtplot, and discuss the reasons for several design decisions, including the use of threads over processes, and the use of the “Handle Graphics” plotting architecture.

3.1

Initialising the Application

Since Oqtplot has to be called from Octave, it needs to run independent of Octave. Not doing so would prevent Octave from functioning as long as Oqtplot is active, which in turn would prevent the user from issuing any commands to Oqtplot. Thus, the plotting application needs to be run separately either a process or a thread.

3.1.1

Process vs Thread

There are several advantages and disadvantages to both approaches. As mentioned in Section 2.5.3, threads are faster to create, and allow faster access to data, due to the use of shared memory. They are however difficult to manage and synchronise. A process on the other hand would require duplication of data, and also require transferring all this data over a TCP socket, which adds unnecessary overhead to it. This is a critical issue, since the plotting application would have to access potentially large amounts of data. A detailed plot can have as many as a million points. It

20

CHAPTER 3. APPLICATION ARCHITECTURE

21

thus makes sense to avoid the duplication of data as much as possible. With this in mind, it is obvious that a thread is the better solution, despite being more difficult to work with.

3.1.2

Qt and Threads

Qt, like most other toolkits only supports one GUI thread in an application, forcing any modification to the GUI to be performed only from this thread. This implies that any other thread wishing to modify the GUI needs a method of communication with the GUI thread in order to do so. Several unsuccessful attempts were made to communicate with the GUI thread using only mutexes and condition variables. Eventually, a TCP socket was determined to be the only method of initiating a connection between Oqtplot and the GUI thread. Once this connection is established however, it is possible to perform other thread synchronisation tasks effectively with mutexes and condition variables. Any adverse effect of using a TCP socket is minimised by using it purely as a connection mechanism. The data is still accessed from shared memory once the connection is established.

3.2

Using Handle Graphics

Recently, plenty of discussion on the GNU Octave mailing lists [22] has led to several calls for a “Handle Graphics” based approach to plotting in Octave. Given this, it seems logical that Oqtplot should be designed around the “Handle Graphics” approach. Furthermore, given that “Handle Graphics” is used throughout Matlab, it would be beneficial to use it as the foundation, should Oqtplot ever be developed into a complete GUI for Octave.

CHAPTER 3. APPLICATION ARCHITECTURE

3.2.1

22

Analysis of Handle Graphics in Matlab

The “Handle Graphics” architecture in Matlab was discussed in Section 2.2. While it is certainly efficient and elegant, Matlab’s implementation of it is slightly outdated. “Handle Graphics” utilises unique floating point numbers to represent an object. While the current system employed by Matlab is elegant, it can be improved to provide the user with more feedback about the object represented by the handle. Furthermore, when using functions such as grid() or plot(), which can have a variable number of arguments, the function should be able to distinguish between an argument and a handle. As seen in the code snippet below, Matlab does this correctly by only recognising the handle if it is passed in as the originally returned variable, and not an equivalent value defined by the user. This creates a bit of ambiguity, and it would be easier if the handle was not such an easily quantifiable data type. >> a=subplot(1,1,1) a = 158.0016 >> grid(158.0016, ’on’) ??? Error using ==> grid at 41 First argument must be an axes handle. >> grid(a, ’on’)

3.2.2

Handle Graphics in Oqtplot

Given the minor inconveniences of the system used in Matlab, it was decided that the handle would be a custom object in Octave. This would allow the handle to hold more information about the object it represents, as well as display this information to the user. Figure 3.1(a) shows the implementation of oqtHandle as a class, and Figure 3.1(b) shows the class as used in Octave. As seen from Figure 3.1(b), the handle now provides information about the precise location of the axes and the figure in which these axes are located.

CHAPTER 3. APPLICATION ARCHITECTURE

23

1> a=subplot(2,1,2) a =

oqtHandle int figure string axes int curve int text char type constructor() print()

stores figure index stores axes index stores curve index stores text index stores type information creates handle based on input displays handle info. to user

Axis Handle (1|2,1,2) 2> grid(a, ’on’) (1|2,1,2)

Figure

(a) Class design of oqtHandle

Axes

(b) oqtHandle in practice

Figure 3.1: Design and usage of the oqtHandle class Root

Figure

Axes

Curve

Toolbar

Text

Figure 3.2: Handle Graphics in Oqtplot

3.3

Architecture of Oqtplot

Oqtplot’s architecture is divided into several classes. As with Matlab’s “HandleGraphics” architecture, each class represents a certain object on the plot. A simplified example of the currently implemented classes can be seen in Figure 3.2. As seen in Figure 3.2, the Root class is the first one created. It controls communication with Octave, as well as the manipulation of its child objects such as Figure and Axes.

3.3.1

The root Class

The root class is first created when Oqtplot is called using the toggle oqtplot() function is called from Octave. This function creates a new thread, and initialises the root class within it. A pointer to the class is exported to Octave’s global memory, to allow the use of mutex and condition variables within Octave. Figure 3.3 shows

CHAPTER 3. APPLICATION ARCHITECTURE

24

oqtRoot QTcpServer map int cur_fig string cur_axes int cur_curve constructor() doAction() addFigure() addAxes() addCurve() processFigure() processAxes() processCurve()

TCP server which receives connections A list of figures, with indices for easy access Stores information about the current figure, axes and curve for reference Initialises the TCP server and calls doAction when it receives a connection Fetches an action from shared memory and calls the respective process function If a figure is being added, create it and add it to the list, and return handle else, call the respective add function, and create and return handle If an object is being created, call the respective add function else, call a process function inside the correct object

Figure 3.3: Root Class in Oqtplot the implementation of the root class. As seen in Figure 3.3, the root class controls the creation and modification of any child object.

3.3.2

Communication between Octave and Oqtplot

As mentioned in Section 3.1.2, communication between Octave and Oqtplot is initiated when a TCP socket connects to the TCP server in the root class. When the root class is first constructed, it creates a TCP server and returns is associated port to Octave’s global memory. In order to send information to the root class, the calling function must first create a new oqtAction object. An oqtAction object is a very simple class, consisting of two variables: • type, a string which stores the type of action to be performed and • arguments, a list of arguments passed into the calling function. Once an instance of oqtAction is created with the necessary variables, it is stored in Octave’s global memory. A TCP Socket is then created and connects to the TCP Server in the root class. As soon as the connection is established, the server calls doAction which accesses the action in memory and processes it. This is illustrated in Figure 3.4, showing steps from the creation of the root object to the retrieval of

CHAPTER 3. APPLICATION ARCHITECTURE

25

Octave (1) create oqtplot root

Oqtplot

toggle_oqtplot (5) connect to server plot(x,y)

TCP Server Global Memory (3) get port (4) set action

TCP_port = 12345

(6) if connected call doAction

(2) set port

Action

doAction

type = add_curve args = (x,y)

(7) get Action and process

Figure 3.4: Connection Diagram between Octave and Oqtplot the action object by the doAction() function.

3.3.3

Assigning Handles

Figure 3.5 shows a sample set of objects, and selected handles. The assignment of handles to any object is a logical process. Each object’s handle is determined by its index, and preceded by its parents’ indices. Thus, the second curve, on axes (2,1,2) on figure 1 will have the handle (1 | 2,1,1 | 2).

Assigning indices The index of an object is the value which determines the location of the object within a certain data structure. For example, the Figures and Axes are stored in a Vector like structure, while the curves are stored in a Linked List. The individual indices are determined differently for each object type. Figure Handle (1) Axes(2,1,2)

Curve(1)

Axes(2,1,1)

Curve(1)

Figure(1) Root Figure(2)

Curve(2)

Curve Handle (1 | 2,1,1 | 2)

Axis Handle (1 | 2,1,1)

Figure 3.5: A sample set of Objects and Handles

CHAPTER 3. APPLICATION ARCHITECTURE

26

oqtRoot

1

QTcpServer map int cur_fig string cur_axes int cur_curve constructor() doAction() addFigure() 4 addAxes() 3 addCurve() processFigure() 2 processAxes() processCurve()

oqtAxes

oqtFigure 5 6 8

map constructor() addAxis() processAxes()

7

map bool hold int cur_colour int cur_curve constructor() addCurve() processCurve() setColour() setGrid()

oqtCurve

9

double xData[] double yData[] constructor()

Figure 3.6: Adding a curve in Oqtplot For a figure object, the index is either automatically determined by an internal counter, or is set by the user. For an axes object, the index is determined by the position of the axes on a figure. Since a figure can have multiple axes, of different configurations, this is essential. For all other objects, such as curve and text objects, the index is determined automatically by an internal counter.

3.3.4

Manipulating Objects

Figure 3.6 shows a brief overview of the main classes in Oqtplot. Also seen in the Figure is the movement of data when the plot() command, is issued. Objects in Oqtplot can be manipulated in almost the same way as they can in Matlab. Several functions such as grid() and hold() have been written, which work well with handles. The set() and get() commands utilise these functions indirectly to manipulate various attributes of an object. The oqtAction class was mentioned in Section 3.3.2. This class is responsible for translating an Octave command, into one that may be processed from the root class in Oqtplot. For example, creating a curve, as seen in the previous example, would pass the action type curve add with the rest of the arguments. The template that has been decided upon for the action type is [object] [action] [hdl], with the hdl being

CHAPTER 3. APPLICATION ARCHITECTURE

27

optional, to indicate the presence of a handle. Some examples of actions issued using this template include: plot(x,y)

--> curve_add

plot(ax, x, y)

--> curve_add_hdl

figure(1)

--> figure_add

grid(ax, ’on’)

--> grid_on_hdl

grid(’on’)

--> grid_on

Algorithm 1 and 2 show how an action is processed by the doAction() function and subsequently the processCurve() function in the root class. Algorithm 1: Algorithm for the doAction() function get action from global memory; if First 6 characters of action→type are “figure” then call processFigure(action); else if First 4 characters of action→type are “axes” then call processAxes(action); else if First 5 characters of action→type are “curve” then call processCurve(action); else call processText(action);

CHAPTER 3. APPLICATION ARCHITECTURE

28

Algorithm 2: Algorithm for the processCurve function Data: action if First 9 characters of action→type are “curve add” then call curveAdd(action); if First 12 characters of action→type are “curve colour” then if Last 3 characters are “hdl” then handle = value of handle in action; figure = value of figure in handle; axes = value of axes in handle; curve = value of curve in handle; else figure = current figure; axes = current axes; curve = current curve; figures[figure]→axes[axes]→curve[curve]→setColour(action→args→colour);

3.3.5

The plot() function

The plot() function is one of the most important functions in the scope of this thesis, since it interprets and delivers the plot data to Oqtplot. It takes a variable number of arguments, and calls another function, usually plot1() or plot2(). As the names suggest, plot1() is called when there is only one set of data to plot, while plot2() is called when there are two sets of data to plot. Each of these functions in turn call the Oqtplot interface function, which does the actual plotting.

CHAPTER 3. APPLICATION ARCHITECTURE Algorithm 3 better explains the workings of the plot() function. Algorithm 3: Algorithm for the plot() function Data: variable Number of Arguments set current argument to 1; while There is at least one argument left do if there are two or more arguments then if current argument is not a string then if Buffer1 is empty then set Buffer1 to current argument; increment current argument; else if Buffer2 is empty then set Buffer2 to current argument; increment current argument; else Call plot2() with data: Buffer1, Buffer2; empty Buffer Variables;

else if Buffer1 is empty then error- first argument cannot be a string; else if Buffer2 is empty then Call plot1() with data: Buffer1 and format: current argument; increment current argument; else Call plot2() with data: Buffer1, Buffer2 and format: current argument; increment current argument;

else if there is only one argument left then if it is not a string then Call plot2() with data: current argument, next argument; increment current argument by 2; else Call plot1() with data: current argument and format: next argument; increment current argument by 2;

else if its not a string then Call plot1() with data: current argument; else error- first argument cannot be a string;

end

29

CHAPTER 3. APPLICATION ARCHITECTURE

3.4

30

Conclusion

The architecture of Oqtplot has been designed with to bear a close resemblance to that of Matlab’s “Handle Graphics”. However, improvements have been made where deemed necessary. This is especially true with the oqtHandle class implementation, which presents the average user a meaningful handle. In theory, this application should perform faster than the existing defaults for Octave due to the use of threads and shared memory, rather than processes and sockets or pipes. The next chapter of the report will discuss the implementation of this architecture, as well as present performance benchmarks.

Chapter 4 Implementation and Performance The previous Chapter discussed the “backend” architecture of Oqtplot. This chapter discusses the frontend, i.e. the interface presented to the user. Currently, the interface of Oqtplot is still quite minimal. A screenshot of the interface can be seen in Figure 4.1. At present, the main emphasis is on improving compatibility with the commandline functions in both Matlab and Octave. This will allow the use of Oqtplot in prewritten scripts without much modification. Additionally, users adept with the command-line would be able to use Oqtplot before major improvements to the GUI are made.

4.1

Key Features Implemented

Currently, Oqtplot has support for the following functions: • Rubber-band Zoom on the GUI; • A Data-Cursor on the GUI; • A Pan function on the GUI; • A fully Matlab-compatible grid function; • A fully Matlab-compatible hold function;

31

CHAPTER 4. IMPLEMENTATION AND PERFORMANCE

32

Figure 4.1: Simple screenshot of Oqtplot • A fully Matlab-compatible figure function and • Fully Matlab-compatible gca and gcf functions. Additionally, the following functions are nearing completion: • plot() function, which currently does not plot matrix-matrix data; • print() function for saving plots; • title(), xlabel() among other functions involving text and • Logarithmic plotting functions. The only critical function not yet completed is the subplot() function. This was due to neither Qt nor Qwt including a layout manager compatible with Matlab-like subplots. Thus, a custom layout manager needs to be written, which will allow for subplot support. The plotting architecture however, is designed to support subplots and this will make future integration of the subplot function, upon completition of the layout manager quite trivial.

CHAPTER 4. IMPLEMENTATION AND PERFORMANCE

4.2

33

Screenshots of Implemented Functions

Figure 4.2, 4.3 and 4.4 demonstrate the various functions that have currently been implemented.

Figure 4.2: Screenshot showing Zoom tool in use with several concurrent plots

4.3

Performance Benchmarks

Octave and Matlab include the tic() and toc() functions, which allow the user to measure the precise time taken to execute a function. This was used to benchmark Oqtplot against other Octave-based plotting applications and Matlab. Since several functions have only been partially implemented, it was not possible to conduct a very extensive set of benchmarks. However, two tests were conducted to observe the performance of various applications under extreme circumstances. All tests were conducted on the same system, under similar load conditions.

CHAPTER 4. IMPLEMENTATION AND PERFORMANCE

Figure 4.3: Screenshot showing Data cursor in use with a normal grid

Figure 4.4: Screenshot showing minor grid in use

34

CHAPTER 4. IMPLEMENTATION AND PERFORMANCE

35

Matlab

Oqtplot

Octplot

Grace

gnuplot

Attempt 1

0.3075

0.72966

0.60502

7.3524

10.410

Attempt 2

0.2113

0.27654

0.27281

6.1465

17.263

Attempt 3

0.1156

0.27621

0.19015

8.8901

18.860

Attempt 4

0.1099

0.27560

0.19093

7.4447

18.927

Attempt 5

0.1116

0.27386

0.18732

6.5694

17.867

Attempt 6

0.1123

0.27658

0.18676

6.7105

17.283

Attempt 7

0.1110

0.27317

0.18626

9.4714

19.143

Attempt 8

0.1101

0.27155

0.18428

6.8710

18.155

Attempt 9

0.1098

0.27054

0.18456

6.9214

17.355

Attempt 10

0.1098

0.27644

0.18375

6.9033

19.023

Attempt 11

0.1100

0.27056

0.18366

6.8784

18.649

Attempt 12

0.1097

0.27068

0.18427

6.9120

18.801

Mean

0.1357

0.31178

0.22831

7.2559

17.645

Table 4.1: Timing results for plotting 2,000,000 points from various applications (in seconds)

4.3.1

Test 1: A 2,000,000 point plot

This test involved generating a 2,000,000 point plot and displaying it with various applications. The test was repeated 12 times to reduce experimental error. The results can be seen in Table 4.1. All times are provided in seconds. As seen in Table 4.1, the fastest plotting application is Matlab. This is no surprise given the years of development that have gone into integrating different parts of Matlab into one unified package. Oqtplot performs slightly worse than Matlab and Octplot. However, these three applications are significantly faster than both Grace and gnuplot. This is probably due to the fact that gnuplot uses a Unix Domain Socket for communication with Octave, while Grace uses a pipe, both of which are slow.

CHAPTER 4. IMPLEMENTATION AND PERFORMANCE

36

Matlab

Oqtplot

Octplot

Grace

gnuplot

Plot 1

0.5495

0.44530

0.34909

7.2597

10.551

Plot 2

0.1148

0.23435

0.18531

7.2613

27.042

Plot 3

0.1153

0.25159

0.18428

7.7284

46.442

Plot 4

0.1178

0.26298

0.18375

7.1387

79.708

Plot 5

0.1209

0.27636

0.19067

11.0804

94.621

Plot 6

0.1228

0.29082

0.19444

6.8532

100.801

Plot 7

0.1196

0.30752

0.19715

9.2779

80.040

Plot 8

0.1211

0.32728

0.18253

9.7604

40.957

Plot 9

0.1196

0.33702

0.22355

10.6018

44.561

Plot 10

0.2989

0.35273

0.17774

10.3241

55.182

Mean

0.1800

0.30860

0.20685

8.72859

57.990

Table 4.2: Timing results for 10 cumulative plots from various applications (in seconds)

4.3.2

Test 2: 10 cumulative plots of 2,000,000 points each

The second test was designed completely as a stress test. It was a modification to the first test, which forced the applications to process and display 10 cumulative plots from Test 1. This placed an extremely large load on the system, which caused gnuplot and Grace to stop responding for several minutes. However, they did finish the test successfully, albeit slowly. The results to this test can be seen in Table 4.2. Once again, Matlab, Octplot and Oqtplot were significantly quicker than Grace and especially gnuplot.

4.3.3

Conclusions from Benchmarks

As seen above Matlab and Octplot are the faster plotting applications at the moment. However, Oqtplot is not far behind. Given that Matlab has been in development for over a decade and Octplot, over a year, Oqtplot, still in its infancy performs reasonably well.

Chapter 5 Conclusions and Future Work

5.1

Thesis Progress

One of the major aims of this thesis was to provide a foundation upon which the open-source community could build. The Oqtplot architecture has been developed successfully, and a uniform API has been provided based on the Qt toolkit, upon which further development may commence. The current Oqtplot application is a good preview of the capabilities of the architecture, and also a useful guide to promote further development.

5.1.1

Architecture Design

The underlying architecture of Oqtplot has been carefully planned and designed to be compatible with Matlab’s “Handle Graphics” architecture. Since Matlab’s architecture extends beyond its plotting capabilities to other GUI related design, it is conceivable that the Oqtplot architecture may be used in the same way.

5.1.2

Feature Implementation

Several features have already been implemented within the timeframe of this thesis. Most of them, such as multiple figure creation and basic vector-vector and vectormatrix plotting have been implemented seamlessly. 37

CHAPTER 5. CONCLUSIONS AND FUTURE WORK

38

However, features such as subplots and bar graphs have not yet been implemented. Furthermore, Matlab also has several infrequently used functions which need to be catalogued, studied and implemented as part of Oqtplot. The author of this thesis wishes to continue working on the application at the conclusion of the thesis, and release it to the open-source community when it is mature enough.

5.1.3

Performance

The performance of Oqtplot has been excellent this early into the project’s life cycle. It compares well with Octplot, the other major graphing platform for Octave, and outshines applications such as gnuplot and Grace, which are included by default with Octave and Octave-forge respectively.

5.2

Future Recommendations

The initial focus will be on refactoring the code to improve efficiency and deal with known issues. Following that, the code needs to be documented thoroughly, so as to facilitate the involvement of other developers. It is hoped that after the project is open-sourced, it will evolve with the help of the Octave community into a full featured plotting application, including support for 3-Dimensional plots. This can be aided by the 3D extension to the Qwt library, QwtPlot3D [23]. Following this, the existing architecture could then be expanded to provide a complete Matlab-like GUI wrapper for Octave.

Bibliography [1] J. W. Eaton. About Octave. [Online]. Available: http://www.octave.org/ about.html [2] The Gnuplot Homepage. [Online]. Available: http://gnuplot.sourceforge.net [3] A. Vaught, “Graphing with gnuplot and xmgr: Two graphing packages available under linux,” Linux J., vol. 1996, no. 28es, p. 7, 1996. [4] S. Ayal, M. Schmid, and B. Roggeri. Octplot - A graphics system for Octave. [Online]. Available: http://octplot.sourceforge.net [5] J. W. Eaton, GNU Octave Manual, 3rd ed.

Network Theory Limited, 1997,

pp. 1–6. [6] M. Murphy, “Octave: A free, high-level language for mathematics,” Linux J., vol. 1997, no. 39es, p. 8, 1997. [7] MATLAB - High-Performance Numeric Computation and Visualization Software: User’s Guide.

24 Prime Park Way, Natick, Mass. 01760-1500: The

MathWorks, Inc., 1992, ch. 2, pp. 101–114. [8] B. Hahn and D. T. Valentine, Essential Matlab For Engineers and Scientists, 3rd ed.

Linacre House, Jordan Hill, Oxford, OX2 8DP 30 Corporate Drive,

Burlington, MA 01803: Elsevier Ltd., 2007, ch. 12, pp. 272–280. [9] S. VanDerWalt and C. Spiel. DaCodaAlFine - Pushing Octave’s Limits. [Online]. Available: http://wiki.octave.org/wiki.pl?DaCodaAlFine [10] Grace Plot. [Online]. Available: http://plasma-gate.weizmann.ac.il/Grace/ [11] J.-M. Valin. Glplot. [Online]. Available: http://glplot.sourceforge.net

39

BIBLIOGRAPHY

40

[12] Octaviz - 3D visualisation system for Octave. [Online]. Available:

http:

//octaviz.sourceforge.net [13] Octave-forge - Extra Packages for GNU Octave. [Online]. Available: http://octave.sourceforge.net [14] Qt widget toolkit. [Online]. Available: http://www.trolltech.com/products/qt [15] Qt Reference Documentation (Open Source Edition). [Online]. Available: http://doc.trolltech.com/4.2/index.html [16] U. Rathmann and J. Wilgen. Qwt - Qt Widgets for Technical Applications. [Online]. Available: http://qwt.sourceforge.net [17] IEEE POSIX Certification Authority. [Online]. Available: http://standards. ieee.org/regauth/posix/ [18] S. Logan. POSIX.1 API Support. [Online]. Available: http://www.sydlogan. com/posix.html [19] R. W. Stevens, UNIX Network Programming, Volume 2, ser. Second Edition. Prentice Hall, 1998, ch. 3, 14. [20] ——, UNIX Network Programming, Volume 2, ser. Second Edition.

Prentice

Hall, 1998, ch. 23. [21] B. Barney. POSIX Threads Programming. [Online]. Available:

http:

//www.llnl.gov/computing/tutorials/pthreads/ [22] Octave-Graphics Mailing Lists. [Online]. Available: http://www.nabble.com/ Handle-Graphics-and-visualisation-applications-in-Octave.-tf3310372.html# a9208275 [23] QwtPlot3d. [Online]. Available: http://qwtplot3d.sourceforge.net

Appendix A Original Project Specifications The primary objective of this project is to create a fully functional plotting application for GNU Octave to replace the existing application, gnuplot. The new plotting application should be at least as functional as gnuplot, and work towards the functionality of the Matlab plotter. Gnuplot is a very reliable but old piece of software. It lacks several user-friendly features present in software such as Matlab, such as zooming or resizing plots. It also does not have an easily accessible interface for outputting graphs to a file. Currently, this is done through a command line interface which is not obvious to the new user. The software developed in this project will be based on the Qt Widget toolkit. There is a set of graphing tools for this toolkit called Qwt. The objective of this project is hence to develop a usable graphing widget and interface it with octave’s type system. The software is intended to be part of a larger effort to create a proper frontend to Octave. The initial emphasis will be on 2D (Cartesian and polar) plots, as there already is a good plotter for 3D figures in Octave (Octaviz). The plotter should support all the basic affine transforms such as translation, scaling and rotation of plots. It should also support the saving and restoration of plots (including the ability to retrieve the data which has been plotted), and an option to allow it to export to a vector/bitmap based image. Finally it should provide a convenient printing tool.

41

Appendix B Project Plan

D 6 0032717/1:0 2 9 7 1 2 v 5 o N 9 2 7 5 1 0 8 tO c0 4 2 7 1 p 3 e S 7 2 0 3 1 2 6 g u 0 A 3 2 6 7 1 0 9 2 l0 u J2 5 8 1 7 4 n u J0 8 1 2 7 4 y a M 3 2 6 7 0 1 9 r0 p 2 A 6 9 7 1 2 rM 5 a2 6 9 1 feacr fteacrhtsnm e c n a n t I n e E g I w r I l d a f U a i r r e c t t W G n t a r r i e i o v i h t t I o o n m P l n d e p p p P i s o A R m a p T s e a r R S 4 P e n Q v G S E R R s S P e a n n n 5 u s D e e m t m t m m t g g g x c c h K v v a n n p O e i a c f / u u T a r o i i i g j o N W W r r r e t t t 5 T p p p c u l r e o k O Q Q O i A A A B S S S P L v p s s l e i M D R R ihTseSTB 4 4 W 1.213.15.617.21.23.31.23.14.234. Figure B.1: Gantt Chart for the Project

42

Appendix C Supervisor Signatures

Figure C.1: Supervisor signatures for Autumn session

43

APPENDIX C. SUPERVISOR SIGNATURES

Figure C.2: Supervisor signatures for Spring session

44

Appendix D Software Documentation This appendix discusses the usage of Oqtplot as a plotting application for Octave. Firstly, a brief discussion of Oqtplot’s structure is presented, followed by a discussion on its usage.

D.1

Structure of Oqtplot

Oqtplot is broken down into two broad areas, the classes and the functions. The classes are all created or loaded inside the Oqtplot thread, while most of the individually defined functions are meant for use with Octave. Among the functions, most functions are defined as .m files, implying that they are Octave functions. The functions defined as .cc or .oct are C++ functions, which are used by various Octave functions to access Oqtplot. Octave’s naming convention states that all functions that need not be accessed directly by the user start and end with a double underscore. An example of this is oqtfigure .cc. Furthermore, it is preferable if all functions accessed by the user were Octave functions. They are easier to debug, and also more transparent to the user, should there be an error.

45

APPENDIX D. SOFTWARE DOCUMENTATION

D.2

46

The Oqtplot API

Oqtplot’s API is an attempt to closely mimic the Matlab API, but with Qt based classes. Hence, the Oqtplot class structure is very similar to Matlab’s. The root class allows the creation of every other object in Oqtplot. The root class is first initialised by the function toggle oqtplot. This function creates a new thread with Qt’s GUI loop, and initialises the root class inside this loop. Any function wishing to create or modify an object first needs to communicate with the root class.

D.3

Communication with the root class

As mentioned in Chapter 3, all communication with the root class is triggered by a TCP connection. When connected, the doAction() function in the root class grabs an oqtAction variable from Octave’s global memory, and uses it to determine the next course of action. The oqtAction class holds only two data members, the type of action, and a list of arguments to be passed on to the respective function. The type of argument is represented as follows: [object]_[action]_[handle] The handle argument is optional, and is only used if the calling function passes a handle.

D.3.1

Analysis of the

A look inside the

oqtfigure () function

oqtfigure () function will better explain the communication

structure. octave_base_value tmp = get_global_value("__oqtRoot__").get_rep(); oqtRoot *root = &((oqtRoot&) tmp);

APPENDIX D. SOFTWARE DOCUMENTATION

47

The above statement creates an instance of the root class, from Octave’s global memory in order to access the mutex variables. oqtAction *newAction = new oqtAction( "figure_process", args); set_global_value("__oqtAction__", octave_value(newAction)); The action variable is then created and sent to Octave’s global memory. root->mutex.lock();

//create socket and connect to it oqtSocket *newSocket = new oqtSocket(); newSocket->newConnection(); delete newSocket;

//set condition variable and wait for the condition to be met root->condition.wait(&root->mutex);

//pthread_mutex_unlock(&root->mutex); root->mutex.unlock(); Upon connecting to the root class through the socket, the doAction() function is called. When doAction() terminates, it would have added the handle of the current figure to Octave’s global namespace. In order to synchronise this function with doAction(), the mutex is used. When doAction() terminates, it emits a condition.wakeAll() signal, which wakes the condition variable in the

oqtfigure () function, thus allowing it to continue and

grab the handle from memory. return get_global_value("__current_figure__");

D.4

A simple activity diagram

To better illustrate the flow of information between Octave and Oqtplot, Figure D.1 shows the sequence of data flow through the application.

APPENDIX D. SOFTWARE DOCUMENTATION

48

Octave Root Process

Octave’s Memory

Shared Memory (2) create

create

oqtAction

Matrix x

copy pointer

toggle_oqtplot

oqtSocket (1) copy

oqtHandle a

(5) copy

(3) create

a=plot(x,sin(x))

oqtPlot Thread

oqtHandle

(3) set handle

call on connect (1) (1)

int figure string canvas int curve

create

oqtRoot

(2) call

(4) copy

copy pointer

connect when created

x=[0:0.1:10] QTcpSocket newConnection()

string type octave_value args constructor()

set_global_value()

(1) get action

QTcpServer map int cur_fig string cur_axes int cur_curve constructor() doAction() create addFigure() (2) call addAxes() (2) call addCurve() processFigure() processAxes() processCurve()

get_global_value()

oqtFigure

oqtAxes

map constructor() create addAxis() processAxis()

map bool hold int cur_colour int cur_curve constructor() create addCurve() setHold() selectColour() setGrid()

oqtCurve double xData[] double yData[] constructor()

Figure D.1: Activity diagram for the plot() function

Legend Thread Class Variable Function Process