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

Rlab stands for “our lab”. It is available to almost everyone who needs a computational tool for scientific and engineering applications, because it is freely available, and it runs on many platforms.

I started working with high level languages when I realized I was spending far too much time writing Fortran and C language programs as a part of engineering analyses, test data reduction, and continuing education. I searched for a better engineering programming tool; except for Matlab, and some Matlab-like programs (all commercial), I came up empty-handed (this was in 1989). I did not feel Matlab's language design was powerful enough, but I would have used it had it been lower in cost and available on more platforms. I diverted my “off-hour” studies to interpreter construction, and started prototyping Rlab. Within a year, I released version 0.10 to the Internet for comment. Now, almost five years later, Rlab has undergone significant changes and improvements primarily due to excellent assistance from users around the world.

Rlab does not try to be a Matlab clone. Instead, it borrows what I believe are the best features of the Matlab language and provides improved language syntax and semantics. The syntax has been improved to allow users more expression and reduce ambiguities. The variable scoping rules have been improved to facilitate creation of larger programs and program libraries. A heterogeneous associative array has been added to allow users to create and operate on arbitrary data structures.


The term “high level language” has many different connotations. In the context of Rlab it means that variables are not explicitly typed or dimensioned. A variable's type and dimension are inferred from usage, and can be arbitrarily changed during a program's execution. This automatic typing and dynamic allocation free the scientific programmer from many of the more time consuming programming duties normally associated with languages like C or Fortran.

In Rlab's case, high level also means interactive. Since one of the purposes is to provide convenient means for data manipulation and visualization, the program can be run in either batch or interactive mode. Typing rlab at the shell prompt starts the program. Rlab gives the user the command line prompt prompt >, from whence program statements are issued and executed.

What do you get? What does it cost? Most people find that they can develop a working program far faster than with C or Fortran. Furthermore, the built-in graphics capabilities and interactive mode of operation promote experimentation and exploration of data and methods. The price you pay is slower program execution in some instances. Performance tests between compiled and interpreted languages usually show the compiled language to be faster in all respects. If your Rlab program uses scalar operations exclusively, and uses none of the built-in linear algebra functions, then it will be substantially slower than the Fortran or C version. However, if you take advantage of Rlab's optimized array operations, built-in linear algebra and utility functions, you may find that Rlab will perform quite well.

Although I cannot provide a complete introduction in a single article, I can show you enough of the language to help you decide if it is something that you would want to try. A more complete introduction is provided in “The Rlab Primer”, which is included in the source and binary distributions.


The numeric array, or matrix, is the most commonly used data type. The numeric array can be one-dimensional (a vector) or two-dimensional. Most often, matrices are created by reading data from another program or from a file. For simpler examples, we will create our matrices interactively. Array/matrix syntax uses square brackets, [ ], like the C language, to delimit the matrix, and semi-colons to separate each row from the next. So, to create a matrix within Rlab, the user types:

> a = [1, 2; 3, 4]

Which provides the following response:

  a =
        1          2
        3          4

Matrix referencing and assignment uses the following syntax:

> a[1;] = 2 * a[2;2,1]
 a =
        8          6
        3          4

The semi-colon delimits row and column specifications. The absence of a row or column specification selects all of the rows or columns. Additionally, the user can specify particular indices, or combinations of indices, in any order. In the previous example, a[2;2,1] selects the second row of a, and the second and first columns (in that order) of that row. Therefore, a[2;2,1] evaluates to [4,3]. This quantity is then multiplied by 2, and the result is assigned to the first row of a.

In this article real numbers will be used in all of the examples. However, Rlab can deal with complex numbers equally well. To enter a complex number, the imaginary constant i or j is used (don't worry, you can still use i and j as variables). For example: a = 1 + 2j creates the complex number with real part 1 and imaginary part 2. All numeric operators and functions (where they make sense) work with complex values as well as real values.

The traditional numeric operators are overloaded. When working with scalar operands, the results are what most people would expect. However, when working with array/matrix operands, the numeric operators behave differently. Addition and subtraction function in an element-by-element sense between the two operands. The multiplication operator * performs the matrix inner-product. To illustrate:

> a = [ 1 , 2 , 3 ];
> b = [ 4 , 5 , 6 ];
> a + b
        5          7          9
> a' * b
        4          5          6
        8         10         12
       12         15         18
> a * b'

Note (in the first two lines) that a ; at the end of a statement suppresses printing the result. The division operator / performs traditional division on scalar operands, and solves sets of simultaneous linear equations with matrix/vector operands. A set of element-wise operators exist to perform element-by-element operations between arrays. The element-wise operators are two-symbol operators; the first symbol is always a . so the element-wise division operator is ./ and the element-wise multiplication operator is .*:

> a = [1,2,3;4,5,6];
> b = 1./a
 b =
        1        0.5      0.333
     0.25        0.2      0.167
> a.*b
        1          1          1
        1          1          1

In addition to the numeric class of data, there is a string class. String arrays/matrices are handled in exactly the same way as numeric arrays:

> s = ["how", "to create" ;
>      "a string", "within rlab"]
 s =
how          to create
a string     within rlab

As you can see, string arrays consist of arbitrary length strings. There are no restrictions upon the relative size of strings in an array. Strings can be concatenated with the + operator. The other (traditionally numeric) operators do not operate on string arrays.