
                           ****** ASSIST ******


   A file of additional functions to REDUCE which raise the programming
     power of the user in a broad range of applications.


Author : H. Caprasse .     Date : 15/09/1991
------                     ----

Address : Physics Institute, B5 , Sart-Tilman, B4000 Liege, Belgium.
--------

Electronic Mail : <u21400L@bliulg11.bitnet> or <u214001@vm1.ulg.ac.be>
---------------

ASSIST arose from the use of REDUCE in many different applications.  It
contains functions which are often needed.  Many of them give
assistance to the user allowing him to produce a more straightforward
and a more efficient code for its own applications. Others give him
more control on the environment. Some of them allows him to introduce
PROPERTIES and FLAGS within the algebraic mode.

                  ___________________________________
                           _________________


                        NEW FUNCTIONS AVAILABLE
                        -----------------------


Control of SWITCHES :
--------------------

SWITCHES SWITCHORG


Operations on "lists" AND "bags" :
-------------------------------

MKLIST DELETE BAGPROP
PUTBAG CLEARBAG BAGP BAGLISTP ALISTP ABAGLISTP LISTBAG
FIRST SECOND THIRD REST REVERSE LAST BELAST APPEND CONS
LENGTH REMOVE DELETE MEMBER ELMULT PAIR DEPTH INSERT POSITION
ASFLIST ASSLIST RESTASLIST SUBSTITUTE REPFIRST REPLAST


Operations on SETS :
------------------

MKSET UNION SETP SETDIFF SYMDIFF


General purpose functions :
-------------------------

MKIDN == INF2 SUP2 ODDP EVENP FOLLOWLINE DETIDNUM
RANDOMLIST COMBNUM PERMUTATION COMBINATIONS FUNCVAR
IMPLICIT DEPATOM EXPLICIT SIMPLIFY


"Properties" and "flags":
-----------------------

PUTFLAG PUTPROP DISPLAYPROP DISPLAYFLAG CLEARFLAG CLEARPROP

Control statement and control of the environment :

NORDP DEPVARP ALATOMP ALKERNP PRECP
KORDERLIST REMSYM SHOW SUPPRESS CLEAROP CLEARFUNCTIONS

Handling of polynomials :
-----------------------

DISTRIBUTE LEADTERM REDEXPR MONOM LOWESTDEG DIVPOL


Handling of TRIGONOMETRIC functions :
-----------------------------------

TRIGEXPAND HYPEXPAND TRIGREDUCE HYPREDUCE


Handling of log's :
-----------------

PLUSLOG CONCSUMLOG

Handling of n-vectors :

SUMVECT MINVECT SCALVECT CROSSVECT MPVECT

Handling of matrices :
MKIDM BAGLMAT COERCEMAT UNITMAT SUBMAT MATSUBR MATSUBC
RMATEXTR RMATEXTC HCONCMAT VCONCMAT TPMAT HERMAT SETELTMAT GETELTMAT

                        __________________
                             =====
We describe successively these different facilities.

CONTROL OF SWITCHES
--------------------

Not all switches are included. The ones we have chosen are
EXP, DIV, MCD, LCM, EZGCD, GCD, ALLFAC, INTSTR, RAT , RATIONAL, FACTOR,
PRECISE, REDUCED, COMPLEX, RATIONALIZE and the new switch DISTRIBUTE.
The selection covers all switches which are essential for ALGEBRAIC
calculations fashion by the user.  The control symbolic variables
!*EXP, !*DIV, etc... which have either the value T or the value NIL are
available on the level of the algebraic mode so it  becomes
possible to write conditional statements of the kind

                  IF !*EXP THEN DO ......

                  IF !*GCD THEN OFF GCD;

Two functions SWITCHES; and SWITCHORG; are provided:

SWITCHES; gives the ACTUAL STATUS of ALL (selected) switches,
SWITCHORG; puts them in the status they have when ENTERING
                                           the system (ORiGinal status).
The new switch DISTRIBUTE controls the working of some polynomial func-
tions which are described below. It allows to put polynomial in a distri-
buted form.

MANIPULATION OF THE "LIST" STRUCTURE
____________________________________

Some additional functions for list manipulations are provided.

i) automatic generation of a LIST :

                      MKLIST n ;    n is an INTEGER

   returns a list of length n with 0 elements.

                      MKLIST(U,n);    U is LIST-like, n is an INTEGER

   returns U if n is LESS than the length of U; otherwise returns a list
   of length n with the first length U elements equal to the elements of
   U. and with the n-length U elements equal to 0.

