Linux Goodies

In Pursuit Of The Perfect O/S



A Review of the Free Yorick Matrix Language

keendesigns tshirt banner

Yorick, One of the Fastest Matrix Language Options Available

Yorick 3D mesh plot

The plot above is the Yorick math language version of a mesh. It is a graph of the sinx/x function, which is also the 3D graphic of a star image as seen through a telescope. In this image you can see some interesting shading not seen in all math language mesh graphics. Yorick's mesh routines allow adjustments to be make in shading, light direction, and other viewing options.

Yorick Syntax

Yorick is a scripting matrix language created by a physicist for doing general prototyping in scientific work, data processing, and simulation. The language is described as being like Basic or Lisp, but far faster.

Yorick uses a C like syntax, so programmers of C, Java, and perl will find themselves at home with Yorick. Even the looping commands in Yorick are C like. If, however, you are currently a MATLAB or MATLAB clone user, you'll encounter a bit of adjustment in moving to Yorick.

User function files in Yorick must be pre-loaded before being used, unlike MATLAB and Octave in which functions are auto-loaded on reference. Putting related functions in libraries seems to be the most efficient way of packaging user-defined functions. User created Yorick files end with extension i, and the file custom.i allows users to list modules they want loaded each time Yorick is invoked.

Yorick is available in Windows and Linux. In windows, the language presents a moderate GUI interface. This review only deals with the Linux version of Yorick. In Linux, the user interface is a very basic command line interface. In fact, the basic interface doesn't even have a history mechanism, and is thus very difficult to work with.

But -- Don't Lose Faith.

The Linux interface for Yorick can be dramatically improved in two ways. The Yorick documentation shows how to implement Yorick in conjunction with the popular emacs editor, with emacs becoming the interface to Yorick. A simpler mechanism is to use a utility named rlwrap. Rlrwap provides a front end for virtually any program, providing a command history as well as additional optional features. The syntax of rlwrap is simple:

rlwrap -c yorick

That simple rlwrap command starts Yorick and becomes an interface to Yorick that provides the command history and other features (like file name completion) to Yorick. Replacing the word Yorick in the rlwrap command with some other program will create a front end for that program.

Yorick's syntax, once learned, is very convenient for interactive work. Most languages provide some kind of function for passing commands to the operating system. Something like system("ls *.i") to tell the system to do a listing of all .i files. Yorick provides such a function, but provides a much handier way to pass commands to the system when working interactively, making the operating system commands seem much more like part of an integrated environment. To pass a command to the operating system Yorick-style, just precede the command with a dollar sign. For example:

$ls *.i

Tells the operating system to list all .i files.

In Yorick, math operators are assumed to be applied in scalar fashion, unlike the matrix assumption in MATLAB and Octave. In the following matrix equations, the first equation does a scalar cell upon cell multiplication of matrices x and y to get z. The second equation performs a full matrix multiplication of x and y to get z.

Scalar product of matrices: z = x * y;
Matrix product of matrices: z = x(, +) * y(+ ,);

The odd looking nature of the matrix multiply in the second equation is due to the fact that Yorick isn't limited to two-dimensional matrices. Matrices may be of virtually any number of dimensions. Because of the multi-dimensional nature of Yorick, matrix math operations must be able to provide information about the nature of the operation and dimensions involved.

Yorick allows users to create variables of many types, not just double precision matrices. One can create short, int, float (single precision), and double arrays and matrices. While this gives the user better control of memory usage, it can cause confusing math results. An int array divided by an integer scaler will not yield any fractional results, for example. The user must keep track of the types of variables used in equations to be sure the results are as expected.

Variables passed to functions in Yorick are operated on as local variables within the functions. That is, modifications to a passed variables value are lost when the function returns. Only the values explicitly returned by a return statement get passed to the calling routine.

This local behavior methodology can be affected in a few ways. If an array is passed to a yorick function, operating on an element of the array will affect the calling functions respective array element, as follows:

x = [10,11,12];

