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

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' 32

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.