ii) direct manipulation of a LIST (apart from FIRST,REST,REVERSE):

            ***    U is a LIST-like quantity.

                      LAST U ; BELAST U ; DEPTH U ;

   LAST gives the last element of U
   BELAST gives the list U without the last element,
   DEPTH returns an INTEGER equal to the number of levels where a
   list is found if and only if this number is the SAME for each element
   of U otherwise a message telling the user that U is of UNEQUAL depth
   is returned.

                      POSITION(x,U);    x is anything.

   returns the POSITION of the first occurrence of x in U or a message
   if x is not present in U.

                      DELETE(x,U);    x is anything.

   DELETE returns U after the FIRST occurrence of x in U has been deleted.

                      REMOVE(U,n);    n is an INTEGER.

   REMOVE returns a list which is U without the nth. element.

   If one wants to EXTRACT the nth. element of U instead of using PART
   one may write

                      U.n;

                      MEMBER(x,U);    x is anything.

   MEMBER returns a non-empty list if x belongs to U and nothing if it this
      is not the case. It is a BOOLEAN function so one may write

                      IF MEMBER(x,U) then ......

                      ELMULT(x,U);     x is anything.

   ELMULT return an INTEGER which is the MULTIPLICITY of x inside U.

                     REPFIRST(x,U); REPREST(x,U);   x is anything.

   REPFIRST replaces the first element of U by x and returns the new list.

   REPREST replaces the rest of U by x and returns the list
                                    list(first U,x).

                     INSERT(x,U,n); x is anything, n is an integer.

   INSERTs x in U at the position n and returns the resulting list.

                     SUBSTITUTE(new,old,U);

   where "new" is the OBJECT to substitute to the object "old" in U at
   ALL levels. This function is more elementary than the functions "SUB".
   It is more efficient but works properly only for atomic "new" and old
   objects.

iii) manipulations of two lists:

                 ***  U and V are LIST-like.

                      APPEND(U,V); U.V;

   APPEND returns a list which is the union of the two lists U and V.

   "." (dot) returns a list whose first element is the list U and the other
         elements are the elements of V.

                     PAIR(U,V);

   PAIR returns a list whose elements are LISTS of TWO ELEMENTS. The
   nth sublist contains the nth element of U and the nth. element of V.
   These types of lists are called ASSOCIATION LISTS or ALISTS in the fol-
   lowing. To test for these type of lists a BOOLEAN function is available

            ABAGLISTP U;

   Can ONLY be used in a conditional statement like

            IF ABAGLISTP U THEN .....

   ( this "bizarre" name because it also works for BAGS; see below).

iv) functions which apply to ALISTS:

                   *** x is anything, U is an ALIST.

                    ASFIRST(x,U);

    returns the sublist of U whose FIRST element is x.

                    ASSECOND(x,U);

    returns the sublist of U whose SECOND element is x.

                    ASLAST(x,U);

    returns the sublist of U whose LAST element is x.

                    ASREST(V,U);   here V is a LIST.

    returns the sublist of U whose REST is V.

In addition to these different functions always gives as output the
FIRST occurrence of the appropriate element. There are functions which
either return a LIST of elements of U. We describe them now. U is still
 an ALIST.

                    ASFLIST(x,U);

    returns ALL the listb-elements of U whose
    first element are the KEY x. So the returned object is a list of lists.

                    ASSLIST(x,U);

     acts in the same way as the previous one except that the KEY x is
     the second element of the list-elements of U.

                    RESTASLIST(V,U);   V is a LIST of KEYS.

     returns  a list of the RESTs of the sublists of U associated to each KEY
     present in V.


THE "BAG" TYPE AND ITS ASSOCIATED FUNCTIONS
___________________________________________

In REDUCE 3.4, the LIST structure has a mapping property associated
to it and, consistently, cannot be a coefficient in a polynomial.
Sometimes, also, one would like to manipulate functions
or operators arguments in the same way one manipulates the
elements of a list. The BAG structure allows to do such things.

