LME Reference

This chapter describes LME (Lightweight Matrix Engine), the interpreter for numerical computing used by SysQuake.

Program format

Statements

An LME program, or a code fragment typed at a command line, is composed of statements. A statement can be either a simple expression, an affectation, or a structure statement. Statements are separated by commas, semicolons, or end of lines. The end of line has the same meaning as a comma, unless the line ends with a semicolon. When simple expressions and affectation are followed by a comma (or an end of line), the result is displayed to the standard output; when they are followed by a semicolon, no output is produced. What follows structure statements does not matter.

When typed at the command line, the result of simple expressions is assigned to the variable ans; this makes easy chaining computations.

Continuation characters

A statement can span over several lines, provided all the lines but the last one ends with three dots. For example,

1 + ...
2

is equivalent to 1 + 2. After the three dots, the remaining of the line, as well as empty lines and lines which contain only spaces, is ignored.

Comments

Unless when it is part of a string enclosed between single ticks, a single percent character or two slash characters mark the beginning of a comment, which continues until the end of the line and is ignored by LME. Comments must follow continuation characters, if any.

a = 2;    % comment at the end of a line
x = 5;    // another comment
% comment spanning the whole line
b = ...   % comment after the continuation characters
    a;
a = 3%   no need to put spaces before the percent sign
s = '%';  % percent characters in a string

Comments may also be enclosed between /* and */; in that case, they may span several lines.

Types

The basic type of LME is the two-dimensional matrix. There exist four variants:

Complex matrices are stored using twice as much memory as real matrices; but real, logical, and string matrices differ only by the value of a flag. Internally, each character of strings is represented by its ASCII representation stored as a floating-point number. Boolean values are also stored as floating-point numbers; 0 means false, and any other value (including "not a number", or nan, which indicates an invalid result and is returned for operations such as 0/0 or inf-inf) true. Operators and functions which return a boolean always represent true with 1. These internal representations are revealed by the conversion functions double, logical, and char. Many functions can be used on any kind of matrices. Mathematic functions accept logical and string arguments, but always convert the result to a real or complex number or matrix.

These basic types can be used to represent many mathematic objects:

Scalar
One-by-one matrix.
Vector
n-by-one or one-by-n matrix. Functions which return vectors usually give a column vector, i.e. n-by-one.
Empty object
0-by-0 matrix (0-by-n or n-by-0 matrices are always converted to 0-by-0 matrices).
Polynomial of degree d
1-by-(d+1) vector containing the coefficients of the polynomial of degree d, highest power first.
List of n polynomials of same degree d
n-by-(d+1) matrix containing the coefficients of the polynomials, highest power at left.
List of n roots
n-by-1 matrix.
List of n roots for m polynomials of same degree n
n-by-m matrix.
Single index
One-by-one matrix.
List of indices
Any kind of matrix; the real part of each element taken row by row is used.
Boolean value
One-by-one matrix; 0 means false, and any other value (including nan) means true (comparison and logical operators and functions return logical values). In programs and expressions, constant boolean values are entered as false and true. Scalar boolean values are displayed as false or true; in arrays, respectively as F or T.
String
Usually 1-by-n string matrix, but n-by-m matrices are also accepted by many functions.

Numbers

Numbers are stored as floating-point numbers, whose finite accuracy depends on the number magnitude. During computations, round-off errors may accumulate and lead to visible artifacts; for example, 2-sqrt(2)*sqrt(2), which is mathematically 0, yields -4.4409e-16. Integers whose absolute value is smaller than 2^52 (about 4.5e15) have an exact representation, though.

Literal numbers (constant numbers given by their numerical value) have an optional sign, an integer part, an optional fractional part following a dot, and an optional exponent. The exponent is the power of ten which multiplies the number; it is made of the letter 'e' or 'E' followed by an optional sign and an integer number. Numbers too large to be represented by the floating-point format are changed to plus or minus infinity; too small numbers are changed to 0. Here are some examples (numbers on the same line are equivalent):

123 +123 123. 123.00 12300e-2 
-2.5 -25e-1 -0.25e1 -0.25e+1
0 0.0 -0 1e-99999
inf 1e999999
-inf -1e999999

Literal integer numbers may also be expressed in hexadecimal with prefix 0x, in octal with prefix 0, or in binary with prefix 0b. The four literals below all represent 11:

0xb
013
0b1011
11

Command format is used to specify how numbers are displayed.

Strings

Literal strings are enclosed in single quotes:

'Example of string'
''

The second string is empty. For special characters, the following escape sequences are recognized:

CharacterEscape seq.ASCII value
Null\00
Bell\a7
Backspace\b8
Horizontal tab\t9
Line feed\n10
Vertical tab\v11
Form feed\f12
Carriage return\r13
Single tick\'39
Backslash\\92
Hexadecimal number\xhhhh
Octal number\oooooo

For octal and hexadecimal representations, up to 3 (octal) or 2 (hexadecimal) digits are decoded; the first non-octal or non-hexadecimal digit marks the end of the sequence. The null character can conveniently be encoded with its octal representation, \0. When an unknown character is found after the backslash, the backslash is ignored.

Lists

With structures, inline functions, and function references (see below), lists are one of the (native) non-matrix types. Lists are ordered sets of other elements. They may be made of any type, including lists. Literal lists are enclosed in braces; elements are separated with commas, like for row vectors.

{1,[3,6;2,9],'abc',{1,'xx'}}

Lists may be empty:

{}

List's purpose is to collect any kind of data which can be assigned to variables or passed as arguments to functions. They may also replace matrices when elements are neither numbers nor characters.

Structures

Like lists, structures are sets of data of any type. While list elements are ordered but unnamed, structure elements, called fields, have a name which is used to access them. There are two ways to make structures: with the struct function, or by setting each field in an assignment.

a = struct('name', 'SysQuake', 'os', {'Mac OS', 'Windows'});

b.x = 200;
b.y = 280;
b.radius = 90;

Inline functions

Inline functions encapsulate executable code. They are created with function inline; their main use is as argument to other functions.

Function references

Function references are equivalent to the name of a function together with the context in which they are created. They have the same use as inline functions, but do not contain executable code. They are obtained with operator @.

Objects

Objects are the basis of Object-Oriented Programming (OOP), an approach of programming which puts the emphasis on encapsulated data with a known programmatic interface (the objects). Two OOP languages in common use today are C++ and Java.

The exact definition of OOP varies from person to person. Here is what it means when it relates to LME:

Data encapsulation
Objects contain data, but the data cannot be accessed directly from the outside. All accesses are performed via special functions, called methods. What links a particular method to a particular object is a class. Class are identified with a name. When an object is created, its class name is specified. The names of methods able to act on objects of a particular class are prefixed with the class name followed with two colons. Objects are special structures whose content is accessible only to its methods.
Function and operator overloading
Methods may have the same name as regular functions. When LME has to call a function, it first check the type of the input arguments. If one of them is an object, the corresponding method is called, rather than the function defined for non-object arguments. A method which has the same name as a function or another method is said to overload it. User functions as well as built-in ones can be overloaded. Operators, which also have a function name (for instance x+y can also be written plus(x,y)), can also be overloaded. Special functions, which are also methods while their input arguments are not necessarily objects, have the same name as the class and create new objects; they are the object constructors.
Inheritance
A class (subclass) may extend the data and methods of another class (base class or parent). It is said to inherit from the parent. In LME, objects from a subclass contain in a special field an object of the parent class; the field name has the same name as the parent class. If LME does not find a method for an object, it tries to find one for its parent, great-parent, etc. if any. An object may also inherit from several parents.

Here is an example of the use of polynom objects, which (as can be guessed from their name) contain polynomials.

p = polynom([1,5,0,1])
  p =
    x^3+5x^2+1
q = p^2 + 3 * p / polynom([1,0])
  q =
    x^6+10x^5+25x^4+2x^3+13x^2+15x+1

Error Messages

When an error occurs, the execution is interrupted and an error message explaining what happened is displayed, unless the code is enclosed in a try/catch block. The whole error message may look like

> factor({2})

Wrong type (stdlib:primes:164) 'ones'
-> stdlib:factor:174

The first line contains an error message, the location in the source code where the error occurred, and the name of the function or operator involved. Here stdlib is the library name, primes is the function name, and 164 is the line number in the file which contains the library. If the function where the error occurs is called itself by another function, the whole chain of calls is displayed; here, primes was called by factor at line 174 in library stdlib.