func somefunction(x){
x(2) = x(2) * 2; // results in x(2) being changed in calling function

Another method to allow a function to change the value of a variable beyond the local version is to use the & symbol on front of a variable name in the function definition, as follows:

x *= 2; // results in x being changed in calling function

Notice the *= operator in the previous example. The shortcut c style math operators are recognized by yorick.

Finally, values can be declared non-local with an extern statement in a function declaration, as follows:

x = 10;
y = 20;

func somefunction(y){
extern x;

x *= 2; // causes x to be changed in calling routine via extern
y *= 2; // changes to y are local since not listed in extern

Yorick has a healthy population of mathematical functions, from statistical to signal processing -- plus a number of routines used in modeling calculations. Matrix indexing has some interesting shortcuts not available in all matrix languages. Indexes run from 1 to n, but a user can reference the last element of an array (or any dimension of a multi-dimensional matrix) with the index zero. Thus x(0) refers to the last element of the array x. x(-1) refers to the next to last element of the array, etc.

One thing I like most about Yorick is that it is fast! Really fast. All of the matrix languages perform matrix operations fast, but most matrix languages really bog down in instances when the user is forced to resort to loops to complete an operation. Yorick, however, can even process through loop procedures very quickly. The Yorick documentation gives some good guidelines for when a user can expect to be able to vectorize a solution and avoid loops.

Functions in Yorick can only return a single entity. Normally that's a scalar or a matrix of some number of dimensions. It is possible to declare variables within functions as external, making multiple variables in a function available to other functions.

It is also possible to declare a C like struct to hold variables. While structs cannot be declared in functions, they can, after having been declared in the main routine, be used in functions. This gives an additional way for functions to pass back multiple values -- by placing them into a struct.

Yorick programs can easily be ran in a batch mode. There are actually two ways to do this. In one way, interactive input from the user is not possible, and the custom.i isn't automatically read on invocation. The other way leaves user interaction in place, and custom loads are automatically done. Both methods use a specific command on the first line of a batch file as follows:

For no run time interaction:
#!/user/bin/yorick -batch

For run time interaction:
#!/usr/bin/yorick -i

For help, the Linux Yorick install includes a Yorick info file. Typing info yorick from the Linux shell will bring up the Yorick info file. Within the language, the user can type help,topic to bring up help on a given function or topic. Yorick makes documentation of user-defined functions easy, as the documentation for each function is simply a particularly structured comment within the respective functions.

Yorick Graphics

Yorick color contour
Yorick contour map

Yorick has a sizable collection of graphic primitives which can, with supplied parameters, create an impressive array of 2D and 3D graphic presentations. It does take a bit of study to get the hang of some of the routines, but the output results are worth the effort. Yorick uses a well integrated implementation of the Gist plot package. It's pretty easy to repackage Yorick plot commands into commands you're more familiar with, once you learn about them.

With the Yorick graphics, one can make line graphs, contour graphs, 3D mesh graphs, and display color images. The graph at the upper top is a color contour graph made with Yorick.

The graph you see at the bottom is a Yorick color map presentation. Yorick can present matrix images of large size quickly, and allows the user to select and easily create different color schemes. One can display images with either the color option of the contour utility (plc), as shown here, or with an image display utility (pli). The contour version works best with a limited number of color levels, less than 20 or so.

Even a simple quick line plot in Yorick produces an active plot window. As one moves the mouse around within the plot, the engineering coordinates of the mouse position are instantaneously displayed at the top of the plot. Clicking on the plot causes an instant redisplay of a zoomed in plot. Clicking on the right mouse button zooms out. One can zoom the entire plot, or just the x or y axis.

Mouse location and button information can be obtained by a Yorick program. This feature, combined with the fast plotting speed of graphics, makes Yorick one of the more capable matrix languages for image processing. Included with the Yorick install is a comprehensive set of fits image file utilities. This allows the user to input, manipulate, and output fits format files. Yorick also has read and write routines for ppm, pgm, and pbm file formats. Combined with the convert utility of the imagemagick package puts images of all types within the reach of Yorick.

The image at the upper top is an example if using the image graphic command instead of the contour command. With it, one can get the full 256 colors of a color map to be shown instead of the digitized look of a small number of colors.

The image at the upper bottom is a 3D mesh with hidden lines. As you can see, the highlights possible with the 3D command (plwf) give a very easily interpreted 3D display.

Yorick can even make and present movies, like the movie of the rippling sinx/x curve that you see here. Yorick has an animate command that can repeatedly call a computational function and present the results at a user designated rate.


In summary, I find Yorick to be an easy to use matrix language for a wide range of computational solutions. It is well supplied with mathematics routines for filtering, Fourier analysis, signal processing, and regression. It has robust enough I/O support to allow a user to tailor routines to read most any ASCII or binary file whose format is known. It has some unique graphics methods, and provides possibilities for the solution of some very complex problems with it's multi-dimensional capabilities.

I have used it extensively both for modeling problems and for time series reduction and analysis. I found that with the speed of Yorick, I seldom had to resort to writing a compiled program in some other language.

My subjective pros and cons list for Yorick follows.

  • Yorick is freely available for both Linux and Windows.

  • Yorick is very fast. Even when one resorts to loops, Yorick remains respectably fast.

  • Yorick closely follows C programming syntax. So users familiar with C, Perl, or Java will learn it quickly.

  • Yorick supports highly interactive 2D and 3D plots. By default one can expand or contract any graph in X, Y, or both coordinates.

  • Mouse clicks on graphs can deliver information back to a Yorick script.

  • Yorick has sufficient low-level file I/O routines to allow it to read or create files compatible with external utilities.

  • Yorick supports fits and pnm graphic files.

  • Yorick has sufficient string handling functions to deal with parameters and straight forward ASCII data.

  • Yorick can support a C-style data structure to allow returning more than one argument from a function.

  • Yorick supports char, integer, double, and complex data types.

  • Yorick supports arrays, and multi-dimensional arrays, at least as high as 9 dimensions.

  • Yorick has a very effective debugger that lets you examine variable values within a crashed function.

  • Yorick works well in both interactive and batch modes.

  • Cons:
  • While Yorick has some string handling capability, it's limited in support of more complex ASCII files.

  • Yorick has a very simplistic user interface. You'll want to either use rlwrap or emacs as an interface for Yorick.

  • Some of the matrix operators are a bit arcane, adding to the learning curve.

  • All functions must be in library files, and only those listed in the custom.i file are automatically loaded.

  • Data structure layouts must be globally declared.