The definition: It is a "FLAG" which can be superimposed to the properties
                of most KERNELS. They keep their own properties but
                to these are superimposed properties which make them VERY
                SIMILAR to lists.  When the prefix of a kernel gets
                the flag "BAG" all functions defined for lists (or for sets)
                become ACTIVE.
                A detailed description of this structure is given in the
                article by H. Caprasse and M. Hans in
                SIGSAM Bulletin, Vol. 19, 46-52 (1985).
                Here we try to make the use of this notion clear from the des-
                cription of the action of the various functions available.

                        PUTBAG id1,id2,....idn;

    where id1,.....idn are identifiers.
    This functions allows one to give to id1,...,idn the BAG properties.
    id1,.. ,idn  are only restricted NOT to be

          - the name LIST,
          - the name of a BOOLEAN function.

     id1,....,idn may be the

          - the name of an OPERATOR prefix,
          - the name of an ordinary function.

     WHEN AND ONLY WHEN the identifier is not an already defined function
     does PUTBAG puts on it the property of an OPERATOR PREFIX.

                        CLEARBAG id1,...idn;

     eliminates the BAG property on id1,...,idn.


When an identifier has got the bag property ALL FUNCTIONS previously defined
for LISTS (and also subsequently defined for SETS) become ACTIVE.  Their
actions are the same as for list-like objects except for the following
important difference:

      The NAME of the IDENTIFIER is KEPT by the functions

                             FIRST and LAST.

When "appending" two bags the resulting bag gets the name of the FIRST
argument bag.
So a bag-like identifier can always be considered as an "envelope" suited
to contain any objects. These ojects are the arguments of the bag.
The possibility to manipulate the arguments as if the bag were a LIST
increases the programming capabilities and efficiency in the ALGEBRAIC MODE.
The TEST FILE gives several illustrations of the actions of the various
functions on bags.  Here we stress two cases where it is particularly
convenient:
An operator function is defined as

                       OP(x):=x**2;
                       OP(x,y):=x*sin(y);


The command           PUTBAG OP;

will allow us to encompass the different definitions trivially.

For example

                    AA:=FIRST OP(X,Y,Z); ==> AA:=OP(X)

and                 AA:=AA; ==>              AA:=X**2

                    AA:=REST OP(X,X,Y); ==> AA:=OP(X,Y)

and                 AA:=AA; ==>              AA:=X*SIN Y

One can wonder why we did not manage to do the two steps together. This
is so because in most applications we encountered the evaluation is not
to be done IMMEDIATELY. Moreover we want to keep the basic functions
very efficient since they are usually applied repeatedly a great number
of times. Last but not least, it is not difficult, if necessary, to con-
struct a procedure which does so.

The second case is when one wants to construct a PROCEDURE with an (a
priori) INDETERMINATE number of variables.  Then the use of a prefix with
the "BAG" flag to capture all variables will allow to do so easily.  The
package provides a "standard" name for it which is

                                BAG

but ANY OTHER NAME can be used after it has been declared a "bag" through

                                PUTBAG.

For instance one may write

                     PROCEDURE TRIAL U ;
                     FOR I:=1:SIZE U DO WRITE PART(U,i);

When U is BAG(v1,v2,....,vn), SIZE U automatically determines the ACTUAL
number of variables (SIZE is another name for LENGTH which is more
appropriate when applied to a bag-like object).
This possibility is also available if U is a list when one delivers the
command

                      LISTARGP TRIAL;

But this command forbids the associated mapping property of U.
So, it is very convenient to be able to use as U either a list-like or
bag-like object using a code which manages to handle both structures.
Of course several arguments are allowed one or several of them can be
"bags".  The example above could be treated also with U being LIST-LIKE.
It is important to remember that

               - a bag can be treated as  an ordinary KERNEL so that all
                 ALGEBRAIC operations and simplifications do apply to it.
               - if the prefix is the one of an already defined function
                 it keeps these properties or can also be given other
                 properties (one may declare BAG to be a SYMMETRIC function
                 for instance).


ADDITIONAL FUNCTIONS
--------------------

There are several simple functions devoted to the bag manipulations .

                          BAGP x ; BAGLISTP x ;   x is anything.

They are boolean functions.  As such they can only be used in conditional
statements.

BAGP detects if x is a bag or not .
BAGLISTP detects if x is a list or a bag.

Coercing functions are

                          KERNLIST U ;  U is a bag.

KERNLIST transforms a KERNEL into a LIST. This is convenient when the name
of the prefix does not matter or if one wants to HIDE temporarily
its properties.

                          LISTBAG(U,nb); U is a list, nb is an identifier.

LISTBAG transforms a LIST into a BAG whose envelope has the NAME nb.

                          SIZE U ;   U is a bag (or a list).

As said above it is another name for length givem to indicate that it gives
the total number of objects INSIDE the envelope.

