#define LM_ALL #include "lightmat.h"at the start of your code and add some object files when linking the application.
Some options are not implemented yet, but they will be available in
the next versions.
Compilers | Preprocessor definitions set the compiler and used in code |
WorkShop Compilers 4.2 C++ 4.2 (Sun / Solaris 5.6) | __SUNPRO_CC |
SC4.0 / C++ 4.1 (Sun / Solaris 5.5.1) | __SUNPRO_CC |
GNU C++ V.2.6.3(Sun / Solaris 5.5.1, 5.6) | __GNUG__ |
GNU C++ 2.7.2.1 (Sun / Solaris 5.5.1, 5.6, Linux 2.0.30) | __GNUG__ |
GNU C++ 2.7.2 (Digital UNIX V3.2) | __GNUG__ |
DEC C++ V1.3B-0 DEC OSF/1 (Alpha) | __alpha |
MicroSoft Visual C++ 4.0 | _WIN32 |
MicroSoft Visual C++ 5.0 | _WIN32 |
#define LM_ALL #include <lightmat.h> doubleNNN f(5,6,7,3.11); cout << f;Compile with (assuming that LightMat is installed in /home/john/lightmat099)
g++ foo.cc -I/home/john/lightmat099/include \ /home/john/lightmat099/obj/cstring.o \ /home/john/lightmat099/obj/extwin.o
#define LM_ALL #include <lightmat.h> doubleNNN f(5,6,7,3.11); cout << f;Compile with
g++ foo.cc -I/home/john/lightmat099/include -DNOT_INLINED \ /home/john/lightmat099/obj/cstring.o \ /home/john/lightmat099/obj/extwin.o \ /home/john/lightmat099/obj/not_inlined.o
#define LM_N #include <lightmat.h> doubleN xx(5,2.0); // doubleNN yy(5,6); - Forbidden // This is not allowed because this class requires LM_NN. // Compiler reports an error.Compile with
g++ foo1.cc -I/home/john/lightmat099/include -DNOT_INLINED \ /home/john/lightmat099/obj/cstring.o \ /home/john/lightmat099/obj/extwin.o \ /home/john/lightmat099/obj/not_inlined.o
|
|
|
Meaning if undefined |
LIGHTMAT_LIMITS_CHECKING | defined | LightMat does limits checking during calculations. I.e. LightMat will abort computations and dump core if an index is out of bounds. Computation speed is reduced by these checks. | An operation with bad index can cause unpredictable results. |
LIGHTMAT_INIT_ZERO | undefined | LightMat will initialize all array elements to zero when constructing
a new object. Computation speed is reduced.
|
Array elements initially may contain any value. Care should be taken if non-initialized values are used in some other interfaces, like MathLink. |
LIGHTMAT_DONT_USE_BLAS | defined | LightMat uses its own function for double array multiplication | LightMat calls BLAS libraryroutines. The library
should be linked with the application.
(N/A) |
LIGHTMAT_OUTPUT_FUNCS | defined | The ToStr (conversion to Tools.h++ class RWCString) functions are defined and operator<< functions are defined for all arrays. | (N/A) |
LIGHTMAT_TEMPLATE | undefined | LightMat classes can be used as templates. This option is not available due to difficulties with various compilers.(N/A) | LightMat classes are used as traditional C++ classes. |
Dimension
suffix |
Preprocessor
symbol for inclusion |
Use | Default stack allocation size | Class names (long form ) | Class names
(short form) |
Explanations |
3 | LM_3 | special | 3 | light3double
light3int |
double3
int3 |
Vector of 3 elements |
4 | LM_4 | special | 4 | light4double light4int |
double4 int4 |
Vector of 4 elements |
N | LM_N | universal | 10 | lightNdouble lightNint |
doubleN intN |
Vector of arbitrary size |
33 | LM_33 | special | 3 x 3 | light33double light33int |
double33 int33 |
Matrix 3 by 3 elements |
44 | LM_44 | special | 4 x 4 | light44double light44int |
double44 int44 |
Matrix 4 by 4 elements |
N3 | LM_N3 | special | 10x 3 | lightN3double lightN3int |
doubleN3 intN3 |
Matrix N by 3 elements, i.e. storage for N vectors if 3 elements |
NN | LM_NN | universal | 10 x 10 | lightNNdouble lightNNint |
doubleNN intNN |
Matrix of arbitrary size |
N33 | LM_N33 | special | 10 x 3 x 3 | lightN33double lightN33int |
doubleN33 intN33 |
Tensor N by 3 by 3, i.e. storage for N matrixes of 3 by 3 elements |
NNN | LM_NNN | universal | 5 x 5 x 5 | lightNNNdouble lightNNNint |
doubleNNN intNNN |
Tensor of arbitrary size |
NNNN | LM_NNNN | universal | 4 x 4 x 4 x 4 | lightNNNNdouble lightNNNNint |
doubleNNNN intNNNN |
Quansor of arbitrary size |
Note on higher ranks: There are no classes for tensors
of higher ranks larger than 4. It is possible to add support for that in
the future though. Having different classes for vectors, matrices etc is
quite natural, and that's what most other packages also have chosen. Other
packages sometimes have one class for tensors of high ranks, but that does
not exist in LightMat. Having different classes for the different ranks
also avoids run-time choices of what algorithm, for the different ranks,
that should be used.
The classes for elements of type int and double
are implemented.
These classes, though, can also interface with the other
existing classes in lightmat.
There are also classes for matrices and tensors with partially
fixed sizes (intN3, doubleN3 and intN33, doubleN33). The
usefulness of these classes will be described in
Indexing. One is for matrices with three columns and the other one
is for tensors of rank 3 which have the size of the two last indices set
to three. Internally the matrix-class consist of a number of vectors of
length 3 (int3, double3) and the tensor-class consist of a number
of 3x3 matrices (int33, double33).
Since the sizes of objects of these classes are partially or totally
fixed they cannot dynamically change their sizes as freely as the the universal
LightMat classes. Only classes with suffixes N3 andN33
can change the first dimension during calculations.
Class names
The user specifies a variable
double4 foo
This means that foo is a vector with 4 elements of
type double.
There are typedef definitions that allow using another, longer notation
for class names, for instance light4double instead of double4.
The examples below are given in the short form.
All available names are given in the table.
The properties for classes with elements of type int
and double are very similar.
Further, for instance, by classes with siffix 3 usually
meant both classes int3 and double3.
Specially optimized classes for certain sizes
Extra fast classes (suffixes 3, 4, 33, 44) have been made for some specific sizes of vectors and
matrices. Those are vectors of length 3 and 4, and matrices of size 3x3
and 4x4. They have, of course, a static memory-area for the elements.
That means that the the compiler can make code which need a less number
of references through pointers. Code for calculations is written especially
suited to those sizes. Calculation loops are completely unrolled. This
makes these classes extra fast.
Constructors and access to arrays
All LightMat classes have some basic member functions like constructors,
destructors, assignment
operators and a few more.
Constructors
There exist a number of constructors, with different arguments, with
which a new object can be created. The reasons for having a number of different
constructors are efficiency and ease of use.
intNN a; doubleNN b;
doubleNN b = a; intNNN c = d;
doubleNN a(3,5); intNNNN c(3,5,2,4); intN3 d(6)
double33 a;
doubleNN c = a;
Such constructors are also called converters. There are converters for
int3 intN int4 intN int33 intNN intN3 intNN int44 intNN intN33 intNNN double3 doubleN double4 doubleN double33 doubleNN doubleN3 doubleNN double44 doubleNN doubleN33 doubleNNN
double arr[] = { 1.3, 2.6, 3, 4, 5.7, 6 };
doubleNN a(2,3,arr);
The same result can be achieved by writing a loop:
doubleNN a(2,3);
idx=0;
for(int i=1;i<=2;i++)
for(int j=1;j<=3;j++)
a(i,j)=arr[idx++];
doubleNN a(3,4,17.7);
double33 a(1.1,2,3.5,4,5,6.9,7,8.3,9);
Element initialization
If values for the elements are not supplied in the constructor, the behaviour
depends on preprocessor definition LIGHTMAT_INIT_ZERO.
(See preprocessor definition table)If
it is defined, the elements initialized to zero.
Otherwise, the elements are not initialized. This saves some time.
It can be a good idea to not define LIGHTMAT_INIT_ZERO
if the user knows that objects never are used without explicit initialization.
Functions within the classes that do calculations and need a local object
use a special internal protected constructor that never initializes the
elements.
doubleNN a(2,3), b(3,2); a = b; // a becomes 3x2 a = 5.7; // all elements of a become 5.7Assignment from a scalar will set all the elements in the object to that value.
doubleNN a(5,6,17.7), b(5,6); double arr[30]; a.Get(arr); // a --> arr b.Set(arr); // arr --> b
No bounds check is performed.
dimension()
The size of an object can be found with the function dimension().
It takes an integer argument which should specify the dimension. The argument
should, for example, be 1 for the number of rows in a matrix, and 2 for
the number of columns.
Equality and inequality
The usual operators for equality and inequality exist for all classes.
Two objects are considered equal if they have the same size and if the
values of all corresponding elements are equal. Only arrays of the
same rank can be compared.
if(a == b ?? c != d) { /* something */ }
Promoting to higher dimensions
A function named reshape is used to promote an object to another object
with higher dimensions. E.g. a vector can be promoted to a matrix and all
the columns in the matrix will then be given the values of the vector.
doubleN v(3);
doubleNN a;
a.reshape(3,5,v); // a becomes 3x5
Constructing arrays in a function call
Function make_lightN()
is not a method of a class, but a friend function. You can use it for
construction of an array from its components. Given several arrays of rank
n it constructs an array of rank n+1. Number of components should be specified
as the 1st argument. Obviously, the dimensions and element types of all
arrays should be the same.
Not more than 10 parameters can be given in the argument list.
lightNN a;
a=make_lightN(2, make_lightN( 3, 11,12,13),
make_lightN( 3, 14,15,16));
This code creates array 2x3 of integers from 11 to 16. Specification
is always given in row-major order.
Note: This function is very time and space consuming. Therefore use
Set() if you are interested in higher performance.
Indexing
The indexes in LightMat are 1-based, like in Fortran, not 0-based like
in C.
For matrices the first coordinate is usually named "row", the second
- "column".
Bound check in indexing operations can be turned on or off by preprocessor
definitions.
There is indexing for individual
elements , indexing for array
extraction, and special access functions.
doubleNN a(5,3); a(1,1) = a(2,3);
doubleN v; doubleNN a(5,5); doubleNNN c(7,8,9); v = a(4); v=c(4,5); a= c(3); a(1) = v; // The result is discarded, and matrix a does not change. a.SetRow(1,v) ;// This is the correct way. See "access functions" below. double3 w; doubleN3 m(5); m(3) = w + m(2); // This class is exception, m changes.
doubleN s(5,30.0); // Length is 5, all elements initialized to 30 doubleN p(2,40.0); // Length is 2, elements are initialized to 40 s.SetSubVector(3,4,p); // s becomes {30,30,40,40,30} p=s.SubVector(2,4); // p changes length and becomes {30,40,40}
doubleNN a; // Allocates 10x10, has shape 0x0 doubleNN b(5,6); // Allocates 10x10, has shape 5x6 a.SetShape(20,40); // Allocates 20x40, has shape 20x40 b(70,30)=1; // Causes error b.SetShape(70,30); // Allocates 70x30, has shape 70x43 b(70,30)=1; // OK
doubleNN a; cout << a;May produce:
( 5.0 7.0 2.6 7.2 )
Operators available for all classes are:
Note: (Version 0.76) FractionalPart, IntegerPart,
Mod, LightMax, LightMin - implemented for universal types only
Unary operators:
Elementwise binary operators.
One of arguments can be scalar. If both are arrays they must be of the
same size.
Inner product and multiplication with scalar.
x*y
All the possible variants are given in the table (s is a scalar; other symbols
are suffixes of class names) :
Arg 1
Arg 2
Result
s
s
s
3
s
3
s
3
3
3
3
s
33
3
3
3
33
3
3
NN
N
4
s
4
s
4
4
4
4
s
4
44
4
44
4
4
4
NN
N
s
N
N
N
s
N
N
N
s
NN
N
N
Arg 1
Arg 2
Result
NN
3
N
NN
4
N
N3
3
N
N3
N
N
N3
N3
N3
N3
s
N3
s
N3
N3
N3
33
N3
44
N3
N3
NN
N3
N3
NN
s
NN
s
NN
NN
NN
NN
NN
NN
33
NN
NN
44
NN
N3
NN
NN
33
NN
NN
Arg 1
Arg 2
Result
44
NN
NN
N
NNN
NN
NNN
N
NN
3
NNN
NN
NNN
3
NN
4
NNN
NN
NNN
4
NN
33
s
33
s
33
33
33
33
33
44
s
44
s
44
44
44
44
44
NNN
s
NNN
s
NNN
NNN
NN
NNN
NNN
NNN
NN
NNN
Arg1
Arg2
Result
NNNN
N
NNN
N
NNNN
NNN
NNN
33
NNN
33
NNN
NNN
NNNN
3
NNN
3
NNNN
NNN
NNN
44
NNN
44
NNN
NNN
NNNN
4
NNN
4
NNN N
NNN
s
NNNN
NNNN
NNNN
s
NNNN
NNNN
NN
NNNN
NN
NNNN
NNNN
NNNN
33
NNNN
33
NNNN
NNNN
NNNN
44
NNNN
44
NNNN
NNNN
NNN
NNN
NNNN
Operation with assignment.
If y is array, it must have the same dimensions as x. Result
has the same dimension as array x.
Division.
Result has the same dimension as array.
Division and multiplication as operations performed only element-wise.
The x and y are arrays. Result has the same dimension.
Other operations with arrays
Example:
double add(double x)
{ return x+1; }
double3 a(1.5,1.6,1.7);
double3 b=Apply(a,add);
cout << b; // prints 2.5, 2.6, 2.7
Example:
int sum(int x1, int x2)
{ return x1+x2;}
int4 s(5,6,7,8);
int4 t(10,11,12,13);
int4 u=Apply(s,t,sum); // 15, 17, 19, 21
Mathematical functions, applied element-wise:
Vadim Engelson
Last modified: Tue Feb 24 11:52:28 MET 1998