Introduction to Matrices and Linear Algebra
===========================================

DOT
---

- . The dot operator, for matrix (non-commutative) multiplication.  When "." is used in this way, spaces should be left on both sides of it, e.g. A . B.  This distinguishes it plainly from a decimal point in a floating point number.  Do APROPOS(DOT); for a list of the switches which affect the dot operator.

VECTORS
-------

- The file SHARE;VECT > contains a vector analysis package, share/vect.dem contains a corresponding demonstration, and SHARE;VECT ORTH contains definitions of various orthogonal curvilinear coordinate systems.  LOAD(VECT); will load this package for you. The vector analysis package can combine and simplify symbolic expressions including dot products and cross products, together with the gradient, divergence, curl, and Laplacian operators.  The distribution of these operators over sums or products is under user control, as are various other expansions, including expansion into components in any specific orthogonal coordinate systems. There is also a capability for deriving the scalar or vector potential of a field. The package contains the following commands: VECTORSIMP, SCALEFACTORS, EXPRESS, POTENTIAL, and VECTORPOTENTIAL.  Do DESCRIBE(cmd) on these command names, or PRINTFILE(VECT,USAGE,SHARE); for details. Warning:  The VECT package declares "." to be a commutative operator.

Definitions for Matrices and Linear Algebra
===========================================

 -- Function: ADDCOL (M,list1,list2,...,listn)
     appends the column(s) given by the one or more lists (or matrices) onto the matrix M.

 -- Function: ADDROW (M,list1,list2,...,listn)
     appends the row(s) given by the one or more lists (or matrices) onto the matrix M.

 -- Function: ADJOINT (matrix)
     computes the adjoint of a matrix.

 -- Function: AUGCOEFMATRIX ([eq1, ...], [var1, ...])
     the augmented coefficient matrix for the variables var1,... of the system of linear equations eq1,....  This is the coefficient matrix with a column adjoined for the constant terms in each equation (i.e. those not dependent upon var1,...).  Do EXAMPLE(AUGCOEFMATRIX); for an example.

 -- Function: CHARPOLY (M, var)
     computes the characteristic polynomial for Matrix M with respect to var.  That is, DETERMINANT(M - DIAGMATRIX(LENGTH(M),var)). For examples of this command, do EXAMPLE(CHARPOLY); .

 -- Function: COEFMATRIX ([eq1, ...], [var1, ...])
     the coefficient matrix for the variables var1,... of the system of linear equations eq1,...

 -- Function: COL (M,i)
     gives a matrix of the ith column of the matrix M.

 -- Function: COLUMNVECTOR (X)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  COLUMNVECTOR takes a LIST as its argument and returns a column vector the components of which are the elements of the list. The first element is the first component,...etc...(This is useful if you want to use parts of the outputs of the functions in this package in matrix calculations.)

 -- Function: CONJUGATE (X)
     a function in the EIGEN package on the SHARE directory.  It returns the complex conjugate of its argument.  This package may be loaded by LOAD(EIGEN); .  For a complete description of this package, do PRINTFILE("eigen.usg"); .

 -- Function: COPYMATRIX (M)
     creates a copy of the matrix M.  This is the only way to make a copy aside from recreating M elementwise.  Copying a matrix may be useful when SETELMX is used.

 -- Function: DETERMINANT (M)
     computes the determinant of M by a method similar to Gaussian elimination.  The form of the result depends upon the setting of the switch RATMX.  There is a special routine for dealing with sparse determininants which can be used by setting the switches RATMX:TRUE and SPARSE:TRUE.

 -- Variable: DETOUT
     default: [FALSE] if TRUE will cause the determinant of a matrix whose inverse is computed to be kept outside of the inverse. For this switch to have an effect DOALLMXOPS and DOSCMXOPS should be FALSE (see their descriptions).  Alternatively this switch can be given to EV which causes the other two to be set correctly.

 -- Function: DIAGMATRIX (n, x)
     returns a diagonal matrix of size n by n with the diagonal elements all x.  An identity matrix is created by DIAGMATRIX(n,1), or one may use IDENT(n).

 -- Variable: DOALLMXOPS
     default: [TRUE] if TRUE all operations relating to matrices are carried out.  If it is FALSE then the setting of the individual DOT switches govern which operations are performed.

 -- Variable: DOMXEXPT
     default: [TRUE] if TRUE,

          %E^MATRIX([1,2],[3,4]) ==>
          MATRIX([%E,%E^2],[%E^3,%E^4])

     In general, this transformation affects expressions of the form <base>^<power> where <base> is an expression assumed scalar or constant, and <power> is a list or matrix.  This transformation is turned off if this switch is set to FALSE.

 -- Variable: DOMXMXOPS
     default: [TRUE] if TRUE then all matrix-matrix or matrix-list operations are carried out (but not scalar-matrix operations); if this switch is FALSE they are not.

 -- Variable: DOMXNCTIMES
     default: [FALSE] Causes non-commutative products of matrices to be carried out.

 -- Variable: DONTFACTOR
     default: [] may be set to a list of variables with respect to which factoring is not to occur.  (It is initially empty). Factoring also will not take place with respect to any variables which are less important (using the variable ordering assumed for CRE form) than those on the DONTFACTOR list.

 -- Variable: DOSCMXOPS
     default: [FALSE] if TRUE then scalar-matrix operations are performed.

 -- Variable: DOSCMXPLUS
     default: [FALSE] if TRUE will cause SCALAR + MATRIX to give a matrix answer.  This switch is not subsumed under DOALLMXOPS.

 -- Variable: DOT0NSCSIMP
     default: [TRUE] Causes a non-commutative product of zero and a nonscalar term to be simplified to a commutative product.

 -- Variable: DOT0SIMP
     default: [TRUE] Causes a non-commutative product of zero and a scalar term to be simplified to a commutative product.

 -- Variable: DOT1SIMP
     default: [TRUE] Causes a non-commutative product of one and another term to be simplified to a commutative product.

 -- Variable: DOTASSOC
     default: [TRUE] when TRUE causes (A.B).C to simplify to A.(B.C)

 -- Variable: DOTCONSTRULES
     default: [TRUE] Causes a non-commutative product of a constant and another term to be simplified to a commutative product. Turning on this flag effectively turns on DOT0SIMP, DOT0NSCSIMP, and DOT1SIMP as well.

 -- Variable: DOTDISTRIB
     default: [FALSE] if TRUE will cause A.(B+C) to simplify to A.B+A.C

 -- Variable: DOTEXPTSIMP
     default: [TRUE] when TRUE causes A.A to simplify to A^^2

 -- Variable: DOTIDENT
     default: [1]  The value to be returned by X^^0.

 -- Variable: DOTSCRULES
     default: [FALSE] when TRUE will cause A.SC or SC.A to simplify to SC*A and A.(SC*B) to simplify to SC*(A.B)

 -- Function: ECHELON (M)
     produces the echelon form of the matrix M.  That is, M with elementary row operations performed on it such that the first non-zero element in each row in the resulting matrix is a one and the column elements under the first one in each row are all zero.

                                  [2  1 - A  -5 B ]
          (D2)                    [               ]
                                  [A    B      C  ]

          (C3) ECHELON(D2);
                           [      A - 1        5 B      ]
                           [1   - -----      - ---      ]
                           [        2           2       ]
          (D3)             [                            ]
                           [                2 C + 5 A B ]
                           [0     1         ------------]
                           [                       2    ]
                           [                2 B + A  - A]

 -- Function: EIGENVALUES (mat)
     There is a package on the SHARE; directory which contains functions for computing EIGENVALUES and EIGENVECTORS and related matrix computations.  For information on it do PRINTFILE(EIGEN,USAGE,SHARE); . EIGENVALUES(mat) takes a MATRIX as its argument and returns a list of lists the first sublist of which is the list of eigenvalues of the matrix and the other sublist of which is the list of the multiplicities of the eigenvalues in the corresponding order.  [ The MACSYMA function SOLVE is used here to find the roots of the characteristic polynomial of the matrix.  Sometimes SOLVE may not be able to find the roots of the polynomial;in that case nothing in this package except CONJUGATE, INNERPRODUCT, UNITVECTOR, COLUMNVECTOR and GRAMSCHMIDT will work unless you know the eigenvalues.  In some cases SOLVE may generate very messy eigenvalues.  You may want to simplify the answers yourself before you go on.  There are provisions for this and they will be explained below.  ( This usually happens when SOLVE returns a not-so-obviously real expression for an eigenvalue which is supposed to be real...)]  The EIGENVALUES command is available directly from MACSYMA.  To use the other functions you must have loaded in the EIGEN package, either by a previous call to EIGENVALUES, or by doing LOADFILE("eigen"); .

 -- Function: EIGENVECTORS (MAT)
     takes a MATRIX as its argument and returns a list of lists the first sublist of which is the output of the EIGENVALUES command and the other sublists of which are the eigenvectors of the matrix corresponding to those eigenvalues respectively.  This function will work directly from MACSYMA, but if you wish to take advantage of the flags for controlling it (see below), you must first load in the EIGEN package from the SHARE; directory.  You may do that by LOADFILE("eigen");.  The flags that affect this function are: NONDIAGONALIZABLE[FALSE] will be set to TRUE or FALSE depending on whether the matrix is nondiagonalizable or diagonalizable after an EIGENVECTORS command is executed. HERMITIANMATRIX[FALSE] If set to TRUE will cause the degenerate eigenvectors of the hermitian matrix to be orthogonalized using the Gram-Schmidt algorithm. KNOWNEIGVALS[FALSE] If set to TRUE the EIGEN package will assume the eigenvalues of the matrix are known to the user and stored under the global name LISTEIGVALS.  LISTEIGVALS should be set to a list similar to the output of the EIGENVALUES command.  ( The MACSYMA function ALGSYS is used here to solve for the eigenvectors. Sometimes if the eigenvalues are messy, ALGSYS may not be able to produce a solution. In that case you are advised to try to simplify the eigenvalues by first finding them using EIGENVALUES command and then using whatever marvelous tricks you might have to reduce them to something simpler. You can then use the KNOWNEIGVALS flag to proceed further. )

 -- Function: EMATRIX (m, n, x, i, j)
     will create an m by n matrix all of whose elements are zero except for the i,j element which is x.

 -- Function: ENTERMATRIX (m, n)
     allows one to enter a matrix element by element with MACSYMA requesting values for each of the m*n entries.

          (C1) ENTERMATRIX(3,3);
          Is the matrix  1. Diagonal  2. Symmetric  3. Antisymmetric
           4. General

          Answer 1, 2, 3 or 4
          1;
          Row 1 Column 1:  A;
          Row 2 Column 2:  B;
          Row 3 Column 3:  C;
          Matrix entered.
                                           [ A  0  0 ]
                                           [         ]
          (D1)                             [ 0  B  0 ]
                                           [         ]
                                           [ 0  0  C ]

 -- Function: GENMATRIX (array, i2, j2, i1, j1)
     generates a matrix from the array using array(i1,j1) for the first (upper-left) element and array(i2,j2) for the last (lower-right) element of the matrix.  If j1=i1 then j1 may be omitted. If j1=i1=1 then i1 and j1 may both be omitted. If a selected element of the array doesn't exist a symbolic one will be used.

          (C1) H[I,J]:=1/(I+J-1)$
          (C2) GENMATRIX(H,3,3);
                                     [   1  1]
                                     [1  -  -]
                                     [   2  3]
                                     [       ]
                                     [1  1  1]
          (D2)                       [-  -  -]
                                     [2  3  4]
                                     [       ]
                                     [1  1  1]
                                     [-  -  -]
                                     [3  4  5]

 -- Function: GRAMSCHMIDT (X)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  GRAMSCHMIDT takes a LIST of lists the sublists of which are of equal length and not necessarily orthogonal (with respect to the innerproduct defined above) as its argument and returns a similar list each sublist of which is orthogonal to all others.  (Returned results may contain integers that are factored.  This is due to the fact that the MACSYMA function FACTOR is used to simplify each substage of the Gram-Schmidt algorithm.  This prevents the expressions from getting very messy and helps to reduce the sizes of the numbers that are produced along the way.)

 -- Function: HACH (a,b,m,n,l)
     An implementation of Hacijan's linear programming algorithm is available by doing BATCH("kach.mc"$.  Details of use are available by doing BATCH("kach.dem");

 -- Function: IDENT (n)
     produces an n by n identity matrix.

 -- Function: INNERPRODUCT (X,Y)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  INNERPRODUCT takes two LISTS of equal length as its arguments and returns their inner (scalar) product defined by (Complex Conjugate of X).Y (The "dot" operation is the same as the usual one defined for vectors).

 -- Function: INVERT (matrix)
     finds the inverse of a matrix using the adjoint method.  This allows a user to compute the inverse of a matrix with bfloat entries or polynomials with floating pt. coefficients without converting to cre-form.  The DETERMINANT command is used to compute cofactors, so if RATMX is FALSE (the default) the inverse is computed without changing the representation of the elements.  The current implementation is inefficient for matrices of high order. The DETOUT flag if true keeps the determinant factored out of the inverse. Note: the results are not automatically expanded.  If the matrix originally had polynomial entries, better appearing output can be generated by EXPAND(INVERT(mat)),DETOUT.  If it is desirable to then divide through by the determinant this can be accomplished by XTHRU(%) or alternatively from scratch by EXPAND(ADJOINT(mat))/EXPAND(DETERMINANT(mat)). INVERT(mat):=ADJOINT(mat)/DETERMINANT(mat). See also DESCRIBE("^^"); for another method of inverting a matrix.

 -- Variable: LMXCHAR
     default: [[] - The character used to display the (left) delimiter of a matrix (see also RMXCHAR).

 -- Function: MATRIX (row1, ..., rown)
     defines a rectangular matrix with the indicated rows.  Each row has the form of a list of expressions, e.g. [A, X**2, Y, 0] is a list of 4 elements.  There are a number of MACSYMA commands which deal with matrices, for example:  DETERMINANT, CHARPOLY, GENMATRIX, ADDCOL, ADDROW, COPYMATRIX, TRANSPOSE, ECHELON, and RANK.  There is also a package on the SHARE directory for computing EIGENVALUES.  Try DESCRIBE on these for more information. Matrix multiplication is effected by using the dot operator, ".", which is also convenient if the user wishes to represent other non-commutative algebraic operations.  The exponential of the "." operation is "^^" . Thus, for a matrix A, A.A = A^^2 and, if it exists, A^^-1 is the inverse of A. The operations +,-,*,** are all element-by-element operations; all operations are normally carried out in full, including the . (dot) operation.  Many switches exist for controlling simplification rules involving dot and matrix-list operations. Options Relating to Matrices: LMXCHAR, RMXCHAR, RATMX, LISTARITH, DETOUT, DOALLMXOPS, DOMXEXPT DOMXMXOPS, DOSCMXOPS, DOSCMXPLUS, SCALARMATRIX, and SPARSE. Do DESCRIBE(option) for details on them.

 -- Function: MATRIXMAP (fn, M)
     will map the function fn onto each element of the matrix M.

 -- Function: MATRIXP (exp)
     is TRUE if exp is a matrix else FALSE.

 -- Variable: MATRIX_ELEMENT_ADD
     default: [+] - May be set to "?"; may also be the name of a function, or a LAMBDA expression.  In this way, a rich variety of algebraic structures may be simulated.  For more details, do DEMO("matrix.dem1"); and DEMO("matrix.dem2");.

 -- Variable: MATRIX_ELEMENT_MULT
     default: [*] - May be set to "."; may also be the name of a function, or a LAMBDA expression.  In this way, a rich variety of algebraic structures may be simulated.  For more details, do DEMO("matrix.dem1"); and DEMO("matrix.dem2");

 -- Variable: MATRIX_ELEMENT_TRANSPOSE
     default: [FALSE] - Other useful settings are TRANSPOSE and NONSCALARS; may also be the name of a function, or a LAMBDA expression.  In this way, a rich variety of algebraic structures may be simulated.  For more details, do DEMO("matrix.dem1"); and DEMO("matrix.dem2");.

 -- Function: MATTRACE (M)
     computes the trace [sum of the elements on the main diagonal] of the square matrix M.  It is used by NCHARPOLY, an alternative to MACSYMA's CHARPOLY.  It is used by doing LOADFILE("nchrpl");

 -- Function: MINOR (M, i, j)
     computes the i,j minor of the matrix M.  That is, M with row i and column j removed.

 -- Function: NCEXPT (A,B)
     if an (non-commutative) exponential expression is too wide to be displayed as A^^B it will appear as NCEXPT(A,B).

 -- Function: NCHARPOLY (M,var)
     finds the characteristic polynomial of the matrix M with respect to var.  This is an alternative to MACSYMA's CHARPOLY. NCHARPOLY works by computing traces of powers of the given matrix, which are known to be equal to sums of powers of the roots of the characteristic polynomial.  From these quantities the symmetric functions of the roots can be calculated, which are nothing more than the coefficients of the characteristic polynomial.  CHARPOLY works by forming the determinant of VAR * IDENT [N] - A.  Thus NCHARPOLY wins, for example, in the case of large dense matrices filled with integers, since it avoids polynomial arithmetic altogether.  It may be used by doing LOADFILE("nchrpl");

 -- Function: NEWDET (M,n)
     also computes the determinant of M but uses the Johnson-Gentleman tree minor algorithm.  M may be the name of a matrix or array.  The argument n is the order; it is optional if M is a matrix.

 -- declaration: NONSCALAR
     - makes ai behave as does a list or matrix with respect to the dot operator.

 -- Function: NONSCALARP (exp)
     is TRUE if exp is a non-scalar, i.e.  it contains atoms declared as non-scalars, lists, or matrices.

 -- Function: PERMANENT (M,n)
     computes the permanent of the matrix M.  A permanent is like a determinant but with no sign changes.

 -- Function: RANK (M)
     computes the rank of the matrix M.  That is, the order of the largest non-singular subdeterminant of M.  Caveat: RANK may return the wrong answer if it cannot determine that a matrix element that is equivalent to zero is indeed so.

 -- Variable: RATMX
     default: [FALSE] - if FALSE will cause determinant and matrix addition, subtraction, and multiplication to be performed in the representation of the matrix elements and will cause the result of matrix inversion to be left in general representation.  If it is TRUE, the 4 operations mentioned above will be performed in CRE form and the result of matrix inverse will be in CRE form.  Note that this may cause the elements to be expanded (depending on the setting of RATFAC) which might not always be desired.

 -- Function: ROW (M, i)
     gives a matrix of the ith row of matrix M.

 -- Variable: SCALARMATRIXP
     default: [TRUE] - if TRUE, then whenever a 1 x 1 matrix is produced as a result of computing the dot product of matrices it will be converted to a scalar, namely the only element of the matrix. If set to ALL, then this conversion occurs whenever a 1 x 1 matrix is simplified.  If set to FALSE, no conversion will be done.

 -- Function: SETELMX (x, i, j, M)
     changes the i,j element of M to x.  The altered matrix is returned as the value.  The notation M[i,j]:x may also be used, altering M in a similar manner, but returning x as the value.

 -- Function: SIMILARITYTRANSFORM (MAT)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  SIMILARITYTRANSFORM takes a MATRIX as its argument and returns a list which is the output of the UNITEIGENVECTORS command.  In addition if the flag NONDIAGONALIZABLE is FALSE two global matrices LEFTMATRIX and RIGHTMATRIX will be generated.  These matrices have the property that LEFTMATRIX.MAT.RIGHTMATRIX is a diagonal matrix with the eigenvalues of MAT on the diagonal.  If NONDIAGONALIZABLE is TRUE these two matrices will not be generated.  If the flag HERMITIANMATRIX is TRUE then LEFTMATRIX is the complex conjugate of the transpose of RIGHTMATRIX.  Otherwise LEFTMATRIX is the inverse of RIGHTMATRIX. RIGHTMATRIX is the matrix the columns of which are the unit eigenvectors of MAT.  The other flags (see DESCRIBE(EIGENVALUES); and DESCRIBE(EIGENVECTORS);) have the same effects since SIMILARITYTRANSFORM calls the other functions in the package in order to be able to form RIGHTMATRIX.

 -- Variable: SPARSE
     default: [FALSE] - if TRUE and if RATMX:TRUE then DETERMINANT will use special routines for computing sparse determinants.

 -- Function: SUBMATRIX (m1, ..., M, n1, ...)
     creates a new matrix composed of the matrix M with rows mi deleted, and columns ni deleted.

 -- Function: TRANSPOSE (M)
     produces the transpose of the matrix M.

 -- Function: TRIANGULARIZE (M)
     produces the upper triangular form of the matrix M which needn't be square.

 -- Function: UNITEIGENVECTORS (MAT)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  UNITEIGENVECTORS takes a MATRIX as its argument and returns a list of lists the first sublist of which is the output of the EIGENVALUES command and the other sublists of which are the unit eigenvectors of the matrix corresponding to those eigenvalues respectively.  The flags mentioned in the description of the EIGENVECTORS command have the same effects in this one as well.  In addition there is a flag which may be useful : KNOWNEIGVECTS[FALSE] - If set to TRUE the EIGEN package will assume that the eigenvectors of the matrix are known to the user and are stored under the global name LISTEIGVECTS.  LISTEIGVECTS should be set to a list similar to the output of the EIGENVECTORS command.  (If KNOWNEIGVECTS is set to TRUE and the list of eigenvectors is given the setting of the flag NONDIAGONALIZABLE may not be correct.  If that is the case please set it to the correct value.  The author assumes that the user knows what he is doing and will not try to diagonalize a matrix the eigenvectors of which do not span the vector space of the appropriate dimension...)

 -- Function: UNITVECTOR (X)
     a function in the EIGEN package.  Do LOAD(EIGEN) to use it.  UNITVECTOR takes a LIST as its argument and returns a unit list.  (i.e. a list with unit magnitude).

 -- Function: VECTORSIMP (vectorexpression)
     This function employs additional simplifications, together with various optional expansions according to the settings of the following global flags:

          EXPANDALL, EXPANDDOT, EXPANDDOTPLUS, EXPANDCROSS, EXPANDCROSSPLUS,
          EXPANDCROSSCROSS, EXPANDGRAD, EXPANDGRADPLUS, EXPANDGRADPROD,
          EXPANDDIV, EXPANDDIVPLUS, EXPANDDIVPROD, EXPANDCURL, EXPANDCURLPLUS,
          EXPANDCURLCURL, EXPANDLAPLACIAN, EXPANDLAPLACIANPLUS,
          EXPANDLAPLACIANPROD.

     All these flags have default value FALSE. The PLUS suffix refers to employing additivity or distributivity.  The PROD suffix refers to the expansion for an operand that is any kind of product. EXPANDCROSSCROSS refers to replacing p~(q~r) with (p.r)*q-(p.q)*r, and EXPANDCURLCURL refers to replacing CURL CURL p with GRAD DIV p + DIV GRAD p.  EXPANDCROSS:TRUE has the same effect as EXPANDCROSSPLUS:EXPANDCROSSCROSS:TRUE, etc.  Two other flags, EXPANDPLUS and EXPANDPROD, have the same effect as setting all similarly suffixed flags true.  When TRUE, another flag named EXPANDLAPLACIANTODIVGRAD, replaces the LAPLACIAN operator with the composition DIV GRAD.  All of these flags are initially FALSE.  For convenience, all of these flags have been declared EVFLAG. For orthogonal curvilinear coordinates, the global variables COORDINATES[[X,Y,Z]], DIMENSION[3], SF[[1,1,1]], and SFPROD[1] are set by the function invocation

 -- Variable: VECT_CROSS
     default:[FALSE] - If TRUE allows DIFF(X~Y,T) to work where ~ is defined in SHARE;VECT (where VECT_CROSS is set to TRUE, anyway.)

 -- Function: ZEROMATRIX (m,n)
     takes integers m,n as arguments and returns an m by n matrix of 0's.

 -- special symbol: "["
     - [ and ] are the characters which MACSYMA uses to delimit a list.