REMARK: The functions KERNLIST and LISTBAG allow easily to mix list-like and
------  bag-like objects in a given expression. All functions do recognize
        the differences except that functions which work on association-list
        or -bag cannot work on MIXED objects. This restriction can be elimina-
        ted but we have had no motivation to do so.


SETS AND BASIC MANIPULATION FUNCTIONS
-------------------------------------

These functions apply BOTH to list-like and bag-like objects.

                         MKSET U ; SETP U ; U is a bag or list.

MKSET  returns a bag or list with each element appearing only ONCE.
SETP is a boolean function which recognizes set-like objects.

            UNION(U,V); INTERSECT(U,V); DIFFSET(U,V); SYMDIFF(U,V);

U and V are set-like.

All these functions return a SET.  The names are self-explanatory.


GENERAL PURPOSE FUNCTIONS
-------------------------

The list of these functions were already given. They depend either of
one or two arguments. We describe some of them only.
COMBNUM gives the number of combinations of P objects taken among
N objects.


                     PERMUTATIONS U ;  U is a bag

returns a bag of bags each containing one permutation of the original bag.

                     COMBINATIONS (U,n) ; U is a bag , n is an integer.

returns a bag of bags each containing one combination of the original bag

                      FUNCVAR x ; x is any expression .

returns the *set* identifiers which are NOT prefix identifiers. The set
does NOT contain reserved or constant identifiers.

                      DEPATOM x ; x is an ATOMIC expression.

returns a list of identifiers if x has previously been declared to DEPEND on
these otherwise returns an empty list.

                      EXPLICIT x ; IMPLICIT x ;

These two functions allow one to change smoothly the representation of
OPERATORS and FUNCTIONS going from an EXPLICIT to an IMPLICIT
representations of these objects.  By EXPLICIT representation we mean one
in which VARIABLES mus be EXPLICITLY written as in

                      OP(X,Y,F(G));

By IMPLICIT representation we mean one in which VARIABLES dependences are
"HIDDEN" as one obtains through the DEPEND command.  So the IMPLICIT
representation of the object above is

                      OP ;

TOGETHER with the command

                      DEPEND OP,X,Y,F(G);

One could equivalently call them the CONCRETE and ABSTRACT representations.
It is often much better in a calculation to manipulate the abstract represen-
tation but then we need functions allowing us to switch easily to the concrete
one and vice versa. The function

IMPLICIT returns its argument if it is an ATOM and returns the ABSTRACT (or
"implicit") representation of its argument if this argument is an OPERATOR
(or a FUNCTION). So

                  IMPLICIT OP(X,Y,F(G)); ==>     OP
                  IMPLICIT A           ; ==>     A.

The function EXPLICIT must have an argument x which is ALWAYS an ATOM. If
this atom is the abstract representation of an OPERATOR (or a FUNCTION) it
returns its CONCRETE (or "explicit") representation. So

                  EXPLICIT OP ; ==>    OP(X,Y,F(G))


                  DETIDXNUM x ;  where x is any IDENTIFIER

This function allows to identify a given variable in a set like
                        A1,A2,....A23,...
extracting the number appended to its name. It returns nothing if a
variable name terminates by a letter but any integer may be included in
the name. For instance

                  DETIDXNUM a1bb23c122 ; ==> 122

The function SET of REDUCE 3.4 is generalized and slightly modified to
make it work not only for atomic quantities but also for KERNELS. We have
not redefined the function SET but we have created the INFIX function
" == " . Suppose one makes the assignment

                  A:=OP(X);

then writing

                  A == SIN(X);

will assign OP(X) to SIN(X).

Finally the function SIMPLIFY which full forces resimplification of an
expression is an "emergency" function sometimes helpful to simplify
some output of the EXCALC package.

"PROPERTIES" AND "FLAGS":
-----------------------

One of the important drawbacks of the algebraic mode is the fact that the user
has not the possibility to ENDOW objects of flags and properties. The subse-
quent functions allow one to do that.
If one wants to give a flag or a property to one or a list of IDENTIFIERS
one must issue

                  PUTFLAG(idp,<flagname>,T); or
                  PUTFLAG(LIST(idp1,idp2,..),<flagname>,T);

                  PUTPROP(idp,<propname>,<value>,T); or
                  PUTPROP(LIST(idp1,idp2,..),<propname>,<value>,T);

The SAME commands must be issued if one wants to ERASE them EXCEPT that

                     T must be replaced by 0.


