LinoLab Manual

Frans Lundberg

Linova

This document can be distributed freely as long as it is not modified. Please provide feedback to frans(at)linova.com.

1 September 2005


Table of Contents

1. Introduction
1.1. What is LinoLab?
1.2. Installation
1.3. Working with LinoLab
1.4. Examples
2. Using LinoLab
2.1. More About Installation
2.2. License
2.3. Compiling
2.4. Scripts and Modes
2.5. LinoLab Session
2.6. Command Arguments
2.7. BuildApp
2.8. Static Variables
2.9. Class Search Order
3. Lino Language
3.1. Print Operator (;;)
3.2. Array Creation ([...])
3.3. Plus and Minus (+, -)
3.4. Lino Star Operator (*)
3.5. Lino Dot Star (.*) Operator
3.6. Lino Solve (\)
3.7. Subarray and Index Operators([])
3.8. Details of the Lino Operators
4. Guide to Features
4.1. LinoLapack
4.2. Mathematics
4.3. Plotting
4.4. LinoLab Server
4.5. LinoLab and QNX
5. LinoLab versus Matlab
5.1. Features
5.2. Performance
6. Versions, Bugs and Issues
6.1. Versions
6.2. Bugs
7. Acknowledgements

Chapter 1. Introduction

Read this introduction first. It gives you all information to get quickly started.

LinoLab is based on the Java programming language from Sun Microsystems. This manual assumes the reader has some Java knowledge. Linova recommends the tutorial http://java.sun.com/docs/books/tutorial/ for those who would like to learn Java. It is a great starting point.

The official documentation for LinoLab consists of the following parts.

  1. This manual. The most up to date version is available at www.linolab.com. The manual also ships with LinoLab and is available from LINOLAB/system/doc/index.html where LINOLAB is the LinoLab installation directory. Issuing the LinoLab command help(); gives you access to the manual in searchable Java Help format.

  2. Javadoc. The Javadoc source code documentation is also available from LINOLAB/system/doc/index.html and with the help(); LinoLab command.

  3. LinoLab Extra Download. LinoLab comes with software from other organizations. These pieces of software are documented in the LinoLab Extra Download. Any documentation or software not normally required to run LinoLab may be available in the Extra Download.

  4. LinoLab Homepage. LinoLab's official homepage is www.linolab.com which is currently (June 2005) redirected to www.linova.com/linolab/.

1.1. What is LinoLab?

LinoLab is a Java-based environment that helps developers run code using a command prompt and a workspace that keeps variables available for interactive manipulation.

LinoLab is created to let scientists implement and share their ideas easily. It supports everything between a small prototype to a large commercial product. The Lino Language can optionally be used instead of pure Java. Lino is a superset of Java that adds language constructs for easy manipulation of matrices and general numerical arrays.

LinoLab has been developed by Linova (www.linova.com) since 2002 and was first offered to the public in 2004.

1.2. Installation

LinoLab runs on any platform with a Java virtual machine (Java runtime environment) version 1.4 or later. Download Java from www.java.com if you need to.

If your system supports Java Web Start it is recommended that you install LinoLab by clicking on the link "run LinoLab now!" on the web page www.linova.com/linolab/

Another alternative is to install LinoLab by downloading the file linojarX.Y.jar from the same web page and then execute it by double-clicking on it and follow the instructions.

For more installation information see the next chapter.

1.3. Working with LinoLab

When LinoLab is started a graphical window is normally shown. In the lower part of the window the user types the commands. Run the classic hello world example by typing:

"Hello world!";;

in the LinoLab command prompt. Then press ENTER. LinoLab should print "hello world!" in response to your action. Note the use of the double semicolon. It is LinoLab's print operator. You could have typed:

System.out.println("hello world!");

instead, but who wants to?

What happens under the hood is that the command is translated to form a standard java source file (USERDIR/LinoLabCommandClass.java). This source file is then compiled with a java compiler (included in the LinoLab application) to a class file that is dynamically loaded and executed.

The class LinoLabCommandClass extends SuperCommandClass which has a number of useful methods for the LinoLab user - the command methods. See the Javadoc documentation for linolab.ICommandMethods for for detailed information.

Every public Java method and field is available for manipulation directly from the prompt! Play around yourself with your own Java code or try the commands below.

Help

To get help open LINOLAB/doc/index.html with Firefox or any other web browser, or type

help();

in your LinoLab prompt.

Typing Commands

Try the arrow up/down keys to retrieve old commands. If you type the beginning of the command and press arrow up/down only the commands that start with that beginning will be retrieved. To disable browsing of old commands press arrow left or right. ESCAPE will remove the text from the input area. A command may extend over several lines, press SHIFT+ENTER for a line break.

Context Menu

The graphical LinoLab window has a context menu. On most systems this menu will be activated by right-clicking on the mouse. The menu contains command suggestions ordered hierarchically. Try these example commands!

Print Operator

The print operator is applied by finishing a Java expression with ";;" instead of ";". For example the command

Runtime.getRuntime().availableProcessors();;

prints the number of available processors for the Java virtual machine. The command

System.getProperty("java.version");;

prints the version of your Java virtual machine, and

365*24*60*60;;

prints the number of seconds in a year.

The print operator has no meaning for statements, for example int i=12;; will not work. Use int i=12; i;; instead.

Workspace

LinoLab keeps a workspace of live java variables that can be manipulated directly. For example run the command

int a=12;

followed by the command

a+10;;

and the response will be "22". The variable "a" is automatically stored in the workspace between command executions. Type

who();

to print the variables currently in the workspace. Type clear("a"); to remove variable "a" from the workspace. Type clear(); to remove all variables from the workspace.

Note, that a command like

int a;      // ERROR, will not compile

will result in a compilation error. Variables must be defined and initialized in the same command.

Userpath

The userpath is an important setting. It consists of a number of directories that are searched for java classes and LinoLab scripts. It is similar to the Java classpath, but different in two ways. One, the userpath can be dynamically changed while LinoLab is running. Two, jar files can be placed in one of the directories on the userpath and are then accessible to LinoLab. The whole path to the jar file itself is not in the userpath. The directory USERDIR/path (see "More About Installation" for a definition on what USERDIR means) is always on the userpath, so to use the classes in a jar file, the jar file can be copied to LINOLAB/user/path. Type the command reloadJars(); after adding jar files to the userpath to be able to use the new classes and resources in the jar files.

The userpath is handled with the commands addPath(String), removePath(String/int), and userpath(). See the Javadoc documentation for the interface ICommandMethods for details.

Imports

To avoid typing we want to import classes. Use the commands addImport(String), removeImport(String/int), and imports() to handle the imports. As an example the command

addImport("java.awt.*");

makes it possible to use the classes in package java.awt in LinoLab commands without using the fully qualified names of the classes. See the Javadoc documentation for the interface ICommandMethods for details.

Editing and Compiling

LinoLab is distributed with the excellent text editor jEdit (www.jedit.org). Use it to edit your Java files. Use the command edit(); to start jEdit (this requires that the program to launch the Java virtual machin is called "java" which is the case for the virtual machine from Sun) or start it by launching the executable jar file LINOLAB/system/jedit/jedit.jar.

By using this editor Java source files on the userpath will automatically be compiled by the built-in Java compiler when they are saved. The built-in compiler is the Eclipse (www.eclipse.org) Java compiler. Error messages from the compiler will be written to LinoLab. Java 5 (1.5) source files are not currently supported.

An existing installation of jEdit can also be used. Copy the plugin LINOLAB/system/jedit/jars/LinoLabPlugin.jar to the plugin directory (jars) of your existing jEdit installation to get it working. More information is available from jEdit's help for the LinoLab plugin.

1.4. Examples

The examples shows how to play interactively with a graphical user interface (GUI) and how to create your first Lino source file.

Interactive GUI Design

To learn how GUI components work, it is nice to work interactively. Try the following commands. We assume "javax.swing.*" is on the list of imports (which is default). If not add it with the command addImport("javax.swing.*");.

Create and display a JFrame with this command.

JFrame f = new JFrame("An Interactive Frame");
f.setSize(200, 200);
f.setVisible(true);

Then set different properties of the window with, for example, the following commands. Commands are separated by blank lines. f.setVisible(true) is used to repaint the window and make it appear in front of other windows.

f.setLocation(300, 100);

f.setTitle("LinoLab is interactive!");

JButton b = new JButton("Push me, I am a JButton!");
f.getContentPane().add(b);
f.setVisible(true);

f.getContentPane().setLayout(new java.awt.FlowLayout());
f.setVisible(true);

b.setBackground(java.awt.Color.blue);
f.setVisible(true);

Creating a Lino Source File

Start the text editor with the LinoLab command

edit("USERDIR/path/First.lino");

This should start the jEdit editor. Enter the following contents to the file.

public class First {
    public void foo() {
        "Hello from First!";;
    }
}

Save the file in jEdit and it will be automatically compiled since USERDIR/path is in the userpath. Try the class by this command.

new First().foo();

The command should print "Hello from First!". Change the string in the foo() method and repeate the command. The command will use the new updated version of the First class as long as First.lino has been saved.

Java classes should not be put in the default package. The create a source file in the mypackage package, first create the directory USERDIR/path/mypackage with the command

mkdir("USERDIR/path/mypackage");;

or create it with jEdit or your file browser. Then write the following text to the file USERDIR/path/mypackage/Second.lino using jEdit.

package mypackage;

public class Second {
    public void foo() {
        "Hello from Second!";;
    }
}

The class can be tested with the command

new mypackage.Second().foo();

To avoid the "mypackage" prefix run the command

addImport("mypackage.*");

Now the classes in mypackage can be used without package prefix. After the import command we can use the command

new Second().foo();

to test the Second class.

Chapter 2. Using LinoLab

This chapter describes how to use LinoLab. Read the introduction before this section. The introduction will get you quickly started, while this section provides more detailed information and advanced usage.

2.1. More About Installation

