% Copyright The Numerical Algorithms Group Limited 1992-94. All rights reserved.
% !! DO NOT MODIFY THIS FILE BY HAND !! Created by ht.awk.
\newcommand{\MatrixXmpTitle}{Matrix}
\newcommand{\MatrixXmpNumber}{9.52}
%
% =====================================================================
\begin{page}{MatrixXmpPage}{9.52 Matrix}
% =====================================================================
\beginscroll

The \spadtype{Matrix} domain provides arithmetic operations on matrices
and standard functions from linear algebra.
This domain is similar to the \spadtype{TwoDimensionalArray} domain, except
that the entries for \spadtype{Matrix} must belong to a \spadtype{Ring}.

\beginmenu
    \menudownlink{{9.52.1. Creating Matrices}}{ugxMatrixCreatePage}
    \menudownlink{{9.52.2. Operations on Matrices}}{ugxMatrixOpsPage}
\endmenu
\endscroll
\autobuttons
\end{page}
%
%
\newcommand{\ugxMatrixCreateTitle}{Creating Matrices}
\newcommand{\ugxMatrixCreateNumber}{9.52.1.}
%
% =====================================================================
\begin{page}{ugxMatrixCreatePage}{9.52.1. Creating Matrices}
% =====================================================================
\beginscroll

There are many ways to create a matrix from a collection of
values or from existing matrices.

\xtc{
If the matrix has almost all items equal to the same value,
use \spadfunFrom{new}{Matrix} to create a matrix filled with that
value and then reset the entries that are different.
}{
\spadpaste{m : Matrix(Integer) := new(3,3,0) \bound{m}}
}
\xtc{
To change the entry in the second row, third column to \spad{5}, use
\spadfunFrom{setelt}{Matrix}.
}{
\spadpaste{setelt(m,2,3,5) \free{m}\bound{m1}}
}
\xtc{
An alternative syntax is to use assignment.
}{
\spadpaste{m(1,2) := 10 \free{m1}\bound{m2}}
}
\xtc{
The matrix was {\it destructively modified}.
%-% \HDindex{matrix!destructive change to}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
}{
\spadpaste{m \free{m2}}
}

\xtc{
If you already have the matrix entries as a list of lists,
use \spadfunFrom{matrix}{Matrix}.
}{
\spadpaste{matrix [[1,2,3,4],[0,9,8,7]]}
}

\xtc{
If the matrix is diagonal, use
%-% \HDindex{matrix!diagonal}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
\spadfunFrom{diagonalMatrix}{Matrix}.
}{
\spadpaste{dm := diagonalMatrix [1,x**2,x**3,x**4,x**5] \bound{dm}}
}
\xtc{
Use \spadfunFromX{setRow}{Matrix} and
\spadfunFromX{setColumn}{Matrix} to change a row or column of a matrix.
}{
\spadpaste{setRow!(dm,5,vector [1,1,1,1,1]) \free{dm}\bound{dm1}}
}
\xtc{
}{
\spadpaste{setColumn!(dm,2,vector [y,y,y,y,y]) \free{dm1}\bound{dm2}}
}

%
\xtc{
Use \spadfunFrom{copy}{Matrix} to make a copy of a matrix.
%-% \HDindex{matrix!copying}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
}{
\spadpaste{cdm := copy(dm) \free{dm2}\bound{cdm}}
}
\xtc{
This is useful if you intend to modify a matrix destructively but
want a copy of the original.
}{
\spadpaste{setelt(dm,4,1,1-x**7) \free{dm2}\bound{setdm}}
}
\xtc{
}{
\spadpaste{[dm,cdm] \free{setdm cdm}}
}

%
\xtc{
Use \spadfunFrom{subMatrix}{Matrix} to extract part of an
%-% \HDindex{matrix!submatrix of}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
existing matrix.
The syntax is \spad{subMatrix({\it m, firstrow, lastrow, firstcol,
lastcol})}.
}{
\spadpaste{subMatrix(dm,2,3,2,4) \free{setdm}}
}