If one wants to DISPLAY the FLAGS or (and) the PROPERTIES of a given
IDENTIFIER one must issue the commands

                  DISPLAYFLAG(idp); or (and)
                  DISPLAYPROP(idp,<propname>);


We point out that the "DISPLAY" functions do not give access to the property
list generated at the level of the source code but ONLY to the properties
generated by the PUT(FLAG or PROP) commands i.e. to the properties or flags
CREATED BY THE USER.
Two additional functions for CLEARING are provided. They are

                   CLEARFLAG A1,A2,...An ;
                   CLEARPROP A1,A2,...An ;

where A1..,An  are identifiers. They eliminate ALL flags or properties
of these. Moreover if one chooses ALL as the UNIQUE argument ALL
flags or properties of ALL identifiers are ELIMINATED.


CONTROL FUNCTIONS
-----------------

Here we describe a certain number of functions which will help the user to
CONTROL and BETTER understand the REDUCE environment.
A collection of  BOOLEAN functions are available. They are

           ALATOMP x;     x is anything.
           ALKERNP x;      x is anything.
           PRECP(x,y);     x,y are ATOMS or printcharacters.
           DEPVARP(x,V);   x is anything, V is an ATOM or a KERNEL.

ALATOMP has the value T iff x is an integer or  an identifier AFTER it
has been evaluated.
ALKERNP has the value T iff x is a KERNEL AFTER it has been evaluated.
PRECP determines whether the OPERATION x has PRECEDENCE over the OPERATION y.
Returns T iff it is the case.
DEPVARP returns T iff the expression x depends on V at ANY LEVEL.
These functions are ALSO ALGEBRAIC functions. This is very convenient
to guide beginners and in particular to make them understand what a KERNEL is.
In addition the function

                       STRINGP x ;

which determines if x is a string is also available in conditional statements.
The next functions allow one to analyze and to CLEAN the environment
of REDUCE which is created by the user while he is working INTERACTIVELY.
They REMIND the user of the names of identifiers they have introduced
IN THE CONSOLE for different purposes and to make PARTIAL CLEARING of them
according to their TYPES.

There are TWO commands to remember:

                        SHOW and SUPPRESS.


They have different arguments which are associated to the different types.
So, one can deliver the following commands to DISPLAY the different used-ids:


                        SHOW SCALARS;
                        SHOW LISTS;
                        SHOW MATRICES;
                        SHOW ARRAYS;
                        SHOW VECTORS;    (contains vector, index and tvector)
                        SHOW FORMS;
                        SHOW ALL;

The argument ALL allows to see all user variables whatever their type.
SUPPRESS can be called with the same arguments.  It clears ALL ids of
the required type and eventually all of them.
It must be stressed these functions IGNORE all variables which are not
DIRECTLY introduced or manipulated ON THE CONSOLE.  For instance variables
which are used ONLY in an INPUT FILE.

The CLEAR function of the system does not do a complete cleaning of OPERATORS
and FUNCTIONS. The following two functions do a more complete cleaning which
also takes automatically into account the USER flag and properties that the
new functions PUTFLAG and PUTPROP may have introduced.

                        CLEAROP x;           x is an OPERATOR

do a COMPLETE cleaning of the x property list.

                        CLEARFUNCTIONS A1,A2,...An ;


do the same with ALL functions with names A1,A2...An.
These are still in an EXPERIMENTAL STAGE . The user should be careful
when he uses them since they only avoid to ERASE the PROTECTED functions and
most of the functions in the basic code are NOT protected.


HANDLING OF POLYNOMIALS :
-----------------------

The LOG file gives all necessary explanations here. Two comments are
to be made:

     a. MONOM is very useful since it places automatically of all monoms
              of a multivariate polynomial in a list. From the result
              each monom  can be manipulated SEPARATELY. Moreover, if
              one wishes, it becomes trivial to place them in an ARRAY
              or to put then as elements of a MATRIX.
     b. LEADTERM and REDEXPR works either on the recursive or on the
        distributive forms of a polynomial. They give a mean to control
        simplifications  and the swelling of intermediate expressions.
        The choice of the recursive- or distributive-way of working is
        made by the user through the command

                     OFF (ON) DISTRIBUTE;

HANDLING OF TRIGONOMETRIC FUNCTIONS :
-----------------------------------

The LOG file is here self-explanatory. The use of TRIG(HYP)REDUCE
followed by the use of TRIG(HYP)EXPAND makes the necessary simplifica-
tions for the sum-squared of the trig(hyp)-functions. In these two cases
they make the work of the COMPACT. It is not garanteed however that the
resulting expression will be the most compact one.