A Java virtual machine (Java runtime environment) version 1.4 or later is needed to run LinoLab. Install it if you don't have it! See www.java.com. Since LinoLab is a Java program it will run on any platform with Java installed. The same distribution is used for all operating systems.

There are two ways of installing LinoLab, either by downloading and running a jar file or by using Java Web Start.

Java Web Start Installation

Java Web Start is a technology used to easily install and run Java software by just clicking on a link in a web browser. If Java Web Start is installed on your system, LinoLab can be downloaded, installed and executed by just clicking on the appropriate link on the web page www.linova.com/linolab/.

Web Start installation is recommended for LinoLab, since it makes it easy to integrate the program with the operating system. For example convinient short-cuts to start LinoLab can be created. Additionally, Web Start deployment is more secure since it verifies the signiture of the linolab jar file to make sure it has not been tampered with while being downloaded.

Jar File Installation

Download the linolab jar file (linojarX.Y.jar) from www.linova.com/linolab/. Execute the jar file by double-clicking on the file or by typing

java -jar linolabX.Y.jar 

in your system command prompt, then simply follow the directions. This command line above assumes that linolabX.Y.jar is in your current directory and java is the command to start your Java virtual machine. X and Y are the version and subversion of LinoLab. If you do not have a graphical environment, LinoLab can be installed from the prompt. Type

java -jar linolabX.Y.jar help

for information on all available install options.

The install process will create a directory that contains all application files. This installation directory is called LINOLAB in this document. Read LINOLAB/doc/index.html for documentation and launch the LINOLAB/linolab.jar file (double-click or do java -jar linolab.jar) to start the application. Create a Windows shortcut, a Unix alias or similar to easily start the executable jar file.

General Installation Information

The installation does not write to any registry or similar, it just unpackages files to the LINOLAB directory. The whole installation can be moved by simply copying the LINOLAB directory. Windows shortcuts and Unix aliases need to be updated of course.

To verify the installation run LinoLab with start task "test" like this:

java -jar linolab.jar test

This will run a number of self-tests. If any test fails, either LinoLab is not properly installed or you have found a bug.

The first time LinoLab is run a user settings directory (called USERDIR) is created and some files are copied to this location. By default USERDIR equals HOME/.linolabX.Y where HOME is the home directory of the user (try command System.getProperty("user.home");;). For example on a Windows XP computer the user files may be stored in C:\Documents and Settings\frans\.linolab1.5.

The LINOLAB directory could be read-only to the LinoLab program once it is installed. The files in LINOLAB are not normally modified. To reset user settings to what is default, exit from LinoLab if it is running and remove the USERDIR directory. When LinoLab is started again the default settings will be used.

To uninstall LinoLab just remove the directories LINOLAB and USERDIR.

Multi-User Installation

The same LinoLab installation can be used by many users if they have a common shared filesystem. This works even if the users have different operating systems. Hurray for Java!

Just install LinoLab somewhere on the shared filesystem. User-specific files are normally stored in a subdirectory of the home directory of each user. Since each user have different home directories it is possible to used a shared installation without loosing ones settings.

Note that unless the shared filesystem is very fast the compile performance will be degraded compared to if LinoLab is installed on the local computer.

LinoLapack

For highest possible matrix performance LinoLapack must be installed. See the LinoLapack chapter for more information.

Reinstalling

The file LINOLAB/linolab.jar is an identical copy of the linolabX.Y.jar that has been downloaded (directly or with Web Start) to install LinoLab. So, the install jar file and the actual application jar file is really the same file! This means that to reinstall LinoLab you can copy LINOLAB/linolab.jar to somewhere, then remove the LINOLAB directory and execute the copied linolab.jar file to reinstall LinoLab. If you want to reset all settings too, also remove USERDIR. The file LINOLAB/linolab.jar can be redistributed freely as long as it is not modified.

2.2. License

LinoLab comes as one download, but two versions depending on the license. There is one free version of LinoLab licensed to "everyone". Anyone can use the free version, also for commercial purposes. See the file LINOLAB/doc/license.txt for details.

The free version has the following limitations

  1. Lino commands execute 4.0 times slower.

  2. Only one command is allowed to execute at a time.

If a user of the free version runs a command that does not finish within a reasonable time he may want to kill that job. To allow this for a user of the free version the following commands are always allowed to run in parallel.

killAll();

jobs();

The commands must be run literally as they appear above. For example if a space is inserted like

killAll( );

the command will not run.

Installing Full License

To install LinoLab with a full license, first install the free version. Then acquire a license string from Linova and install it by using the command

installLicenseString();

The user will be queried for the license string. If the entered license string is valid, LinoLab will run as a full version the next time it is started.

If the entered string is a valid license string the installLicenseString(); creates a *.license file in the directory USERDIR.

If several license files (ending with .license) exist in USERDIR the first file is used. By first is meant the first file based on sorting all .license-files in alphabetical order according the Java method java.lang.String.compareTo.

If you have a multi-user installation and a license that is valid for anyone who can access the installation files, copy the license file to LINOLAB/system and call it <licensee>.license. Tell the users to remove any license file they have in USERDIR to use the multi-user license in LINOLAB/system. License files in USERDIR takes precedence over license files in LINOLAB/system.

2.3. Compiling

Lino source files (must end with ".lino") must be translated to Java source files and then compiled to class files to be used. Fortunately, LinoLab takes care of the translation and compiling phase for you.

jEdit

LinoLab comes with the excellent text editor jEdit (www.jedit.org). To start the bundled editor use the command edit();. jEdit can also be started by launching the executable jar file LINOLAB/system/jedit/jedit.jar.

The bundled jEdit program includes a jEdit plugin called LinoLabPlugin. This plugin notifies the LinoLab application when a Lino or Java source file has been saved so LinoLab can automatically compile a Java source or translate and compile a Lino source.

LinoLabPlugin uses a network TCP socket to communicate with LinoLab. When LinoLab starts it opens port 12321 to receive messages from LinoLabPlugin. Make sure your firewall allows LinoLab to open the port. There is no security risk with this since only "localhost" (connections from the same computer) is allowed to connect. For more details and for how to install the plugin in an existing jEdit installation, see the plugin documentation available from jEdit (menus: Help - jEdit Help - Plugins - LinoLabPlugin).

Other Editors

Lino and Java files may be created with any editor or development environment. Any new or updated source file on the userpath will be compiled when needed to run a command.

ANT Tasks