Here is the list of errors which can occur. For some of them, LME attempts to solve the problem itself, e.g. by allocating more memory for the task.

Stack overflow
Too complex expression, or too many nested function calls.
Data stack overflow
Too large objects on the stack (in expressions or in nested function calls).
Variable overflow
Not enough space to store the content of a variable.
Code overflow
Not enough memory for compiling the program.
Algorithm does not converge
A numerical algorithm does not converge to a solution, or does not converge quickly enough. This usually means that the input arguments have invalid values or are ill-conditioned.
Incompatible size
Size of the arguments of an operator or a function do not agree together.
Bad size
Size of the arguments of a function are invalid.
Index out of range
Index negative or larger than the size of the matrix.
Wrong type
String or complex matrix instead of real, etc.
Bad argument
A numerical argument has the wrong site or the wrong value.
Unknown option
A string option has an invalid value.
Undefined variable
Attempt to retrieve the content of a variable which has not been defined.
Undefined function
Attempt to call a function not defined.
Too few or too many input arguments
Less or more arguments in the call than what the function accepts.
Too few or too many output arguments
Less or more left-side variables in an assignment than the function can return.
Syntax error
Unspecified compile-time error.
"function" keyword without function name
Incomplete function header.
Bad function header
Syntax error in a function header
Missing expression
Statement such as if or while without expression.
Unexpected expression
Statement such as end or else followed by an expression.
Incomplete expression
Additional elements were expected during the compilation of an expression, such as right parenthesis or a sub-expression at the right of an operator.
"for" not followed by a single assignment
for is followed by an expression or an assignment with multiple variables.
Bad variable name
The left-hand part of an assignment is not a valid variable name (e.g. 2=3)
String without right quote
The left quote of a string was found, but the right quote is missing.
Unexpected right parenthesis
Right parenthesis which does not match a left parenthesis.
Unexpected right bracket
Right bracket which does not match a left bracket.
Unrecognized or unexpected token
An unexpected character was found during compilation (such as (1+))
"end" not in an index expression
The end was used outside of any index sub-expression in an expression.
Compilation overflow
Not enough memory during compilation.
Too many nested subexpressions
The number of nested of subexpressions is too high.
Variable table overflow
A single statement attempts to define too many new variables at once.
Expression too large
Not enough memory to compile a large expression.
Too many nested (), [] and {}
The maximum depth of nested subexpressions, function argument lists, arrays and lists is reached.
Too many nested programming structures
Not enough memory to compile that many nested programming structures such as if, while, switch, etc.
Wrong number of input arguments
Too few or too many input arguments for a built-in function during compilation.
Wrong number of output arguments
Too few or too many output arguments for a built-in function during compilation.
Too many indices
More than two indices for a variable.
Variable not found
A variable is referenced, but appears neither in the arguments of the function nor in the left part of an assignment.
Unbounded language construct
if, while, for, switch, or try without end.
Unexpected "end"
The end statement does not match an if, switch, while, for, or catch block.
"case" or "otherwise" without "switch"
The case or otherwise statement is not inside a switch block.
"catch" without "try"
The catch statement does not match a try block.
"break" or "continue" not in a loop
The break or continue statement is not inside a while or for block.
Variable name reused
Same variable used twice as input or as output argument.
Too many user functions
Not enough memory for that many user functions.
Attempt to redefine a function
A function with the same name already exists.
Can't find function definition
Cannot find a function definition during compilation.
Unexpected end of expression
Missing right parenthesis or square bracket.
Unexpected statement
Expression expected, but a statement is found (e.g. if).
Name too long
More than 32 characters in a variable or function name.
Unexpected function header
A function header (keyword "function") has been found in an invalid place, for example in the argument of eval.
Function header expected
A function header was expected but not found.
File not found
fopen does not find the file specified.
Bad file ID
I/O function with a file descriptor which neither is standard nor corresponds to an open file.
Cannot write to file
Attempt to write to a read-only file.
Bad seek
Seek out of range or attempted on a stream file.
Too many open files
Attempt to open too many files.
End of file
Attempt to read data past the end of a file.
Timeout
Input or output did not succeed before a too large amount of time elapsed.
Bad context
Call of a function when it should not (application-dependent).
Not supported
The feature is not supported, at least in the current version.

Copyright 1998-2001, Calerga.

All rights reserved.