%
\xtc{
To change a submatrix, use \spadfunFromX{setsubMatrix}{Matrix}.
}{
\spadpaste{d := diagonalMatrix [1.2,-1.3,1.4,-1.5] \bound{d}}
}
\xtc{
If \spad{e} is too big to fit where you specify, an error message
is displayed.
Use \spadfunFrom{subMatrix}{Matrix} to extract part of \spad{e}, if
necessary.
}{
\spadpaste{e := matrix [[6.7,9.11],[-31.33,67.19]] \bound{e}}
}
\xtc{
This changes the submatrix of \spad{d} whose upper left corner is
at the first row and second column and whose size is that of \spad{e}.
}{
\spadpaste{setsubMatrix!(d,1,2,e) \free{d e}\bound{d1}}
}
\xtc{
}{
\spadpaste{d \free{d1}}
}
%

%
\xtc{
Matrices can be joined either horizontally or vertically to make
%-% \HDindex{matrix!concatenating}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
new matrices.
}{
\spadpaste{a := matrix [[1/2,1/3,1/4],[1/5,1/6,1/7]] \bound{a}}
}
\xtc{
}{
\spadpaste{b := matrix [[3/5,3/7,3/11],[3/13,3/17,3/19]] \bound{b}}
}
\xtc{
Use \spadfunFrom{horizConcat}{Matrix} to append them side to side.
The two matrices must have the same number of rows.
}{
\spadpaste{horizConcat(a,b) \free{a b}}
}
\xtc{
Use \spadfunFrom{vertConcat}{Matrix} to stack one upon the other.
The two matrices must have the same number of columns.
}{
\spadpaste{vab := vertConcat(a,b) \free{a b}\bound{vab}}
}

%
\xtc{
The operation
\spadfunFrom{transpose}{Matrix} is used to create a new matrix by reflection
%-% \HDindex{matrix!transposing}{ugxMatrixCreatePage}{9.52.1.}{Creating Matrices}
across the main diagonal.
}{
\spadpaste{transpose vab \free{vab}}
}

\endscroll
\autobuttons
\end{page}
%
%
\newcommand{\ugxMatrixOpsTitle}{Operations on Matrices}
\newcommand{\ugxMatrixOpsNumber}{9.52.2.}
%
% =====================================================================
\begin{page}{ugxMatrixOpsPage}{9.52.2. Operations on Matrices}
% =====================================================================
\beginscroll

\labelSpace{3pc}
\xtc{
\Language{} provides both left and right scalar multiplication.
}{
\spadpaste{m := matrix [[1,2],[3,4]] \bound{m}}
}
\xtc{
}{
\spadpaste{4 * m * (-5)\free{m}}
}
\xtc{
You can add, subtract, and multiply matrices provided, of course, that
the matrices have compatible dimensions.
If not, an error message is displayed.
}{
\spadpaste{n := matrix([[1,0,-2],[-3,5,1]]) \bound{n}}
}
\xtc{
This following product is defined but \spad{n * m} is not.
}{
\spadpaste{m * n \free{m n}}
}

The operations \spadfunFrom{nrows}{Matrix} and \spadfunFrom{ncols}{Matrix}
return the number of rows and columns of a matrix.
You can extract a row or a column of a matrix using the operations
\spadfunFrom{row}{Matrix} and \spadfunFrom{column}{Matrix}.
The object returned is a \spadtype{Vector}.
\xtc{
Here is the third column of the matrix \spad{n}.
}{
\spadpaste{vec := column(n,3) \free{n} \bound{vec}}
}
\xtc{
You can multiply a matrix on the left by a ``row vector'' and on the right
by a ``column vector.''
}{
\spadpaste{vec * m \free{vec m}}
}
\xtc{
Of course, the dimensions of the vector and the matrix must be compatible
or an error message is returned.
}{
\spadpaste{m * vec \free{vec m}}
}

