% 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} %