# An Introduction to Rlab: A High Level Language for Scientific and Engineering Applications

One of the benefits of the C language is the ability to create data structures to suit a particular programming task. Rlab offers a similar programming construct called a list. In their simplest form, lists are single-dimension associative arrays. However, since list elements can be strings, numbers, arrays, functions, and other lists, they provide a powerful multi-dimensional tool. Lists are created in a manner similar to numeric arrays:

> l = << 3*pi ; rand(3,4) ; > type = "my-list" >> l = 1 2 type

The **<< >>** delimiters contain
the list elements, with **;** separating the
elements. The **=** is used to assign an index name
(which cannot be numeric) to an element, as in the third element of
the list above. If a list element is not assigned an index, then a
numeric value is assigned by default, as in the first two
elements.

Elements of a list are referenced by their index:
**l.["type"]** returns the string
**"my-list"**, and **l.[1]** returns
the value of **3*pi**. In the case of explicit index
names, shorthand notation can be used: **l.type**
will also return the string **"my-list"**.

List indices can be replaced by expressions that evaluate to
a string, or a numeric-scalar, allowing users access to selected
elements in an automated fashion. If **index** is a
variable containing the string **"type"**, the
expression **l.[index]** will access the
**type** element and return the string
**"my-list"**. If **index** contains
the number 1, **l.[index]** will return
**9.42**. Lists will be discussed again later in the
article.

Rlab provides the user with conditional and if-statements for conditional execution, for and while-statements for looping capability, and functions or subroutines. These capabilities will be introduced as we proceed with some examples.

Rlab functions are a little unusual, and deserve some attention. Functions, while not first class, are objects, referred to with variables. Thus, to create and save a function, it must be assigned to a variable. The function argument passing and variable scoping rules were designed to facilitate creation of larger programs and program libraries. Our first example, integrating an ordinary differential equation will illustrate some of these features.

A popular example is Van der Pol's equation, because it is simple, non-linear, and it demonstrates limit-cycle oscillation. Rlab has a built-in integration engine, and several “rfile” integrators. An rfile is a file that contains an Rlab program or statements. The integration function needs as input: a function that returns the value of the derivative, values defining the start and end of the integration interval, and the initial conditions.

The entire problem could be performed interactively. However,
I have chosen to put the program in a file (int.r). This allows me
to edit and re-execute without a lot of repetitive typing. For this
article, I have used the shell-escape feature (**\**
in the first column) to cat the file through pr to generate
Listing 1.

Since the ode function integrates first order differential equations, we must write Van der Pol's equation:

as two first order equations:

The function, which calculates and returns,

is written and assigned to the variable **vdpol**.
After the function is defined, variables **t0**, the
integration start time; **tf**, the integration
final time; and **x0**, the initial conditions, are
initialized (lines 9-11). **tic** and
**toc**, builtin timing functions, are used around
the call to **ode** to tell us how long the
integration takes.

Once this file is finished, the following command will execute it, as if each line was entered from the prompt.

"> rfile int ODE time: 0.620

This simple problem runs fairly fast. The output from ode, a matrix of the time-dependent values of,

is stored in the variable **out** (line 14).
Convenient data visualization is a real plus when investigating the
behavior of differential equations. In this instance we would like
to look at

(**x**) and

(**xd**) versus time. We would also like to look at
the phase-plane for this problem, which is a plot of

versus.

We can do this with the plot function, which plots matrix columns. If the input to plot is a single-column matrix, the matrix row indices are plotted against the abscissa-axis, and the matrix column elements are plotted against the ordinate-axis. If the input to plot is a N-column matrix, then the values in the first column are plotted against the abscissa-axis, and the remaining columns are each plotted against the abscissa-axis.

A plot, similar to Figure 1,
can be created with the command **plot(out);**.
Since the first column of **out** is time, and the
second and third columns are **x** and
**xd**, all we have to do is give the unaltered
matrix to plot. If we want to plot the phase-plane, as in
Figure 2, we need to specify that
we want the third column plotted against the second. To do this
simply extract the second and third columns from
**out** like so:
**plot(out[;2,3]);**

The Plplot graphics library provides the builtin 2 and 3D graphics capability for Rlab. Builtin functions for most common graphics capabilities such as: 2D, 3D, mesh-plots, contour-plots, and histograms are supplied. Plplot supports most common graphics output devices, most notably X-Windows and PostScript.

It is possible that Plplot graphics may not be sufficient. In these cases the ability to get properly formatted data to another program is paramount. There are several methods of interfacing Rlab with other programs. Like most good Unix applications, Rlab will read from stdin and write to stdout. There are functions for writing matrices in ASCII format, as well as a C-like [f]printf function. There is also a system function that allows Rlab programs to do anything that can be done with the Unix shell. However, what makes interfacing with other programs easiest is the facility for writing to, and reading from a process (pipes).