The operation \spadfunFrom{inverse}{Matrix} computes the inverse of a
matrix if
%-% \HDindex{matrix!inverse of}{ugxMatrixOpsPage}{9.52.2.}{Operations on Matrices}
the matrix is invertible, and returns \spad{"failed"} if not.
\xtc{
This Hilbert matrix is invertible.
}{
\spadpaste{hilb := matrix([[1/(i + j) for i in 1..3] for j in 1..3]) \bound{hilb}}
}
\xtc{
}{
\spadpaste{inverse(hilb) \free{hilb}}
}
\xtc{
This matrix is not invertible.
}{
\spadpaste{mm := matrix([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]]) \bound{mm}}
}
\xtc{
}{
\spadpaste{inverse(mm) \free{mm}}
}

The operation \spadfunFrom{determinant}{Matrix} computes the determinant of a matrix
%-% \HDindex{matrix!determinant of}{ugxMatrixOpsPage}{9.52.2.}{Operations on Matrices}
provided that the entries of the matrix belong to a \spadtype{CommutativeRing}.
\xtc{
The above matrix \spad{mm} is not invertible and, hence, must have
determinant \spad{0}.
}{
\spadpaste{determinant(mm) \free{mm}}
}
\xtc{
The operation
\spadfunFrom{trace}{SquareMatrix} computes the trace of a {\em square} matrix.
%-% \HDindex{matrix!trace of}{ugxMatrixOpsPage}{9.52.2.}{Operations on Matrices}
}{
\spadpaste{trace(mm) \free{mm}}
}

\xtc{
The operation \spadfunFrom{rank}{Matrix} computes the {\it rank} of a
matrix:
%-% \HDindex{matrix!rank of}{ugxMatrixOpsPage}{9.52.2.}{Operations on Matrices}
the maximal number of linearly independent rows or columns.
}{
\spadpaste{rank(mm) \free{mm}}
}
\xtc{
The operation \spadfunFrom{nullity}{Matrix} computes the {\it nullity} of
a matrix: the dimension of its null space.
}{
\spadpaste{nullity(mm) \free{mm}}
}
\xtc{
The operation \spadfunFrom{nullSpace}{Matrix} returns a list containing a basis for the
null space of a matrix.
Note that the nullity is the number of elements in a basis for the null space.
}{
\spadpaste{nullSpace(mm) \free{mm}}
}
\xtc{
The operation \spadfunFrom{rowEchelon}{Matrix} returns the row echelon form of a
%-% \HDindex{matrix!row echelon form of}{ugxMatrixOpsPage}{9.52.2.}{Operations on Matrices}
matrix.
It is easy to see that the rank of this matrix is two and that its nullity
is also two.
}{
\spadpaste{rowEchelon(mm) \free{mm}}
}

For more information on related topics, see
\downlink{``\ugIntroTwoDimTitle''}{ugIntroTwoDimPage} in Section \ugIntroTwoDimNumber\ignore{ugIntroTwoDim},
\downlink{``\ugProblemEigenTitle''}{ugProblemEigenPage} in Section \ugProblemEigenNumber\ignore{ugProblemEigen},
\downlink{``\ugxFloatHilbertTitle''}{ugxFloatHilbertPage} in Section \ugxFloatHilbertNumber\ignore{ugxFloatHilbert},
\downlink{`Permanent'}{PermanentXmpPage}\ignore{Permanent},
\downlink{`Vector'}{VectorXmpPage}\ignore{Vector},
\downlink{`OneDimensionalArray'}{OneDimensionalArrayXmpPage}\ignore{OneDimensionalArray}, and
\downlink{`TwoDimensionalArray'}{TwoDimensionalArrayXmpPage}\ignore{TwoDimensionalArray}.
%
\showBlurb{Matrix}
\endscroll
\autobuttons
\end{page}
%