ANT (http://ant.apache.org/) is a great build tool. LinoLab provides ANT tasks to, for example, translate and compile Lino and Java source files. Java source files and then compile the Java source files. See the Javadoc for the package linolab.ant for information on this.

Linoc Start Task

Lino and Java source files can be compiled with the "linoc" start task. This task is similar to the ANT task with the same name. In your system prompt, type

java -jar linolab.jar help linoc

to get updated and detailed information on how to compile source files with the "linoc" start task.

2.4. Scripts and Modes

The primary source of information on scripts and modes is found in the Javadoc documentation for the package linolab.modes. This manual contains an introduction to these features.

Scripts are useful for small common tasks. Scripts are executed as if the commands in the script were entered by the user in the LinoLab command prompt. LinoLab scripts or SuperScripts can run code from many languages or modes.

A LinoLab mode or input mode is the current handler for commands issued from the LinoLab prompt. The mode abstraction makes it possible to smoothly use different languages together within the LinoLab environment. All modes can use the session workspace.

SuperScripts

LinoLab supports running SuperScripts. The name SuperScript comes from the fact that a SuperScript can consist of code from many different programming languages or modes.

An example of a script is

mode lino;
"Hello world!";;

This will print "Hello world!" to the session output in Lino Mode. If you don't have the need to run scripts in other languages (modes) then just remember to start your scripts with mode lino;. You don't have to worry about the other modes and can skip the rest of this section.

Now try the above example by saving the text in a file called USERDIR/path/hello.script. The hello.script could have been placed in any of the userpath directories. Run the example script with the following command

run("hello");

A script always starts in the Primordial Mode. The Primordial Mode is just used to select a real working mode. Scripts often start with the line.

mode lino;

After the semicolon the script is in Lino Mode instead of Primordial Mode and Lino Mode is responsible for parsing and interpreting the source that follows. All modes need to implement a way to tell when the the mode is finished. Often this command is

exitMode;

After exitMode; the script will again be in primordial mode and is free to switch to a new mode. Below is an example that defines a String variable in Lino Mode and prints it in BeanShell Mode.

mode lino;
String linoString = "Hello everyone! / Lino Mode";
exitMode;

mode beanshell;
print("Printing in BeanShell: " + 
        linolab.Access.getWorkspace().get("linoString"));
exitMode;

The last line of the above script is optional.

Scripts should not be used excessively. Script code cannot be used outside of LinoLab, scripts cannot currently have input/output arguments and scripts may execute much slower then real Java classes. However, scripts are useful for certain small tasks, especially when several modes are to cooperate.

Modes

A SuperScript can use several modes and so can the LinoLab user. With the default settings LinoLab starts in Lino Mode. To exit to the Primordial Mode type

exitMode;

Now the session is in Primordial Mode and only primordial commands are allowed. See documentation for the class linolab.modes.PrimordialMode for details. Type

help;

to print some help and a list of available modes. Switch to a mode by the command mode <modeName>;, for example type

mode beanshell;

to switch to BeanShell Mode. The command

print("Hello from BeanShell!");

is a valid BeanShell command. The command

exitMode;

can be used to exit from the BeanShell Mode to the Primordial Mode and the command

mode lino;

gets us back to the familiar Lino Mode. The session is now ready to receive Lino commands again.

The LinoLab context menu provides command examples for the currently active mode. Try these commands.

The Javadoc package documentation for the package linolab.modes has more information about the available modes.

Special Scripts (startup/shutdown)

There is a special script with the filename USERDIR/path/startup.script. This script is run at startup of LinoLab. Locate your settings such as userpath and import list additions in this script.

The script USERDIR/path/shutdown.script is run just before LinoLab terminates the normal way. It will not be run if the method System.exit is called in a user command or the process is killed with Control-C or similar.

Executable Scripts

On Unix systems (including Windows + Cygwin) SuperScripts can be made executable by including a hash-bang comment at the first line of the script file. For example, we may have a file named hello.script with the following contents.

#!/bin/linolab
mode lino;
"Unix executable scripts are very useful!";;

This will work on any Unix-based system provided that there is an executable binary program at /bin/linolab that will run the script.

The following C-source code can be used to create /bin/linolab.

/*---- linolab.c ----
A simple application used to launch LinoLab and SuperScripts.
Replace the "java -jar ..." string with a string appropriate to 
launch LinoLab on your system. Compile with:
    gcc linolab.c -o /bin/linolab
*/
main(int argc, char** argv) {
    char* command;
    int i;
    command = (char*) malloc(sizeof(char) * 5000);
    command[0] = '\n';
    command = strcat(command, 
    "java -jar \"C:\\Program Files\\linolab1.5\\linolab.jar\"");
    
    for(i=1; i<argc; i++) {
        command = strcat(command, " \"");
        command = strcat(command, argv[i]);
        command = strcat(command, "\"");
    }
    system(command);
    free(command);
}

Replace the string "java -jar ..." to match your LinoLab installation directory. Then compile with

gcc linolab.c -o /bin/linolab

That's it! Now all your scripts can be run as executable scripts provided they start with the line

#!/bin/linolab

For example, type

hello.script

in your command program to run the example above. (Type ./hello.script if you do not have "." on the PATH.)

The above C-program and executable script have been successfully tested on the following platforms: Linux SuSE, Windows XP with Cygwin, and Mac OS X 10.3.8. On a Mac you may need to enable the root account. This can be done with: Applications/Utilities/NetInfo Manager/Security/Enable Root User. GCC for OS X is included with the Xcode software.

Note that the /bin/linolab program is also a convinient way to start LinoLab. Just type

linolab

on your prompt and LinoLab will start. It is recommended that all SuperScript files start with the line #!/bin/linolab.

2.5. LinoLab Session

Every LinoLab command is run in a LinoLab session. The session has a number of settings, controls the executing jobs and provides the workspace that keeps variable available between commands.

Session Settings

The session has a number of session-wide settings. The userpath and imports settings have already been described in the introduction of this manual.

Another setting is the current directory (CD) of the session. The notion of a current directory is useful to specify filenames relative to CD easily. The command methods (see linolab.ICommandMethods interface) to handle CD are: cd() and cd(String). Use the command method call getFile(".") to get the File corresponding to the current directory. Note that the current directory of a LinoLab session is not the same as the current directory of the computer system that started LinoLab.

Session Access

The way to access the running LinoLab session from Java or Lino code is to use the method Access.getSession() which returns an ISession interface to the session of the calling thread. Everything the LinoLab user should be able to access is accessible through this interface. Read the javadoc for ISession and Access.

To access the job corresponding to the calling thread, use the method Access.getJob().

Command Methods

The Command Methods are documentated in the Javadoc for the interface ICommandMethods. These methods use an ISession interface to access the session. The methods are available by getting an interface implementation with the method Access.getCommandMethods() or directly from the LinoLab prompt since all methods in ICommandMethods are also implemented in SuperCommandClass which is the superclass of the command class created for each LinoLab command.

LinoLab Filenames

One reason to use the notion of current directory (CD) is that we can easily specify files relative CD. For example the filename "./notes.txt" means the file named "notes.txt" in the current directory.

LinoLab often uses LinoLab filenames to specify files. A LinoLab filename is nearly the same as a system filename. An absolute LinoLab filename of a file is identical to the absolute system filename of the file. A relative LinoLab filename is resolved with respect to the current directory of the LinoLab session. LinoLab filenames always allow both forward and backward slashes to separate the parts of the filenames. This feature makes it easy to move file-dependent applications between different operating systems. Forward slashes are recommended over backward slashes since forward slashes don't need to be escaped in Java string literals.

LinoLab filenames allows the usage of directory aliases which can simplify file handling significantly. Directory aliases are handled by the ICommandMethods methods aliases(), addAlias(String, String), removeAlias(String). The aliases "USERDIR" and "LINOLAB" are set by LinoLab and cannot be changed by the user. Try the command

getFile("LINOLAB");;
getFile("USERDIR");;

It will print those directories.

As an example the two commands

addAlias("~", System.getProperty("user.home"));

getFile("~/notes.txt");;

show how to use '~' for the user's home directory also on a Windows computer.

There are three special aliases that don't refer to an absolute directory.

  1. "." is an alias for the current directory.

  2. ".." is an alias for the parent of the current directory if the parent exists.

  3. "userpath" is a special alias that is used to easily access files on the userpath. For example "userpath/startup.script" refers to a file named "startup.script" in one of the userpath directories. If many such files exists the one in the first userpath directory is used. If no "startup.script" file is found, the LinoLab file as assumed to have the same meaning as "./userpath/startup.script".

    If a LinoLab filename uses the "userpath" special alias and it has a parent directory, for example "userpath/com/mycompany/NewClass.java" the filename will be mapped to a file in the userpath it it exists or if the parent ("userpath/com/mycompany") exists.

Try out for yourself with the getFile(String) command method.

2.6. Command Arguments

If LinoLab is started from the system prompt, command arguments can be used to alter the default behavior of LinoLab. Many users will not need to know how to do this and can skip this section of the manual. The general format of the arguments is

java -jar linolab.jar [<task> <taskParameters>]

where <task> is the name of the start task to perform and <taskParameters> are the parameters specific to that start task. The format of <taskParameters> varies from task to task.

The examples in this section assume your java virtual machine is executed by the command "java" and that the linolab.jar file is located in the current directory.

For complete and updated information on all available tasks type

java -jar linolab.jar help

This will work even though LinoLab is not installed, but in that case only the tasks that can be run without installing LinoLab are printed. To get detailed information on a specific task, type

java -jar linolab.jar help <task>

The tasks described in this section are only a subset of all tasks. Other tasks include tasks to compile source files, to clean source directories and to install LinoLab to a specified directory. Some of the tasks have corresponding ANT tasks, see the package linolab.ant.

Running a Single Script

LinoLab can be used as an engine to run SuperScripts. The "script" parameter is used for this purpose. For example

java -jar linolab.jar linoscript -name /scripts/my.script

will run the script "my.script". No startup or shutdown scripts are run. No welcome message is printed. The LinoLab application exits as soon as the script has been run.

The ability of invoking scripts this way makes it easy for other programs and scripts to run a SuperScript. The LinoLab application will exit with an exit code equal to 0 if the script ran OK and a negative integer if something went wrong.

Running From the Prompt

The standard user interface of LinoLab is graphical. But for some circumstances a simple prompt is preferred. For example, we may want to run LinoLab over SSH, or on a non-graphical Linux installation.

Start linolab like this

java -jar linolab.jar run -prompt

After starting LinoLab in prompt mode everything works the same as in the standard mode except for the following.

  1. Commands are executed when ENTER is pressed twice. This is to allow the user to enter multi-line commands.

  2. Access to graphical user interfaces may be forbidden. For example the command addPath(); will throw an exception.

To finish the session type exit(); and press ENTER twice.

2.7. BuildApp

You will like the BuildApp feature of LinoLab if you intend to easily share applications with people that don't use LinoLab. With the BuildApp feature you can create platform-independent executable Java programs from a single LinoLab command, or script.

For example try this command.

buildApp("1+1;;");

It creates an application that computes 1+1 and prints the result. The default name and location of the generated Java jar file is ./app.jar. For more control, use the class linolab.user.AppBuilder instead. Run the generated application by this command (or similar)

java -jar USERDIR/app.jar

Another example. First run this command

Array x = [0:0.05:Math.PI*2];
Array y = x.sin();

Then run the following command to create a standalone application.

buildApp("LPlot.xy(x,y).output(); Thread.sleep(5000);");

The sleep is used to make sure the plot is actually drawn before the buildApp command finishes. This is needed to ensure all needed classes have been loaded. Note that variables in the workspace (x and y) will automatically be included in the generated jar file. Not all variables in the workspace are included in the jar file, only those that are used. Depending on how the workspace variables are accessed the automatic inclusion may not work properly. In this case specify which variables you want to be included manually. Use the AppBuilder class. Note also that the classes of the variables that are used from the workspace must implement java.io.Serializable to be possible to store in the generated jar file.

To keep the generated jar files small, only the classes that are really used when the command is run are included in the application jar file. This is accomplished with a custom class loader. Note that this approach will not work if the set of loaded classes depends on user actions or other external events. The set of loaded classes for one command invocation may then not be the same as the the set of loaded classes for another command invocation. The solution is to make sure all classes that may be loaded for a command are guaranteed to be loaded. A way to accomplish this is to use statements like these

Class c = mypackage.MyClass.class;
c = mypackage.MySecondClass.class;
c = mypackage.MyThirdClass.class;

in code that is run by the command. The statements make sure the classes MyClass, MySecondClass, and MyThirdClass are loaded and therefore included in the generated jar file.

The command buildAppFromScript uses Lino code in a script to create the executable jar file. BuildApp jars can only be created from commands and scripts that exclusively use the Lino Mode.

Command line arguments can be used with BuildApp jars. For example the following two commands (must be executed as two commands)

String[] args = new String[]{"12"};

buildApp("int x=Integer.parseInt(args[0]); x*x;;");

create a program that squares the first command line argument. 12 is used when the BuildApp jar is created, but it will be replaced by any number the user types when the BuildApp jar is run standalone. Type something like

java -jar app.jar 3

in your system prompt to run the program. It will print 9.

2.8. Static Variables

Some classes are loaded again when a command is issued. For example if a class file on the userpath has been updated and it is used in a command the new version of the class will be used unless a variable in the workspace uses the old class. Classes in jar files on the userpath are reloaded when the reloadJars(); command is run.

When a class is loaded again the static member variables are lost. Therefore, avoid working with static members of classes that are updated while LinoLab is running. Classes stored in jar files are less of a problem since they are only reloaded when the user issues the reloadJars(); command. If you want to make sure a class is not reloaded, add an object of that class to the workspace.

To summarize: avoid using static class members of classes that are redefined while LinoLab is running.

2.9. Class Search Order

Classes are searched for in this order.

  1. If the class is a standard Java class (for example java.util.Vector) it is loaded by the Java virtual machine system class loader.

  2. linolab.jar is searched for the class.

  3. The jars in LINOLAB/system/jars are searched.

  4. Jarfiles on the userpath are searched.

  5. Class files on the userpath are searched.

If several class files with the same name exist in several directories on the userpath, the class file that belongs to the first directory is used.

If the class exists in several jar files on the userpath, the jar file that is in the first directory on the userpath is used. If there are more than one jar file in that directory that contains the class the jar files are ordered alphabetically and the first one in that order is used. The method String.compareTo is used to order the jar file names alphabetically.

It is recommended that classes (class files, or entries in a jar file) with the same name should not be on the userpath. Multiple definitions leads to confusion.

The package linolab and lsh with subpackages are reserved for LinoLab, the LinoLab user should not add classes to these packages.

The same search order as for classes, is used to retrieve Java resources.

Chapter 3. Lino Language

The Lino Language is Java with a few additional language constructs to handle matrices and to print variables easier. A Lino source file is a text file with UTF-8 encoding (US-ASCII works). Additionally, the filename must end with ".lino". A lino file is always translated to a corresponding Java source file before it is compiled with a standard Java compiler.

All Lino language constructs can be used from the LinoLab command prompt. The Lino Language provides operator overloading capabilities for a limited number of operators. LinoLab implements operator overloading for Arrays implementing INumber, but operator overloading is general in the sense that any user-defined class can provide operator overloading by defining a set of methods with standardized names.

The language constructs that Lino adds to the Java language are described below. Except for these additions, the Lino Language is the same language as Java 1.4. Java 1.5 language will be supported in the future.

Note that LinoLab can be used without the Lino language to run standard Java code. Also note that the Lino source is always translated to standard Java source code. This means that all existing Java tools such as debuggers, profilers and javadoc tools can be used.

3.1. Print Operator (;;)

The operator ";;" is called the print operator and is used to easily print the value of any expression to the session output. Think of it as translating

<expression>;;

to

<currentSession>.println(<expression>);

Here are some LinoLab commands as examples. Test them!

"hello LinoLab!";;

"java version = " + System.getProperty("java.version");;

"total memory (kb) = " + Runtime.getRuntime().totalMemory()/1024;;

3.2. Array Creation ([...])

LinoLab is especially suited to work with matrices and any kinds of arrays of numbers. Arrays are stored as linolab.array.Array objects and created either by creating an instance of the Array class or any subclass the ordinary Java way or by using a Lino Matrix Creation expression.

A 2D array can be defined by specifying the values in brackets []. Some examples follow.

Array v = [];           // the empty 2D matrix
v = [1, 2;              // 2x2 matrix
     3, 4];             //

v = [5; 
     6-1.8;
     7.3];              // a 3x1 column vector

Comma "," is used to separate the elements and semicolon ";" to separate the rows of the matrix. If not all rows are the same size an exception will be thrown when the code is executed. The array created is a 2D double precision real matrix (linolab.array.DArray).

Matrices can also be created with the Lino Colon Creation expression.

[ <startValue> : <increment> : <endValue> ]

The increment value is optional, if absent it is assumed to be 1.0 if <endValue> is larger then <startValue> and -1.0 otherwise. The result of the expression is a real double precision column matrix (column vector) of type linolab.array.DArray. For example

Array v = [0:9];      // a column vector with the values 0, 1, 2, ... 9

Run the following commands to get a feeling for it.

[1:5];;

[0:2:4];;

[0:-3];;

[0:-2:-4];;

[-3.3 : 1.1 : 10.9];;

Matrices can also be created by concatenating existing 2D arrays. For example try this.

Array a = [1:3];
Array b = [6:8];

[a, b];;

[a; b];;

[a, b;
 b, a];;

The array creating expression can be used to create arrays of arbitrary type, read the section "Details of the Lino Operators" for more information.

3.3. Plus and Minus (+, -)

Arrays (linolab.array.Arrays) can be added with the plus operator.

Try the following example commands:

[1,2] + [3,4];;        // adding two matrices

[1,2] + 1.23;;         // adding a double to a matrix is OK if the double value
                       // is the second operand

A unary plus or minus is allowed on front of an Array.

+[1, 2];;

Note that the operator overloading is general, the user can define his own classes that can be used with the +, -, /, * operators.

The Lino operator overloading does not modify the behavior of the standard Java operators but make the operators applicable for other types of operands.

The minus operator is used the same way as the Matrix plus operator. For example:

-[1; 2] - [1; 1];;

From the example we see that "-" can be used both as a unary operator and as a binary operator.

3.4. Lino Star Operator (*)

The star operator (*) can be used to multiply matrices. The matrices must have the correct sizes otherwise an exception is thrown at runtime. Try these examples.

[1, 2] * [1; 2];;

[1; 2] * [1, 2];;

The example

[1, 2, 3] * 1.5;;

shows that an Array can be multiplied with a normal Java double value. This has the expected effect of scaling the array with the value of the double variable. Note however that we cannot do this

1.5 * [1, 2, 3];;       // WRONG!

In Lino the first operand in binary operations decide the Java method to call and thus also the type of the result of the operation. A double variable do not implement any method to handle multiplication with an Array, so this will not work.

3.5. Lino Dot Star (.*) Operator

The dot star operator is used with Arrays to do elementwise multiplication. For example

[1, 2] .* [1, 2];;

prints 1.0, 4.0.

3.6. Lino Solve (\)

For Arrays the Lino solve operator is used to solve a system of linear equations, A X = B, where A must be square and non-singular. B may have several independent columns for which the solution is wanted. If A and B are Arrays, the expression A \ B will return the solution X.

One example:

Array a = [1, 2; 
           3, 4];
Array b = [4, 2].t();
Array x = a \ b;

"x = \n" + x;;
"a*x = \n" + a*x;;

3.7. Subarray and Index Operators([])

Subarrays

Given an Array we can get a subarray from it by using the Lino Subarray Operator. Here is the syntax for the 2D case, but the syntax works for arrays of any dimensionality.

vsub = v[start0:step0:end0, start1:step1:end1];

The variables start0, step0, end0, start1, step1, end1 must be integers within correct bounds. The values of the submatrix vsub will be vsub[i,j] = v[start0+step0*i, vstart1+step1*j].

step0 and step1 cannot be 0. The step variables are optional and defaults to 1 if end > start and to -1 otherwise. For example the following two expressions

v[0:2, 3:1];
v[0:1:2, 3:-1:1];

have the same meaning.

The end value can be -1 to indicate the end of the array. For example

v = v[2:-1];

removes the first two elements of the 1D array v.

A solitary colon means "all possible indices". For example, to get a row or a column of a matrix use a syntax like this.

col = v[:, 2];     // gets the third column
row = v[0, :];     // gets the first row

The []-operator can also be used to set subarrays. For example

v1[:, 2] = v2[:, 4];

sets a column of v1 to the the values of a column in v2.

Indexing

LinoLab also overloads "[]" for array indexing. For example try

DArray a = [1, 2; 3, 4];
a[0, 1];;

Note that since a is a DArray (dense double storage array) a double is returned with the index access operator. For this example

Array b = [1, 2; 3, 4];
b[0, 1].getClass();;

an INumber is returned from the expression b[0, 1].

The indexing for Arrays can be used with arrays of any dimensionality. All Arrays can be accessed with a single compound index, see package linolab.array.

Indexing with [] is not limited to getting values, but can also be used for setting values

a[0, 1] = 12;

Negative indices are never allowed when indexing a single number. For example

a[-1];;    // RUNTIME ERROR

will result in a runtime exception (linolab.array.BadIndex) being thrown.

3.8. Details of the Lino Operators

The sections on the Lino Language in this manual has so far only discussed how the operators work with Arrays. Operator overloading in Lino is more general than that and LinoLab provides operator overloading for more than Arrays. For example the number classes implementing INumber provides operator overloading. All operator overloading classes are not defined in this manual. Instead see the Javadoc documentation for the classes and packages for information on which classes that can be used together with operator overloading. The information below details the how overloaded operator expression are translated to standard Java code.

The Lino Language uses operator overloading for the operators in the table below. The operators are translated to method calls. For binary operators such as +, -, * the method is applied to the first operand with the second operand as a parameter. For example a+b is translated to a.linoPlus(b) unless a is a primary type in which case no translation occurs. The operator overloading never changes the standard Java behaviour of the operators, the operators are just made applicable to other types of operands. The following table shows operators and which method is used when translating the operations.

BINARY OPERATORS (6 methods)
    +       linoPlus  ( for example "a+b" -> a.linoPlus(b) )
    -       linoMinus
    *       linoStar
    /       linoDiv
    \       linoBack
    .*      linoDotStar
    
UNARY OPERATORS
    -       linoUnaryMinus
            (for example  "-a" -> "a.linoUnaryMinus()" if "a" is not
            a numerical Java type)
            
    Unary plus for non-primitive types are allowed but is translated
    by simply removing the "+" character.

INDEX ACCESS (4 methods)
    a[i]            a.linoIndex(i)
    a[i1,i2]        a.linoIndex(i1,i2)
    a[i1,i2,i3,i4]  a.linoIndex(new int[]{i1,i2,i3,i4}
    a[:]            a.linoRangeIndex(new int[]{-2,0,-2})
    a[b:c]          a.linoRangeIndex(new int[]{b,0,c})
    a[b:s:c]        a.linoRangeIndex(new int[]{b,s,c})
    a[:, 1:2:6]     a.linoRangeIndex(new int[]{-2,0,-2, 1,2,6})
    
INDEX ASSIGN (4 methods)
    a[i] = b        a.linoIndexAssign(i,b)
    a[i1,i2] = b    a.linoIndexAssign(i1,i2,b)
    a[i1,i2,i3] = b a.linoIndexAssign(new int[]{i1,i2,i3}, b)
    a[b:c] = b      a.linoRangeIndexAssign(new int[]{b,0,c}, b)
    a[:,1:2:6] = b  a.linoRangeIndexAssign(new int[]
                            {-2,0,-2, 1,2,6}, b);

Note that the first operand in a binary expression cannot be of a primitive type, for example 3*v will never be translated, but v*3 will if v is not a primitive type and the type of v has an appropriate linoStar method.

The index assign methods should return this since a standard Java assignment is also an expression.

These methods can be implemented in any class also user-defined classes. The operator overloading will work for these classes too. Note that only part of this set of operators needs to be implemented.

"Overloading" of Return Types

The above operator overloading described as a mapping between operators and corresponding methods is simple and adequate for many cases. However, assume we have a class MyNumber that extends MyAbstractNumber. MyAbstractNumber implements a method with the signiture public MyAbstractNumber linoUnaryMinus(). If we would like the unary minus operator to work for MyNumber we should implement a method public MyNumber linoUnaryMinus() in the class MyNumber but this is not possible according to the Java Language Specification since the return type is not identical to the method with the same signiture in the superclass. The solution to this is either to implement the method public MyAbstractNumber linoUnaryMinus() in NyNumber and use casts all the time. For example we must write

num = (NyNumber) (-num);

to change the sign of the MyNumber called num.

The Lino language provides another solution that avoids casts. If the method public MyNumber linoUnaryMinus_MyNumber() is implemented in NyNumber the expression -num will be translated to num.linoUnaryMinus_MyNumber() if num is a MyNumber and we can write

num = -num

to change the sign of num.

This way of "overloading" the return type is allowed for all Lino operator overloading methods in the above table.

Array Creation

An Array (linolab.array.Array or subclass) can be created with an expression like

[1,2,3; 4,5,6]

That expression will be translated to something like

linolab.array.LDouble.getArrayCreator().a(1).a(2).a(3).row(). a(4).a(5).a(6).end()

This array creator is used when the type of the first element is of primitive type. If not the first element's getArrayCreator method is used to get an object that can create the array. For example

[new LComplex(1.1,2), new LComplex(3,5)]

is translated to

(new LComplex(1.1,2)).getArrayCreator(). a(new LComplex(3,5)).end()

Note that this works for any object that implements a getArrayCreator method that returns an object of a type that has appropriate methods a, row and end. So the LinoLab user may implement his own array creators.

An appropriate getArrayCreator method has been created in Array with which arrays can be concatenated. For example

Array a = [1:5];
Array b = [6:10];
[a, b];;

prints the 5x2 array

1.0, 6.0
2.0, 7.0
3.0, 8.0
4.0, 9.0
5.0, 10.0

The expression [a, b] is translated to (a).getArrayCreator(). a(b).end().

The array type of the first element in the array concatenation will be used to determine the runtime type of the resulting array.

Details of the Print Operator

The print operator ";;" is used to easily print the value of any expression to the session output stream. Think of it as translating

<expression>;

to

<currentSession>.println(<expression>;);

What really happens is that <expression>; is translated to linolab.Printer.println(<expression>);. The exact method that is used for the translation may change for future LinoLab versions, but the meaning of the expression will be the same. The variable is printed to the session output with an ending new line (\n) character. For objects the Object.toString method is used to retrieve a String representation of the object.

An Example

The example below shows how a user-defined type can use operator overloading. It also shows how Array can be used with a new number type and how array creation expressions can be created from user-defined number types.

Assume we need to work much with integer arithmetics modulus 8. We create an Int8 class with the following Java code.

package pack;

/**
 * A class that handles integers modulus 8.
 * Only addition and multiplication is supported.
 */
public class Int8 {
    public static final int M = 8;
    private int value;
    
    public Int8(int value) {
        this.value = value % M;
    }
    
    public int getValue() {
        return value;
    }
    
    public Int8 linoPlus(Int8 a) {
        return new Int8((a.getValue() + value) % M);
    }
    
    public Int8 linoPlus(int a) {
        return new Int8((a + value) % M);
    }
    
    public Int8 linoStar(Int8 a) {
        return new Int8((a.getValue() * value) % M);
    }
    
    public Int8 linoStar(int a) {
        return new Int8((a * value) % M);
    }
    
    public String toString() {
        return "" + value;
    }
}

Test the class with the command

pack.Int8 a0 = new pack.Int8(5);
pack.Int8 a1 = new pack.Int8(2);
a0 + a1 + a1;;
a0 * a1;;
a0*2 + a1*3;;

If we would like to be able to work with arrays of Int8s we should make Int8 implement linolab.array.INumber. This is easily accomplished by extending AbstractNumber. The code below is a full example that can be compiled and tested.

package pack;
import linolab.array.*;

public class Int8b extends AbstractNumber {
    public static final int M = 8;
    private int value;
    
    public Int8b(int value) {
        set(value);
    }
    
    public int getValue() {
        return value;
    }
    
    public double toDouble() { 
        return value; 
    }
    
    public INumber set(double d) {
        value = ((int)Math.round(d)) % M;
        if(value < 0) {
            value += M;
        }
        return this;
    }
    
    public INumber newZero() { 
        return new Int8b(0); 
    }
    
    public GeneralArrayCreator getArrayCreator() {
        return new GeneralArrayCreator(this);
    }
    
    public String toString() {
        return "" + value;
    }
}

Note that the linoPlus, linoStar methods and others are already implemented in AbstractNumber and we can use those methods without modification. The only modulus 8 specific part is the set method. The getArrayCreator method makes it possible to create arrays of Int8bs with the []-array creation operator. Try the example commands below (separated by a blank line).

addImport("pack.*");

Array arr = [new Int8b(4), new Int8b(5), new Int8b(6)];
arr;;
arr.sum();;
arr + arr;;
arr+1 + arr*2;;
arr[0] = 14;
arr;;

All methods of Array will be possible to use even though some of them (trigonometric functions for example) will not be very useful.

If we would need higher performance we could create an array class called DenseInt8Array that extends Array and override methods for performance. We may need a better storage scheme than storing an Int8b object for each value in the array. We really would only need 3 bits per number. A reasonable implementation for large arrays would be to store two Int8bs in each storage byte. This can be accomplished with a class implementing IStorage. This storage class can either be DenseInt8Array or a separate class.

The example above shows how a whole new number type and Array type can be added to the LinoLab Array package infrastructure with only one new class and 40 lines of code. All existing methods of Array and all Lino array operators (+, -, * etc) will work for the new number type.

Chapter 4. Guide to Features

4.1. LinoLapack

LinoLapack is a Java interface to LAPACK (www.netlib.org/lapack/) and BLAS (www.netlib.org/blas/). More information on LinoLapack is available in the Javadoc for the package linolab.linolapack. This section describes how to use LinoLapack in LinoLab.

Installation

To use LinoLapack with LinoLab you need a LinoLapack DLL file. A LinoLapack DLL file is a Windows "DLL" file or a Unix/Linux "SO" file or similar that is used by Java through the Java Native Interface (JNI) to enhance the performance of matrix operations.

Some LinoLapack DLL files are available from the LinoLab Extra Download. The DLL files are different for each operating system and processor type. Linova creates DLL files for a set of common platforms. Hopefully one of the DLL files will work with your system, otherwise you can build your own, see the documentation for the package linolab.linolapack.dev and please send the resulting DLL files to Linova.

The simplest way to install LinoLapack is to copy a suitable LinoLapack DLL file from the LinoLab Extra Download to the directory USERDIR/dll/default and restart LinoLab. That's it if your startup script (USERDIR/path/startup.script) includes the method call loadDefaultLinoLapackDLL() which it does by default.

To use a DLL file in another location try the commands loadLinoLapackDLL(<filename>), or loadLinoLapackDLL() (documented in the javadoc for linolab.ICommandMethods).

Note, it is not possible to use many different DLL files without restarting LinoLab. It is however possible to toggle between using a pure Java implementation of the matrix library or the native LinoLapack version. This is accomplished with the commands useJavaMatrixLib(); and useNativeMatrixLib();.

Performance compared to Matlab when solving a large linear system

The program Matlab from Mathworks (http://www.mathworks.com/) is developed for handling matrices. Matlab's performance is good when dealing with large matrices, but not good for function calls and non-trivial loops.

A simple comparison of the performance of Matlab 6.5 and LinoLab 0.11 is done for a specific problem: solving a dense system of linear equations. A x = b where A is a double precision 1000x1000 matrix. b is a 1000x1 vector. A and b have random values.

The platform I (Frans Lundberg) am using is Windows XP with an Athlon 2400+ CPU. The Java runtime is the Java Runtime Environment from Sun version 1.4.2_05. The LinoLapack DLL file linolapack0_xp_ath1.dll has been put in the LINOLAB/user/dll directory. Note that to run these benchmarks at full speed you need to buy a LinoLab license from Linova. The free default license, licensed to "everyone", is four times slower than the full version.

Here is the Matlab code.

A = rand(1000, 1000);
b = rand(1000, 1);
tic;
A \ b;
t = toc;
disp(['Matlab: it took ', num2str(t), ' seconds.']);

And the LinoLab commands separated by a blank line.

DArray A = DArray.rand(1000, 1000);
DArray b = DArray.rand(1000, 1);

A \ b; &;

The tests were run eight times and the fastest time is recorded. Results: Matlab 0.80 s, LinoLab 8.3 s. LinoLab is 10 times slower. But after the LinoLab command

loadLinoLapackDLL("linolapack0_xp_ath1.dll");

the test

A \ b; &;

takes only 0.47 s. Now Matlab is 70 per cent slower. If we want we can optimize the LinoLab command further to avoid memory allocation. First the command

linolab.linolapack.Lapack lapack = new linolab.linolapack.Lapack();
int[] ipiv = new int[1000];
int[] info = new int[1];

is run to create a LAPACK library and temporary storage. Then

lapack.dgesv(1000, 1, A.getValues(), 1000, ipiv, b.getValues(), 
        1000, info); &;

is run to solve the equation. This runs in 0.31 s which is faster than using LinoLab's backslash operator and much faster then Matlab's backslash operator.

Table 4.1. Performance LinoLab versus Matlab when solving a large linear system

TestTime (sec)
LinoLab without DLL8.3
Matlab0.80
LinoLab with DLL A\b0.47
LinoLab with DLL, lapack.dgesv0.31

Most of the floating point operations takes place in the LU-factorization of the matrix A. This factorization uses (2/3)*1000^3 floating points operations. This means that for the last test case (lapack.dgesv) we have (2/3)*1000^3 / 0.31 = 2.15 Gflop/s.

4.2. Mathematics

This section describes how to use LinoLab for the specified mathematics. Often this section simply contains references to API (javadoc) documentation for specified classes which contains more detailed information. The documentation for third party libraries are available with the LinoLab Extra Download package.

Linear Algebra

The linolab.array package contains methods for storing arrays of arbitrary dimension including 2D matrices. Read more about it in its API documentation.

Table 4.2. Linear Algebra Classes

FeatureClasses, methods
Matrix inverselinolab.array.Array.inv
LU-decompositionlinolab.array.Array.lu
Solving linear equation systemlinolab.array.Array.linoBack, or the backslash operator
Determinantlinolab.array.Array.det
Eigen-value decompositioncern.colt.matrix.linalg.EigenvalueDecomposition
QR-decompositioncern.colt.matrix.linalg.QRDecomposition
Singular value decompositioncern.colt.matrix.linalg.SingularValueDecomposition
CholeskyDecompositioncern.colt.matrix.linalg.CholeskyDecomposition
Sparse matricescern.colt.matrix.impl.SparseDoubleMatrix2D, cern.colt.matrix.impl.RCDoubleMatrix2D, linolab.array.SparseStorage

Statistics

The package cern.jet.random.engine contains high-performance random number generators. cern.jet.random supports a large variety of probability distributions: uniform, binomial, Breit-Wigner, Chi-Square, gamma, logarithmic, normal, poisson, Student-T, hyperbolic, hyper geometric, Burr, Cauchy, Erlang, Geometric, Lambda, Laplace, Logistic, Weibull and more.

The package cern.jet.stat contains Tools for basic and advanced statistics: Estimators, Gamma functions, Beta functions, Probabilities, Special integrals, etc.

Packages hep.aida, hep.aida.ref (part of Colt) contain compact, extensible, modular and high-performance histogramming functionality.

Table 4.3. Statistics Classes

FeatureClasses, methods
Random number generatorscern.jet.random.engine
Mersenne Twister random number generatorcern.jet.random.engine.MersenneTwister
Simple Random Sample Without Replacement (SRSWOR)cern.jet.random.sampling
Correlation, auto-correlation, covariancecern.jet.stat.Descriptive
Alternative implementation for distributionsJSci.maths.statistics

Miscellaneous Mathematics

Table 4.4. Miscellaneous Mathematics Classes

FeatureClasses, methods
Bessel functionscern.jet.math.Bessel
Arithmetic functions (Chebyshev polynomial, binomial)cern.jet.math.Arithmetic
Quaternionslinolab.array.LQuaternion
PolynomialsJSci.maths.polynomials
MathML (XML)JSci.io
ChaosJSci.maths.chaos
WaveletsJSci.maths.wavelet
SplinesJSci.maths.wavelet.splines.Spline
Numerical integrationJSci.maths.NumericalMath.simpson/trapezium/richardson
Ordinary Differential EquationsJSci.maths.NumericalMath.euler/leapFrog/rungeKutta
Numerical DifferentiationJSci.maths.NumericalMath.differentiate
Algebras, Hilbert space, Lie AlgebraJSci.maths.algebras
FFT, Fast Fourier TransformJSci.maths.FourierMath
InterpolateJSci.maths.polynomials.PolynomialMath.interpolateLagrange

Physics

Table 4.5. Physics Classes

FeatureClasses, methods
Physical constantscern.clhep.PhysicalConstants
Periodic tableJSci.chemistry.periodictable
Quantum MechanicsJSci.physics.quantum
RelativityJSci.physics.relativity

4.3. Plotting

The LinoLab Plot support is provided by the Java package linolab.plot. linolab.plot is based on JFreeChart (www.jfree.org) and provides the following features.

  • Integration with linolab.array package.

  • Plot properties make it easy to create a plot with a single line of code.

  • Interactive zooming.

  • Plot types supported include XY plots, XY plots with logarithmic scale, bar plots, histogram plots. Many other plots are also supported by using the JFreeChart directly.

  • Plots are highly customizable.

  • Plots can be output to: screen, printer, JPEG image, PNG image, EPS (Encapsulated Postscript), and SVG (Scalable Vector Graphics).

  • Time series data is supported. Plots can be constructed with a time axis that displays time in a hour-minute-second format (or year-month-day for data spanning a longer time interval).

Besides the plot information presented here LinoLab's plot support is documented by the Javadoc for the package linolab.plot. Example of commands to create plots are provided from the LinoLab context menu. Try those examples! The figure below shows the output from one of them (MultiPlot Demo).

Creating a Plot

Don't be intimidated by all the classes in the linolab.plot package. Most users will only use the single class linolab.plot.LPlot for all their plotting needs.

LinoLab plots (LPlot objects) are created with static methods in LPlot named after the plot type. Currently, the following plot types are supported: "xy", "bar", "hist". These plot types are implemented in the classes LXYPlot, LBarPlot, and LHistPlot, but these LPlot subclasses are normally not used directly.

A plot is created with the following steps.

  1. LPlot Instance. Create a plot object instance with a static factory method in LPlot. Use one of the methods LPlot.xy, LPlot.bar, LPlot.hist, or the general-purpose method LPlot.plot.

  2. Plot Properties. The next step is to set plot properties with the set(String commandLineString) and set(String name, Object value) methods. This step is optional.

  3. Create/Output Plot. The last step is to create and possibly output the plot (draw it) to an output device, for example to the computer screen or to a JPEG image file.

A simple command that displays a plot is:

LPlot.xy([10:-6])
    .set("title", "My First Plot")
    .set("xlabel", "The x values")
    .output();

The example produces the following plot.

We could equivalently have created the plot with the command.

LPlot.xy([10:-6]).set("-title 'My First Plot' -xlabel 'The x values'").output();

Using multiple calls to set(String,Object) is preferred since it allows properties to be set with arbitrary objects, not only Strings. The last .output() outputs the plot to the default output device which is normally the computer screen.

Plot Properties

Plot properties are used to set and get properties of the plot. Each plot type have a different set of named properties that can be modified. The command

LPlot.getHelp("xy");;

prints information on all properties for a plot of type "xy". The same command with the string "hist" or "bar" will print information about properties that applies to those types of plots.

Plot properties can also be set and gotten after a plot has been created. For example:

LPlot p = LPlot.xy([10:-6]).set("subtitle", "First Subtitle").output();
"first subtitle = " + p.getString("subtitle");;
p.set("subtitle", "New Subtitle");

Note that all properties cannot be set after the plot has been created and some can be set but have no effect. Some properties may be set-only or get-only. Property errors are reported with instances of the runtime exception class PropertyException.

Outputting a Plot

An LPlot can be output to a number of different output devices. This is done with the LPlot.output(String commandLine) method that takes a String in command line format. For example the command

LPlot p = LPlot.createXYDemo();
p.output("-type screen -size 300 200 -location 200 0");

draws a demo XY plot a screen pixel location 200, 0. The plot panel is 300 by 200 pixels. Another example is

LPlot.createXYDemo().output("-file C:/temp/plot.png");

The command creates a PNG image of default size. Note that we do not need to specify a "-type" flag. The output type is determined from the suffix of the filename. The next example prints a plot to one page on a printer chosen interactively by the user.

LPlot.createXYDemo().output("-type printer");

Currently, there are seven supported output types:

  • "none". Does not draw the plot to any device.

  • "screen". Draws the plot to the computer screen.

  • "printer". Draws the plot to a printer chosen by the user in an interactive dialog. The plot will be printed to one page.

  • "jpeg". Draws the plot to a JPEG image file. JPEG compression is not really suitable for plots, however it is such a common image format so it is still supported.

  • "png". Draws the plot to a PNG (Portable Network Graphics) image file. PNG is a lossless image file format well suited for plots. See the specification at www.w3.org/TR/PNG/.

  • "eps". Draws the plot to an EPS (Encapsulated Postscript) file. This is a vector graphics format suitable for high-quality printed material. The free program GSview can be used to view EPS files and convert them to PDF files.

  • "svg". Scalable Vector Graphics. This is a quite new and promising vector graphics format. It is XML-based and it is defined by http://www.w3.org/TR/SVG11/. If this output format is used, plot figures can be edited! Try Inkscape (http://www.inkscape.org/).

Below is a list of all output types and the flags and parameters the type supports.

======== none ========
No flags and parameters used.

======== screen ========
-location
    Two integers with the pixel position of the plot window. A Java 
    AWT coordinate system is used. So the origin is the upper left 
    corner of the screen. x increases to the left and y increases 
    downwards.
-size         
    Two integers with pixel width and pixel height of the plot panel.
-windowTitle
    The title of the plot window will be set to this value.
    If the title contains spaces enclose it with '' characters.
    
Example output command line:
  -type screen -location 300 0 -size 600 400 -windowTitle 'Plot 3'
  
======== printer ========
No flags and parameters used.

======== jpeg ========
-file
    Full filename of the file to create.
-size
    Two integers with pixel width and height of the plot image.
-quality      
    A number larger then 0.0 and less than 1.0. This is the 
    compression level. Use a high value for high quality and a low
    value for high compression.
    
Example output command line: 
  -type jpeg -file C:/temp/plot.jpeg -size 600 400 -quality 0.7

======== png ========
-file
    Full filename of the file to create.
-size
    Two integers with pixel width and height of the plot image.

======== eps ========
-file
    Full filename of the file to create.
-size
    Two integers with pixel width and height of the plot drawing.

======== svg ========
-file
    Full filename of the file to create.
-size
    Two integers with pixel width and height of the plot drawing.

Sometimes one might want to output a number of plots together. The MultiPlot class is used to arrange a number of plots in a rectangular grid and then output all plots together as if they were one plot only. Try the demo method MultiPlot.demoMulti().

Array-Convertible Plot Data

The static plot creation methods in LPlot often takes Array-convertible Object parameters instead of Arrays. An Array-convertible Object is an object that can be converted to an Array with the method linolab.array.Convert. The use of Array-convertible objects instead of Arrays makes it easy to work with other array representations, for example double[] or Colt matrices (see Extra Download). The example below displays a plot directly from a double[] array.

LPlot.xy(new double[]{3,2,1.5,1.25,1.1,1.05}).output();

Property Help

Below is the current (19 May 2005) help for the available plot types.

---------------------------------- xy ------------------------------------------

---- background ----
Sets the plot chart background color
See linolab.plot.Colors for how to specify a color with a String.
Sets with a String or a java.awt.Color object, get as a Color object.

---- legend ----
Whether to show a legend or not.
Possible String values:
    true - show legend
    false - do not show legend
    auto - let LinoLab decide
Set the value with a String, get is as a String.

---- line ----
This property determines how each series of data in a xy plot should
be rendered. It determines line style, line width, marker type, 
marker size and line color according to a LineSpec string 
specification as defined in the LinoLab Manual.

---- seriesNames ----
Sets the names of the series. These names are used in the
legend for XY plots.
Set with a single String of comma-separated parts or a String[],
Get as a String[].
Set the property to null to use default names.

---- subtitle ----
The title of the plot get/set as String.

---- time ----
This property determines whether to use a time scale for the x axis.
Set with a String "true" or "false" or a Boolean. Get as a Boolean.

---- title ----
The title of the plot get/set as String.

---- xlabel ----
The x-axis label text.

---- xlim ----
Two values: min x range and max x range.
Set the property with a String with two space-separated numbers or 
with a 2 long Array.
Get as an 2x1 DArray ([min; max])
If either min or max is set to NaN the plot will auto-range.
If set with a string "auto" can be used instead of "NaN NaN".

---- xlog ----
This property controls whether the x axis is logarithmic or not.
Set with a String "true" or "false" or a Boolean, get as a Boolean.

---- ylabel ----
The y-axis label text.

---- ylim ----
Two values: min y range and max y range.
Set the property with a String with two space-separated numbers or 
with a 2 long Array.
Get as an 2x1 DArray ([min; max])
If either min or max is set to NaN the plot will auto-range.
If set with a string "auto" can be used instead of "NaN NaN".

---- ylog ----
This property controls whether the y axis is logarithmic or not.
Set with a String "true" or "false" or a Boolean, get as a Boolean.



------------------------------- bar ----------------------------------

The following properties are available for bar plots and have the same
definitions as for an xy plot:
    background,
    legend,
    title,
    subtitle,
    xlabel,
    ylabel.


    
-------------------------------- hist --------------------------------

The following properties are available for bar plots and have the same
definitions as for an xy plot:
    background,
    legend,
    title,
    subtitle,
    xlabel,
    ylabel,
    xlim, 
    ylim.

---- histogram ----
This property is a user get-only property that is used to get the
histogram (hep.aida.IHistogram1D) created for a hist plot.

---- verbose ----
Determines whether or not information should be printed to session
output when the plot is created or outputted.
Set with a String with value "true" or "false" or a Boolean.
Get as a Boolean.

Note that the set of properties is not yet stable and may change between LinoLab versions.

LineSpec String Definition

linolab.plot uses a compact way to specify the most common line settings for XY plots in the "line" property. These settings are set with LineSpec strings. The LinoLab LineSpec is nearly identical to the LinoSpec in Matlab, but LinoLab's LineSpec allows more colors and line styles. Additionally the marker size and the line thickness can be set with LinoLab's LineSpec strings. If you have Matlab type "doc linespec" for a comparison.

A LinoLab LineSpec string consists of 1 to 3 parts each of which can be a Color-part, LineStyle-part, or a MarkerShape-part. Several parts of the same type cannot appear in the LineSpec string. The LineSpec is not allowed to start with the character '-' so it is advisable not to start the LineSpec string with the LineStyle part. The parts can however otherwise be ordered any way. Below is a description of the parts.

---- Color ----
Allowed characters:
    r = red
    g = green
    b = blue
    c = cyan
    m = magenta
    y = yellow
    k = black
    w = white
A color character cannot appear more than once.
The color prefix 'D' can be used to get a darker color, for example 
"Db" means dark blue.

---- LineStyle ----
The four allowed style characters: "-_:.". A LineStyle parts consists 
of a style part with any number of style characters followed by an 
optional line thickness integer. ':' is the same as '.' (for Matlab 
compatibility). The style characters are combined in a sequence to for
a line style, examples follow.
    -       solid line
    _       solid line
    :       dotted line
    .       dotted line
    --      dashed line
    __      dashed line (with long line segments)
    -.      dash dot line
    _.      dash dot line (with longer line segments)
    -..     dash dot dot
    -...    dash dot dot dot
    --.     dash dash dot
    __.     long dash long dash dot
    
Use any combination. Try it out! A line style sequence of characters 
can be suffixed with a line thickness integer, for example
    --3     thick dashed line
    -1      normal solid line
    
---- MarkerShape ----
The possible marker shape characters are the following.
    +       plus sign
    o       circle
    *       asterisk
    p       point (smaller circle)
    x       cross
    s       square 
    d       diamond
    ^       upward pointing triangle
    >       right pointing triangle
    <       left pointing triangle
    
Note LinoLab uses 'p' instead of '.' for a point to avoid confusion 
with the line style character. Matlab's 'p' (five-pointed star) and 
'h' (six-pinted star) are not supported.

A marker size integer can be suffixed after the marker character as a 
part of the MarkerShape part of the LineSpec string. For example:
    o12     large circles
    x5      normal sized crosses

---- Examples ----
Some complete examples.
    g       a green solid line
    Dr.     a dark red dotted line
    o       circle marker not connected with a line, JFreeChart 
            chooses color
    go20-3  green, huge circle markers connected by a solid line 3 
            units thick

It is possible to specify the properties of many plot sets by using 
space-separated LineSpec strings. For example the following three 
LineSpec strings
    k- k-- k_.
    
could be suitable for a black and white print of the plot.

An example of LineSpec usage is provided below.

Array x = [0:0.20:2*Math.PI];
LPlot.xy(x, [x.sin(), x.cos(), x.sin()+0.3])
        .set("line", "k..__ b* Dgo10-4").output();

The plot looks like this.

Plot properties and JFreeChart API

Some plot properties such as "title" has a 1-to-1 relationship with the JFreeChart API. This means that we can freely mix using the linolab.plot or the JFreeChart API to set/get the property. A linolab.plot "get property" will take into account changes made through the JFreeChart API. For other properties a LinoLab "get property" returns the last property value set by linolab.plot, it will not reflect changes made directly with the JFreeChart API after the property was set with linolab.plot. This is because it is generally impossible to do so since the JFreeChart provides a more detailed interface than linolab.plot do. A single linolab.plot property may set a range of internal JFreeChart properties, which if they are changed cannot in general by mapped back to the simpler linolab.plot property.

Headless Environment

If LinoLab runs in a non-graphical environment (command prompt installation or run mode of Linux, J2EE-container, or something like that) JFreeChart and therefore linolab.plot may not run as expected since graphical output to the screen is not allowed. Consider setting the option java.awt.headless to true by starting Java like this: java -Djava.awt.headless=true ... . Another option for Linux and other unixes is to use X Virtual Frame Buffer (Xvfb). Yet another option could be the Pure Java AWT (PJA).

Linova recognises the need to be able to create graphics files (PNG images, or SVG files for example) even though no visual graphics environment is available. In a server environment this could be essential.

4.4. LinoLab Server

LinoLab Server is a server that allows clients to run LinoLab sessions on the server. The server handles multiple concurrent users. All communication is encrypted using PKI (Public Key Infrastructure) and SSL (Secure Socket Layer). Clients can be restricted to be able to access files from certain directories only.

LinoLab Server is documented in the Java package linolab.server. Also see the package linolab.client.

4.5. LinoLab and QNX

This section describes some experience Linova has with using LinoLab together with the QNX Neutrino operating system. The tested QNX installation is QNX Neutrino 6.3.0 on a PC. The LinoLab version is 1.0.

Unfortunately QNX does not yet come with a full J2SE 1.4 Java virtual machine (JVM). This means that the LinoLab application itself will not run on QNX. However, programs created with LinoLab are likely to run on QNX as the examples below show. It is probable that a J2SE JVM will be available for QNX in the next year or so. When this happens LinoLab will run on QNX as it does on all other platforms.

The JVM that comes with QNX is J9 from IBM. Typing j9 -version on the QNX command prompt results in the following output (somewhat abbreviated).

java version "1.3.0"
License Material - Property of IBM
J9 - VM for the Java(TM) platform, Version 2.1
Target: 20031212c (QNX 6.3.0 x86)

The information on this JVM is sparse. It implements a subset of J2SE. It seems to implement J2ME (Java 2 Micro Edition) CDC (Connected Device Configuration) and other subsets of J2SE. http://java.sun.com/j2me/ has more information on J2Me. The standard Java GUI packages java.awt and javax.swing are not supported. The SWT (Standard Widget Toolkit) from Eclipse (www.eclipse.org) can be used instead to create graphical user interfaces.

Run this command in LinoLab.

buildApp("\"Hello QNX!\";;");

It creates the file USERDIR/app.jar which is an executable jar file. Copy it to QNX and run the command

j9 -jar app.jar

It should print Hello QNX!

The next example solves a linear equation system. Create the following class. Call the source file QNXTest.lino and place it on userpath.

import linolab.array.*;

public class QNXTest {
    public static void run() {
        DArray a = DArray.rand(3, 3);
        DArray b = DArray.rand(3, 1);
        DArray x = null;
        
        "a = " + a;;
        "b = " + b;;
        x = a \ b;
        "a \\ b = " + x;;
        "a * x = " + (a*x);;
        "a * x - b = " + (a*x - b);;
    }
}

Run

buildApp("QNXTest.run();");

In LinoLab to create a new app.jar (it overrides the old jarfile unless it was renamed).

Copy the created app.jar file to QNX an run it.

j9 -jar app.jar

The linolab.array package is intended to run with Java 1.2 and should work with QNX J9. The whole Colt library (see LinoLab Extra Download) runs on Java 1.2 and most of that should also be possible to use on QNX.

Note that LinoLab for QNX is not supported in any way. We are just saying that many programs developed with LinoLab may run on QNX.

Chapter 5. LinoLab versus Matlab

5.1. Features

The table below compares LinoLab with Matlab for a number of features.

Table 5.1. Features of LinoLab and Matlab

FeatureLinoLabMatlab
Thread-supportYesNo
Object-orientationYesNo (not real OO)
Based on standardsYes, all source code is either written or translated to standard Java code that can be used with a large number of other development tools.No, only Mathworks tools can be used to develop the software.
Scales to large projectsYesNo
Strictly typedYesNo
High-performance matrix library.YesYes
Sparse MatricesYes, but not Lapack-optimized yetYes
PlottingYes, provided by JFreeChart, not yet fully integrated LinoLab arraysYes
Standalone programsYes, platform-independentOnly with Matlab compiler
Multiple programming languages supportedYesNo
Open SourceMostlyNo
Free VersionYesNo
Large user-baseNoYes
Hardware-limited performanceYesNo
Install file size10 Mb (+30 Mb for Extra Download)1 - 2 CDs

5.2. Performance

This section compares the performance of LinoLab with Matlab for some basic pieces of language constructs. A PC with an Athlon 2600+ processor running Windows XP was used for these tests. For all details see LLR001 (LinoLab Report 1, included in LinoLab Extra Download). Since LinoLab's basic language constructs are Java-based this comparison is really also a comparison between Java and Matlab.

Three so called platforms are compared.

  1. Native - Perf.java compiled with GCJ.

  2. LinoLab 1.1.

  3. Matlab 6.5.

GCJ is part of the famous GCC (GNU Compiler Collection) and is used to produce a stand-alone program (perf.exe) in machine code from the Perf.lino.

The source code below is used for the Native and LinoLab platforms. The source code for Matlab is available in LLR001.


//------------ Perf.lino -------------------------------------
import linolab.array.*;

/** Class for simple performance tests. */
public class Perf {
    public static int addOne(int myInt) { return myInt+1; }
    
    public static void recursive(int levels) {
        if(levels != 0) {
            recursive(levels-1);
        }
    }
    
    public static void main(String[] args) throws Exception {
        int n = Integer.parseInt(args[1]);
        DArray arr = DArray.zeros(1000*1000, 1);
        int myInt = 0;
        
        long t0 = System.currentTimeMillis();
        if(args[0].equals("loop")) {
            for(int i=0; i<n; i++) {
            }
        } else if(args[0].equals("function")) {
            for(int i=0; i<n; i++) {
                myInt = addOne(myInt);
            }
        } else if(args[0].equals("recursive")) {
            for(int i=0; i<n; i++) {
                recursive(100);
            }
        } else if(args[0].equals("sum")) {
            for(int i=0; i<n; i++) {
                arr.sum();
            }
        } else {
            System.out.println("bad test name");
        }
        
        long t1 = System.currentTimeMillis();
        "n  = " + n + ", time = " + (t1-t0);;
    }
}

The following tests are used.

  1. loop - An empty loop.

  2. function - A simple function call.

  3. recursive - A recursive function call.

  4. sum - Computes the sum of a long vector.

  5. linearSystem - Solves a 1000x1000 linear system of equations. This test is described in the LinoLapack chapter. Note that if LinoLab is used without LinoLapack, Matlab is faster.

Relative times execution times (small numbers are better) are presented below with the LinoLab platform as the reference.

Table 5.2. Performance of LinoLab versus Matlab

TestNativeLinoLabMatlab
loop0.761.02.1
function4.51.03100
recursive3.81.05500
sum1.01.00.97
linearSystem-1.01.7

Chapter 6. Versions, Bugs and Issues

Please send bugs, issues and general feedback to the email: frans at linova.com.

6.1. Versions

  • 0.1, 1 June 2002, prototype release, commands can be run (compiled, written to file, loaded, and executed). Kopi compiler used. Software was called JLab.

  • 0.5, 14 March 2004 (my birthday!), first public release, freeware, pure Java support, no language additions except the print operator, some bugs expected

  • 0.6, released 15 May 2004, parallel jobs can be run, freeware

  • 0.7, 29 August 2004, matrix operators (.+, .-, .*, .\) supported but not documented. license-handling is used.

  • 0.8, 29 September 2004, improved jEdit plugin, AntTask created, many new matrix features, non-existent script results in error message, better line number correspondence between lino and java source files

  • 0.9, 14 October 2004, LinoLapack documented, new matrix features, bug fixes, enhanced User's Manual, the LinoLab Extra Download introduced. The BuildApp feature is included.

  • 0.10, 1 December 2004, help viewer added, libraries now in LINOLAB/system/jars, command line installation supported, submatrix/element access with new .[ operator, user testing with "test()" command, now works better with Mac OS X

  • 0.11, 7 February 2005, context menu added, submatrices can be set (for example A[:, 1] = B;), several modes supported, SuperScript supported but not really documented, The "dots" for in the Lino specific operators have been removed. The general array package (linolab.array) was introduced.

  • 1.0, 16 February 2005. Version 1.0 of LinoLab concentrates on stability, new unit tests and user documentation. The window location, window size and command history is saved between application runs. Array concatenation with [] operator supported. The user-specific files are stored in HOME/linolabX.Y/user instead of in the installation directory. This means that we can install LinoLab on a shared filesystem and have many users of the same installation. License things updated. Part of LinoLab source code accessible.

  • 1.1, 27 February 2005. Bug fixes. Preprocessor (!!-way of inserting text) removed. LinoGrid user classes added. Documentation much improved. The LinoLab Matlab Interface (LMI) included (not tested/documented much).

  • 1.2, 30 March 2005. LMI improved and documented. Mode "matlab" registered in mode list by default. Popup context menus improved. SuperScripts can be executable. Improved startup parameters. jEdit version updated to 4.2. Feedback GUI created. License string installation.

  • 1.3, 18 April 2005. LinoLapack is now available for Mac OS X. Application logging added. BuildApp feature improved. Important bug fixes.

  • 1.4, 1 May 2005, significant performance improvements: translation is now typically 4 times faster, better ANT support, startup tasks, important bug fixes, jEdit plugin updated.

  • 1.5, 1 June 2005, plot support added. Job handling works for any LinoLab Mode. Better session interface. Status bar added to GUI. Current directory setting and "LinoLab files" feature added. Support for user-chosen USERDIR directory makes it possible to run many LinoLab processes on same computer and with the same user.

  • 1.6, 1 July 2005. Remote interface, LinoLab can be controlled via network. Pure Java mode (no Lino language constructs allowed).

  • 1.7, 1 September 2005. Bug fixes, unit tests, stability, documentation, and completeness is emphasized in this release. Better support for complex matrices.

6.2. Bugs

Bugs fixed for next release are marked with FIXED!

Version 1.5

  • MOVED! BUG1, moved to BUG 1.6-1

  • FIXED! BUG2, the command "new DArray();;" results in a NullPointerException.

  • FIXED! BUG3, user classes existing as class files on userpath often results in ClassCastExceptions when instances are stored in workspace and later retrived.

Version 1.6

  • FIXED! BUG1, LinoLab crashes if a variable is added to the workspace with an incorrect LinoLab Type Name. For example issue the command "IWorkspace w = Access.getSession().getWorkspace();" followed by "w.add("myBytes", new byte[]{(byte)5}, "@");" and then use the variable "myBytes" by issuing the command "myBytes;;".

  • FIXED! BUG2, The logging to log-*.txt files in USERDIR/temp does not work as expected.

  • FIXED! BUG3, The license handling does not work properly for non-default USERDIR directories supplied with the "-userdir" flag like this: "java -jar linolab.jar run -userdir C:\myDir".

  • FIXED! BUG4, The LinoLapack DLL "linolapack0_xp_ath1.dll" causes java.lang.UnsatisfiedLinkException:s for some LAPACK functions. The DLL should be replaced by "linolapack_xp_ath2.dll" included in LinoLab Extra Download.

  • FIXED! BUG5, The method linolab.array.Array.abs() is not correct.

  • FIXED! BUG6, The method linolab.array.Array.exp() is not correct.

Version 1.7

  • Please report bugs!

Chapter 7. Acknowledgements

Thank you, Pär Skoglar at www.foi.se for bug reports and feedback.

Thank you, Wolfgang Hoschek for creating the Colt Java library for high performance scientific and technical computing.

Thank you, Slava Pestov and others for creating the excellent text editor jEdit (www.jedit.org).

Thank you, David Gilbert for the plot package JFreeChart.

Thanks to the people behind the Eclipse IDE.

Thanks to Sun Microsystem for creating Java.

Thank you Paul Mutton for EpsGraphics2D.