HANDLING OF LOG'S :
-----------------

PLUSLOG is put for convenience of the user. CONCSUMLOG do the reverse
job for any rational expression. Both of them restore the environment in
the status it had before their action.


BASIC OPERATIONS ON N-DIMENSIONAL (explicit) VECTORS
_____________________________________________________

Vectors in EUCLIDEAN space may be represented by list-like or bag-like
objects.  The components may be "bags" but may NOT be "lists".  This is so
because one has only defined operations between vectors and NOT between
tensors so that the operations at level 1 are ORDINARY algebraic
operations.  As already said list-like objects may NOT be treated as
ordinary kernels while bag-like objects do for the basic operations.
Of course one can be much more ambitious and we have indeed been. But in this
UTILITY package which must remain of rather small size and UNSPECIALIZED so
we confine to the ELEMENTARY cases.
We have, with U1,U2 being two BAGS or LISTS with n elements

                         SUMVECT(U1,U2);  for the sum of U1 and U2,

                         MINVECT(U1,U2);  for the difference of U1 and U2,

                         SCALVECT(U1,U2);for the scalar product.

LIMITED to 3-dimensional vectors we have

                         CROSSVECT(U1,U2); for the cross product,

                         MPVECT(U1,U2);    for the mixed product.



ADDITIONAL FUNCTIONS FOR MATRIX MANIPULATIONS
---------------------------------------------


                         MKIDM(U,J); J is an ATOM.

This functions works like MKID except that its argument U is a MATRIX. It is
also REQUIRED that Uj be a MATRIX. It allows one to make loops.
For instance if U,U1,U2,..U5 are matrices one may write

                         FOR I:=1:5 DO U:=U-MKIDM(U,I);

The next functions are COERCION functions i.e. they MAP matrices on
BAG-LIKE or LIST-LIKE objects and conversely they generate MATRICES from
"bags" or "lists".  If U is a MATRIX and id is any identifier

                         COERCEMAT(U,id);

COERCEMAT transforms U into a list of lists IFF id is equal to LIST otherwise
it transforms it into a bag of bags whose ENVELOPE has the NAME id.

If UN is a MATRIX-NAME and bgl is either a bag or a list of DEPTH two
the function

                         BAGLMAT(bgl,UN);

transforms bgl into a matrix whose name is UN.  The transformation is NOT
done if UN is ALREADY the name of a previously defined matrix.  This is to
avoid ACCIDENTAL redefinition of this matrix.

Often one needs to construct a UNIT matrix of some dimension.  This
construction is done by the system thanks to the function

                         UNITMAT M1(n1), M2(n2), .....Mi(ni) ;

where M1,...Mi are names of matrices and n1,n2,....ni are INTEGERS
representing space dimensions.

Submatrices are obtained using the function

                         SUBMAT(U,nr,nc);

where nr,nc are the row and column numbers respectively.  It gives the
submatrix obtained from U deleting the row nr and the column nc.  When nr
or nc are equal to zero only column nc or row nr is deleted.

Two functions allow one to EXTRACT a row or a column. They are

                         MATEXTR(U,VN,nr);

                         MATEXTC(U,VN,nc);

U is the matrix, VN is the "VECTOR NAME", nr and nc are integers.  If VN
is equal to LIST the vector is given as a list otherwise it is given as a
BAG.

Rows and columns may be SUBSTITUTED using

                         MATSUBR(U,bgl,nr);

                         MATSUBC(U,bgl,nc);

The meaning of the variables U,nr,nc is the same as above while bgl is a LIST
or a BAG. Of course the LENGTH (or the SIZE) of bgl should be compatible with
the dimensions of U.

Concatenation of two matrices can be made with

                         HCONCMAT(U,V);

                         VCONCMAT(U,V);

the first function concatenates horizontally, the second one concatenates
vertically.

The tensor product between two matrices is madse by

                         TPMAT(U,V); or U TPMAT V;

The hermitian matrix corresponding ti an already defined matrix is
created automatically by

                         HERMAT(U,hu);

hu becomes the hermitian matrix of U.
hu SHOULD be a FREE identifier for HERMAT to work successfully. This is
done on purpose to prevent accidental redefinition of an already used
used identifier .

SETELMAT allows to reset the element (i,j) of a given matrix while
GETELTMAT allows to extract the element (i,j). They are useful only
when used INSIDE a procedure.
