
			Linear Algebra

*INTRO This chapter describes the commands for doing linear
algebra. They can be used to manipulate vectors, represented as lists,
and matrices, represented as lists of lists.


*CMD Dot, . --- get dot product of tensors
*STD
*CALL
	Dot(t1,t2)
	t1 . t2
Precedence:
*EVAL OpPrecedence(".")

*PARMS

{t1,t2} -- tensor lists (currently only vectors and matrices are supported)

*DESC

{Dot} returns the dot (aka inner) product of two tensors t1 and t2. The last
index of t1 and the first index of t2 are contracted. Currently {Dot} works
only for vectors and matrices. {Dot}-multiplication of two vectors, a matrix
with a vector (and vice versa) or two matrices yields either a scalar, a
vector or a matrix.

*E.G.

	In> Dot({1,2},{3,4})
	Out> 11;
	In> Dot({{1,2},{3,4}},{5,6})
	Out> {17,39};
	In> Dot({5,6},{{1,2},{3,4}})
	Out> {23,34};
	In> Dot({{1,2},{3,4}},{{5,6},{7,8}})
	Out> {{19,22},{43,50}};

	Or, using the "."-Operator:

	In> {1,2} . {3,4}
	Out> 11;
	In> {{1,2},{3,4}} . {5,6}
	Out> {17,39};
	In> {5,6} . {{1,2},{3,4}}
	Out> {23,34};
	In> {{1,2},{3,4}} . {{5,6},{7,8}}
	Out> {{19,22},{43,50}};

*SEE Outer, Cross, IsScalar, IsVector, IsMatrix


*CMD InProduct --- inner product of vectors (deprecated)
*STD
*CALL
	InProduct(a,b)

*PARMS

{a}, {b} -- vectors of equal length

*DESC

The inner product of the two vectors "a" and "b" is returned. The
vectors need to have the same size.

This function is superceded by the {.} operator.

*E.G.

	In> {a,b,c} . {d,e,f};
	Out> a*d+b*e+c*f;

*SEE Dot, CrossProduct

*CMD CrossProduct --- outer product of vectors
*STD
*CALL
	CrossProduct(a,b)
	a X b
Precedence:
*EVAL OpPrecedence("X")

*PARMS

{a}, {b} -- three-dimensional vectors

*DESC

The cross product of the vectors "a"
and "b" is returned. The result is perpendicular to both "a" and
"b" and its length is the product of the lengths of the vectors.
Both "a" and "b" have to be three-dimensional.

*E.G.

	In> {a,b,c} X {d,e,f};
	Out> {b*f-c*e,c*d-a*f,a*e-b*d};

*SEE InProduct





*CMD Outer, o --- get outer tensor product
*STD
*CALL
	Outer(t1,t2)
	t1 o t2
Precedence:
*EVAL OpPrecedence("o")

*PARMS

{t1,t2} -- tensor lists (currently only vectors are supported)

*DESC

{Outer} returns the outer product of two tensors t1 and t2. Currently
{Outer} work works only for vectors, i.e. tensors of rank 1. The outer
product of two vectors yields a matrix.

*E.G.

	In> Outer({1,2},{3,4,5})
	Out> {{3,4,5},{6,8,10}};
	In> Outer({a,b},{c,d})
	Out> {{a*c,a*d},{b*c,b*d}};

	Or, using the "o"-Operator:

	In> {1,2} o {3,4,5}
	Out> {{3,4,5},{6,8,10}};
	In> {a,b} o {c,d}
	Out> {{a*c,a*d},{b*c,b*d}};


*SEE Dot, Cross






*CMD ZeroVector --- create a vector with all zeroes
*STD
*CALL
	ZeroVector(n)

*PARMS

{n} -- length of the vector to return

*DESC

This command returns a vector of length "n", filled with zeroes.

*E.G.

	In> ZeroVector(4)
	Out> {0,0,0,0};

*SEE BaseVector, ZeroMatrix, IsZeroVector

*CMD BaseVector --- base vector
*STD
*CALL
	BaseVector(k, n)

*PARMS

{k} -- index of the base vector to construct

{n} -- dimension of the vector

*DESC

This command returns the "k"-th base vector of dimension "n". This
is a vector of length "n" with all zeroes except for the "k"-th
entry, which contains a 1.

*E.G.

	In> BaseVector(2,4)
	Out> {0,1,0,0};

*SEE ZeroVector, Identity

*CMD Identity --- make identity matrix
*STD
*CALL
	Identity(n)

*PARMS

{n} -- size of the matrix

*DESC

This commands returns the identity matrix of size "n" by "n". This
matrix has ones on the diagonal while the other entries are zero.

*E.G.

	In> Identity(3)
	Out> {{1,0,0},{0,1,0},{0,0,1}};

*SEE BaseVector, ZeroMatrix, DiagonalMatrix

*CMD ZeroMatrix --- make a zero matrix
*STD
*CALL
	ZeroMatrix(n)
	ZeroMatrix(n, m)

*PARMS

{n} -- number of rows

{m} -- number of columns

*DESC

This command returns a matrix with {n} rows and {m} columns,
completely filled with zeroes. If only given one parameter,
it returns the square {n} by {n} zero matrix.

*E.G.

	In> ZeroMatrix(3,4)
	Out> {{0,0,0,0},{0,0,0,0},{0,0,0,0}};
	In> ZeroMatrix(3)
	Out> {{0,0,0},{0,0,0},{0,0,0}};


*SEE ZeroVector, Identity

*CMD Diagonal --- extract the diagonal from a matrix
*STD
*CALL
	Diagonal(A)

*PARMS

{A} -- matrix

*DESC

This command returns a vector of the diagonal components
of the matrix {A}.


*E.G.

	In> Diagonal(5*Identity(4))
	Out> {5,5,5,5};
	In> Diagonal(HilbertMatrix(3))
	Out> {1,1/3,1/5};

*SEE DiagonalMatrix, IsDiagonal

*CMD DiagonalMatrix --- construct a diagonal matrix
*STD
*CALL
	DiagonalMatrix(d)

*PARMS

{d} -- list of values to put on the diagonal

*DESC

This command constructs a diagonal matrix, that is a square matrix
whose off-diagonal entries are all zero. The elements of the vector
"d" are put on the diagonal.

*E.G.

	In> DiagonalMatrix(1 .. 4)
	Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}};

*SEE Identity, ZeroMatrix

*CMD OrthogonalBasis --- create an orthogonal basis 
*STD
*CALL
	OrthogonalBasis(W)

*PARMS

{W} - A linearly independent set of row vectors (aka a matrix)

*DESC

Given a linearly independent set {W} (constructed of rows vectors),
this command returns an orthogonal basis {V} for {W}, which means 
that span(V) = span(W) and {InProduct(V[i],V[j]) = 0} when {i != j}.
This function uses the Gram-Schmidt orthogonalization process.

*E.G.

	In> OrthogonalBasis({{1,1,0},{2,0,1},{2,2,1}}) 
	Out> {{1,1,0},{1,-1,1},{-1/3,1/3,2/3}};


*SEE OrthonormalBasis, InProduct

*CMD OrthonormalBasis --- create an orthonormal basis 
*STD
*CALL
	OrthonormalBasis(W)

*PARMS

{W} - A linearly independent set of row vectors (aka a matrix)

*DESC

Given a linearly independent set {W} (constructed of rows vectors),
this command returns an orthonormal basis {V} for {W}. This is done
by first using {OrthogonalBasis(W)}, then dividing each vector by its
magnitude, so as the give them unit length. 

*E.G.

	In> OrthonormalBasis({{1,1,0},{2,0,1},{2,2,1}})
	Out> {{Sqrt(1/2),Sqrt(1/2),0},{Sqrt(1/3),-Sqrt(1/3),Sqrt(1/3)},
		{-Sqrt(1/6),Sqrt(1/6),Sqrt(2/3)}};

*SEE OrthogonalBasis, InProduct, Normalize




*CMD Normalize --- normalize a vector
*STD
*CALL
	Normalize(v)

*PARMS

{v} -- a vector

*DESC

Return the normalized (unit) vector parallel to {v}: a vector having the same
direction but with length 1.

*E.G.

	In> v:=Normalize({3,4})
	Out> {3/5,4/5};
	In> v . v
	Out> 1;

*SEE InProduct, CrossProduct

*CMD Transpose --- get transpose of a matrix
*STD
*CALL
	Transpose(M)

*PARMS

{M} -- a matrix

*DESC

{Transpose} returns the transpose of a matrix $M$. Because matrices are
just lists of lists, this is a useful operation too for lists.

*E.G.

	In> Transpose({{a,b}})
	Out> {{a},{b}};

*CMD Determinant --- determinant of a matrix
*STD
*CALL
	Determinant(M)

*PARMS

{M} -- a matrix

*DESC

Returns the determinant of a matrix M.

*E.G.

	In> A:=DiagonalMatrix(1 .. 4)
	Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}};
	In> Determinant(A)
	Out> 24;

*CMD Trace --- trace of a matrix
*STD
*CALL
	Trace(M)

*PARMS

{M} -- a matrix

*DESC

{Trace} returns the trace of a matrix $M$ (defined as the sum of the
elements on the diagonal of the matrix).

*E.G.

	In> A:=DiagonalMatrix(1 .. 4)
	Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}};
	In> Trace(A)
	Out> 10;

*CMD Inverse --- get inverse of a matrix
*STD
*CALL
	Inverse(M)

*PARMS

{M} -- a matrix

*DESC

Inverse returns the inverse of matrix $M$. The determinant of $M$ should
be non-zero. Because this function uses {Determinant} for calculating
the inverse of a matrix, you can supply matrices with non-numeric (symbolic)
matrix elements.

*E.G.

	In> A:=DiagonalMatrix({a,b,c})
	Out> {{a,0,0},{0,b,0},{0,0,c}};
	In> B:=Inverse(A)
	Out> {{(b*c)/(a*b*c),0,0},{0,(a*c)/(a*b*c),0},
	{0,0,(a*b)/(a*b*c)}};
	In> Simplify(B)
	Out> {{1/a,0,0},{0,1/b,0},{0,0,1/c}};

*SEE Determinant

*CMD Minor --- get principal minor of a matrix
*STD
*CALL
	Minor(M,i,j)

*PARMS

{M} -- a matrix

{i}, {j} - positive integers

*DESC

Minor returns the minor of a matrix around
the element ($i$, $j$). The minor is the determinant of the matrix obtained from $M$ by
deleting the $i$-th row and the $j$-th column.

*E.G.

	In> A := {{1,2,3}, {4,5,6}, {7,8,9}};
	Out> {{1,2,3},{4,5,6},{7,8,9}};
	In> PrettyForm(A);
	
	/                    \
	| ( 1 ) ( 2 ) ( 3 )  |
	|                    |
	| ( 4 ) ( 5 ) ( 6 )  |
	|                    |
	| ( 7 ) ( 8 ) ( 9 )  |
	\                    /
	Out> True;
	In> Minor(A,1,2);
	Out> -6;
	In> Determinant({{2,3}, {8,9}});
	Out> -6;

*SEE CoFactor, Determinant, Inverse

*CMD CoFactor --- cofactor of a matrix
*STD
*CALL
	CoFactor(M,i,j)

*PARMS

{M} -- a matrix

{i}, {j} - positive integers

*DESC

{CoFactor} returns the cofactor of a matrix around
the element ($i$, $j$). The cofactor is the minor times
$(-1)^(i+j)$.

*E.G.

	In> A := {{1,2,3}, {4,5,6}, {7,8,9}};
	Out> {{1,2,3},{4,5,6},{7,8,9}};
	In> PrettyForm(A);
	
	/                    \
	| ( 1 ) ( 2 ) ( 3 )  |
	|                    |
	| ( 4 ) ( 5 ) ( 6 )  |
	|                    |
	| ( 7 ) ( 8 ) ( 9 )  |
	\                    /
	Out> True;
	In> CoFactor(A,1,2);
	Out> 6;
	In> Minor(A,1,2);
	Out> -6;
	In> Minor(A,1,2) * (-1)^(1+2);
	Out> 6;

*SEE Minor, Determinant, Inverse


*CMD MatrixPower --- get nth power of a square matrix
*STD
*CALL
	MatrixPower(mat,n)

*PARMS

{mat} -- a square matrix

{n} -- an integer

*DESC

{MatrixPower(mat,n)} returns the {n}th power of a square matrix {mat}. For
positive {n} it evaluates dot products of {mat} with itself. For negative
{n} the nth power of the inverse of {mat} is returned. For {n}=0 the identity
matrix is returned.

*EG
	In> A:={{1,2},{3,4}}
	Out> {{1,2},{3,4}};
	In> MatrixPower(A,0)
	Out> {{1,0},{0,1}};
	In> MatrixPower(A,1)
	Out> {{1,2},{3,4}};
	In> MatrixPower(A,3)
	Out> {{37,54},{81,118}};
	In> MatrixPower(A,-3)
	Out> {{-59/4,27/4},{81/8,-37/8}};

*SEE IsSquareMatrix, Inverse, Dot


*CMD SolveMatrix --- solve a linear system
*STD
*CALL
	SolveMatrix(M,v)

*PARMS

{M} -- a matrix

{v} -- a vector

*DESC

{SolveMatrix} returns the vector $x$ that satisfies
the equation $M*x = v$. The determinant of $M$ should be non-zero.

*E.G.

	In> A := {{1,2}, {3,4}};
	Out> {{1,2},{3,4}};
	In> v := {5,6};
	Out> {5,6};
	In> x := SolveMatrix(A, v);
	Out> {-4,9/2};
	In> A * x;
	Out> {5,6};

*SEE Inverse, Solve, PSolve, Determinant

*CMD CharacteristicEquation --- get characteristic polynomial of a matrix
*STD
*CALL
	CharacteristicEquation(matrix,var)

*PARMS

{matrix} -- a matrix

{var} -- a free variable

*DESC

CharacteristicEquation
returns the characteristic equation of "matrix", using
"var". The zeros of this equation are the eigenvalues
of the matrix, Det(matrix-I*var);

*E.G.

	In> A:=DiagonalMatrix({a,b,c})
	Out> {{a,0,0},{0,b,0},{0,0,c}};
	In> B:=CharacteristicEquation(A,x)
	Out> (a-x)*(b-x)*(c-x);
	In> Expand(B,x)
	Out> (b+a+c)*x^2-x^3-((b+a)*c+a*b)*x+a*b*c;

*SEE EigenValues, EigenVectors

*CMD EigenValues --- get eigenvalues of a matrix
*STD
*CALL
	EigenValues(matrix)

*PARMS

{matrix} -- a square matrix

*DESC

EigenValues returns the eigenvalues of a matrix.
The eigenvalues x of a matrix M are the numbers such that
$M*v=x*v$ for some vector.

It first determines the characteristic equation, and then factorizes this
equation, returning the roots of the characteristic equation
Det(matrix-x*identity).

*E.G.

	In> M:={{1,2},{2,1}}
	Out> {{1,2},{2,1}};
	In> EigenValues(M)
	Out> {3,-1};

*SEE EigenVectors, CharacteristicEquation

*CMD EigenVectors --- get eigenvectors of a matrix
*STD
*CALL
	EigenVectors(A,eigenvalues)

*PARMS

{matrix} -- a square matrix

{eigenvalues} -- list of eigenvalues as returned by {EigenValues}

*DESC

{EigenVectors} returns a list of the eigenvectors of a matrix.
It uses the eigenvalues and the matrix to set up n equations with
n unknowns for each eigenvalue, and then calls {Solve} to determine
the values of each vector.

*E.G.

	In> M:={{1,2},{2,1}}
	Out> {{1,2},{2,1}};
	In> e:=EigenValues(M)
	Out> {3,-1};
	In> EigenVectors(M,e)
	Out> {{-ki2/ -1,ki2},{-ki2,ki2}};

*SEE EigenValues, CharacteristicEquation




*CMD Sparsity --- get the sparsity of a matrix
*STD
*CALL
	Sparsity(matrix)
*PARMS

{matrix} -- a matrix

*DESC

The function {Sparsity} returns a number between {0} and {1} which 
represents the percentage of zero entries in the matrix. Although
there is no definite critical value, a sparsity of {0.75}  or more
is almost universally considered a "sparse" matrix. These type of
matrices can be handled in a different manner than "full" matrices
which speedup many calculations by orders of magnitude.

*E.G.

	In> Sparsity(Identity(2))
	Out> 0.5;
	In> Sparsity(Identity(10))
	Out> 0.9;
	In> Sparsity(HankelMatrix(10))
	Out> 0.45;
	In> Sparsity(HankelMatrix(100))
	Out> 0.495;
	In> Sparsity(HilbertMatrix(10))
	Out> 0;
	In> Sparsity(ZeroMatrix(10,10))
	Out> 1;


*CMD Cholesky --- find the Cholesky Decomposition
*STD
*CALL
	Cholesky(A)

*PARMS

{A} -- a square positive definite matrix

*DESC

{Cholesky} returns a upper triangular matrix {R} such that {Transpose(R)*R = A}.
The matrix {A} must be positive definite, {Cholesky} will notify the user if the matrix
is not. Some families of positive definite matrices are all symmetric matrices, diagonal
matrices with positive elements and Hilbert matrices.

*E.G.

	In> A:={{4,-2,4,2},{-2,10,-2,-7},{4,-2,8,4},{2,-7,4,7}}
	Out> {{4,-2,4,2},{-2,10,-2,-7},{4,-2,8,4},{2,-7,4,7}};
	In> R:=Cholesky(A);
	Out> {{2,-1,2,1},{0,3,0,-2},{0,0,2,1},{0,0,0,1}};
	In> Transpose(R)*R = A
	Out> True;
	In> Cholesky(4*Identity(5))
	Out> {{2,0,0,0,0},{0,2,0,0,0},{0,0,2,0,0},{0,0,0,2,0},{0,0,0,0,2}};
	In> Cholesky(HilbertMatrix(3))
	Out> {{1,1/2,1/3},{0,Sqrt(1/12),Sqrt(1/12)},{0,0,Sqrt(1/180)}};
	In> Cholesky(ToeplitzMatrix({1,2,3}))
	In function "Check" :
	CommandLine(1) : "Cholesky: Matrix is not positive definite"

*SEE IsSymmetric, IsDiagonal, Diagonal


			Predicates related to matrices


*CMD IsScalar --- test for a scalar
*STD
*CALL

	IsScalar(expr)

*PARMS

{expr} -- a mathematical object

*DESC

{IsScalar} returns {True} if {expr} is a scalar, {False} otherwise.
Something is considered to be a scalar if it's not a list.

*E.G.
	In> IsScalar(7)
	Out> True;
	In> IsScalar(Sin(x)+x)
	Out> True;
	In> IsScalar({x,y})
	Out> False;

*SEE IsList, IsVector, IsMatrix


*CMD IsVector --- test for a vector
*STD
*CALL

	IsVector(expr)

	IsVector(pred,expr)

*PARMS

{expr} -- expression to test

{pred} -- predicate test (e.g. IsNumber, IsInteger, ...)

*DESC

{IsVector(expr)} returns {True} if {expr} is a vector, {False} otherwise.
Something is considered to be a vector if it's a list of scalars.
{IsVector(pred,expr)} returns {True} if {expr} is a vector and if the
predicate test {pred} returns {True} when applied to every element of
the vector {expr}, {False} otherwise.

*E.G.
	In> IsVector({a,b,c})
	Out> True;
	In> IsVector({a,{b},c})
	Out> False;
	In> IsVector(IsInteger,{1,2,3})
	Out> True;
	In> IsVector(IsInteger,{1,2.5,3})
	Out> False;

*SEE IsList, IsScalar, IsMatrix


*CMD IsMatrix --- test for a matrix
*STD
*CALL
	IsMatrix(expr)

	IsMatrix(pred,expr)

*PARMS

{expr} -- expression to test

{pred} -- predicate test (e.g. IsNumber, IsInteger, ...)

*DESC

{IsMatrix(expr)} returns {True} if {expr} is a matrix, {False} otherwise.
Something is considered to be a matrix if it's a list of vectors of equal
length.
{IsMatrix(pred,expr)} returns {True} if {expr} is a matrix and if the
predicate test {pred} returns {True} when applied to every element of
the matrix {expr}, {False} otherwise.

*E.G.

	In> IsMatrix(1)
	Out> False;
	In> IsMatrix({1,2})
	Out> False;
	In> IsMatrix({{1,2},{3,4}})
	Out> True;
	In> IsMatrix(IsRational,{{1,2},{3,4}})
	Out> False;
	In> IsMatrix(IsRational,{{1/2,2/3},{3/4,4/5}})
	Out> True;

*SEE IsList, IsVector


*CMD IsSquareMatrix --- test for a square matrix
*STD
*CALL
	IsSquareMatrix(expr)

	IsSquareMatrix(pred,expr)

*PARMS

{expr} -- expression to test

{pred} -- predicate test (e.g. IsNumber, IsInteger, ...)

*DESC

{IsSquareMatrix(expr)} returns {True} if {expr} is a square matrix,
{False} otherwise. Something is considered to be a square matrix if
it's a matrix having the same number of rows and columns.
{IsMatrix(pred,expr)} returns {True} if {expr} is a square matrix and
if the predicate test {pred} returns {True} when applied to every
element of the matrix {expr}, {False} otherwise.

*E.G.

	In> IsSquareMatrix({{1,2},{3,4}});
	Out> True;
	In> IsSquareMatrix({{1,2,3},{4,5,6}});
	Out> False;
	In> IsSquareMatrix(IsBoolean,{{1,2},{3,4}});
	Out> False;
	In> IsSquareMatrix(IsBoolean,{{True,False},{False,True}});
	Out> True;

*SEE IsMatrix

*CMD IsHermitian --- test for a Hermitian matrix
*STD
*CALL
	IsHermitian(A)

*PARMS

{A} -- a square matrix

*DESC

IsHermitian(A) returns {True} if {A} is Hermitian and {False}
otherwise. $A$ is a Hermitian matrix iff Conjugate( Transpose $A$ )=$A$.
If $A$ is a real matrix, it must be symmetric to be Hermitian.

*E.G.

	In> IsHermitian({{0,I},{-I,0}})
	Out> True;
	In> IsHermitian({{0,I},{2,0}})
	Out> False;

*SEE IsUnitary

*CMD IsOrthogonal --- test for an orthogonal matrix
*STD
*CALL
	IsOrthogonal(A)

*PARMS

{A} -- square matrix

*DESC

{IsOrthogonal(A)} returns {True} if {A} is orthogonal and {False} 
otherwise. $A$ is orthogonal iff $A$*Transpose($A$) = Identity, or
equivalently Inverse($A$) = Transpose($A$).

*E.G.

	In> A := {{1,2,2},{2,1,-2},{-2,2,-1}};
	Out> {{1,2,2},{2,1,-2},{-2,2,-1}};
	In> PrettyForm(A/3)

	/                      \
	| / 1 \  / 2 \ / 2 \   |
	| | - |  | - | | - |   |
	| \ 3 /  \ 3 / \ 3 /   |
	|                      |
	| / 2 \  / 1 \ / -2 \  |
	| | - |  | - | | -- |  |
	| \ 3 /  \ 3 / \ 3  /  |
	|                      |
	| / -2 \ / 2 \ / -1 \  |
	| | -- | | - | | -- |  |
	| \ 3  / \ 3 / \ 3  /  |
	\                      /
	Out> True;
	In> IsOrthogonal(A/3)
	Out> True;

*CMD IsDiagonal --- test for a diagonal matrix
*STD
*CALL
	IsDiagonal(A)

*PARMS

{A} -- a matrix

*DESC

{IsDiagonal(A)} returns {True} if {A} is a diagonal square matrix and {False} otherwise.

*E.G.
	In> IsDiagonal(Identity(5))
	Out> True;
	In> IsDiagonal(HilbertMatrix(5))
	Out> False;

*CMD IsLowerTriangular --- test for a lower triangular matrix
*CMD IsUpperTriangular --- test for an upper triangular matrix
*STD
*CALL
	IsLowerTriangular(A)
	IsUpperTriangular(A)

*PARMS

{A} -- a matrix

*DESC

A lower/upper triangular matrix is a square matrix which has all zero entries above/below the diagonal.

{IsLowerTriangular(A)} returns {True} if {A} is a lower triangular matrix and {False} otherwise.
{IsUpperTriangular(A)} returns {True} if {A} is an upper triangular matrix and {False} otherwise.

*E.G.
	In> IsUpperTriangular(Identity(5))
	Out> True;
	In> IsLowerTriangular(Identity(5))
	Out> True;
	In> IsLowerTriangular({{1,2},{0,1}})
	Out> False;
	In> IsUpperTriangular({{1,2},{0,1}})
	Out> True;
A non-square matrix cannot be triangular:
	In> IsUpperTriangular({{1,2,3},{0,1,2}})
	Out> False;

*SEE IsDiagonal

*CMD IsSymmetric --- test for a symmetric matrix
*STD
*CALL
	IsSymmetric(A)

*PARMS

{A} -- a matrix

*DESC

{IsSymmetric(A)} returns {True} if {A} is symmetric and {False} otherwise.
$A$ is symmetric iff Transpose ($A$) =$A$.

*E.G.

	In> A := {{1,0,0,0,1},{0,2,0,0,0},{0,0,3,0,0},
	  {0,0,0,4,0},{1,0,0,0,5}};
	In> PrettyForm(A)

	/                                \
	| ( 1 ) ( 0 ) ( 0 ) ( 0 ) ( 1 )  |
	|                                |
	| ( 0 ) ( 2 ) ( 0 ) ( 0 ) ( 0 )  |
	|                                |
	| ( 0 ) ( 0 ) ( 3 ) ( 0 ) ( 0 )  |
	|                                |
	| ( 0 ) ( 0 ) ( 0 ) ( 4 ) ( 0 )  |
	|                                |
	| ( 1 ) ( 0 ) ( 0 ) ( 0 ) ( 5 )  |
	\                                /
	Out> True;
	In> IsSymmetric(A)
	Out> True;
		

*SEE IsHermitian, IsSkewSymmetric

*CMD IsSkewSymmetric --- test for a skew-symmetric matrix
*STD
*CALL
	IsSkewSymmetric(A)

*PARMS

{A} -- a square matrix

*DESC

{IsSkewSymmetric(A)} returns {True} if {A} is skew symmetric and {False} otherwise.
$A$ is skew symmetric iff $Transpose(A)$ =$-A$. 

*E.G.

	In> A := {{0,-1},{1,0}}
	Out> {{0,-1},{1,0}};
	In> PrettyForm(%)

	/               \
	| ( 0 ) ( -1 )  |
	|               |
	| ( 1 ) ( 0 )   |
	\               /
	Out> True;
	In> IsSkewSymmetric(A);
	Out> True;

*SEE IsSymmetric, IsHermitian
 
*CMD IsUnitary --- test for a unitary matrix
*STD
*CALL
	IsUnitary(A)

*PARMS

{A} -- a square matrix

*DESC

This function tries to find out if A is unitary.

A matrix $A$ is orthogonal iff $A^(-1)$ = Transpose( Conjugate($A$) ). This is
equivalent to the fact that the columns of $A$ build an orthonormal system
(with respect to the scalar product defined by {InProduct}).

*E.G.

	In> IsUnitary({{0,I},{-I,0}})
	Out> True;
	In> IsUnitary({{0,I},{2,0}})
	Out> False;

*SEE IsHermitian, IsSymmetric

*CMD IsIdempotent --- test for an idempotent matrix
*STD
*CALL
	IsIdempotent(A)

*PARMS

{A} -- a square matrix

*DESC

{IsIdempotent(A)} returns {True} if {A} is idempotent and {False} otherwise.
$A$ is idempotent iff $A^2=A$. Note that this also implies that $A$ raised
to any power is also equal to $A$.

*E.G.

	In> IsIdempotent(ZeroMatrix(10,10));
	Out> True;
	In> IsIdempotent(Identity(20))
	Out> True;


			Special matrices


*CMD JacobianMatrix --- calculate the Jacobian matrix of $n$ functions in $n$ variables
*STD
*CALL
	JacobianMatrix(functions,variables)

*PARMS

{functions} -- an $n$-dimensional vector of functions

{variables} -- an $n$-dimensional vector of variables

*DESC

The function {JacobianMatrix} calculates the Jacobian matrix
of n functions in n variables.

The ($i$,$j$)-th element of the Jacobian matrix is defined as the derivative
of $i$-th function with respect to the $j$-th variable.

*E.G.

	In> JacobianMatrix( {Sin(x),Cos(y)}, {x,y} ); 
	Out> {{Cos(x),0},{0,-Sin(y)}};
	In> PrettyForm(%)

	/                                 \
	| ( Cos( x ) ) ( 0 )              |
	|                                 |
	| ( 0 )        ( -( Sin( y ) ) )  |
	\                                 /


*CMD VandermondeMatrix --- create the Vandermonde matrix
*STD
*CALL
	VandermondeMatrix(vector)
*PARMS

{vector} -- an $n$-dimensional vector 

*DESC

The function {VandermondeMatrix} calculates the Vandermonde matrix
of a vector.

The ($i$,$j$)-th element of the Vandermonde matrix is defined as $i^(j-1)$.

*E.G.
	In> VandermondeMatrix({1,2,3,4})
	Out> {{1,1,1,1},{1,2,3,4},{1,4,9,16},{1,8,27,64}};
	In>PrettyForm(%)

	/                            \
	| ( 1 ) ( 1 ) ( 1 )  ( 1 )   |
	|                            |
	| ( 1 ) ( 2 ) ( 3 )  ( 4 )   |
	|                            |
	| ( 1 ) ( 4 ) ( 9 )  ( 16 )  |
	|                            |
	| ( 1 ) ( 8 ) ( 27 ) ( 64 )  |
	\                            /

*CMD HessianMatrix --- create the Hessian matrix
*STD
*CALL
	HessianMatrix(function,var)
*PARMS

{function} -- a function in $n$ variables

{var} -- an $n$-dimensional vector of variables

*DESC

The function {HessianMatrix} calculates the Hessian matrix
of a vector.

If $f(x)$ is a function of an $n$-dimensional vector $x$, then the ($i$,$j$)-th element of the Hessian matrix of the function $f(x)$ is defined as 
$ Deriv(x[i]) Deriv(x[j]) f(x) $. If the third
order mixed partials are continuous, then the Hessian
matrix is symmetric (a standard theorem of calculus).

The Hessian matrix is used in the second derivative test 
to discern if a critical point is a local maximum, a local
minimum or a saddle point.


*E.G.

	In> HessianMatrix(3*x^2-2*x*y+y^2-8*y, {x,y} )
	Out> {{6,-2},{-2,2}};
	In> PrettyForm(%)

	/                \
	| ( 6 )  ( -2 )  |
	|                |
	| ( -2 ) ( 2 )   |
	\                /


*CMD HilbertMatrix --- create a Hilbert matrix
*STD
*CALL
	HilbertMatrix(n)
	HilbertMatrix(n,m)
*PARMS

{n,m} -- positive integers

*DESC

The function {HilbertMatrix} returns the {n} by {m} Hilbert matrix
if given two arguments, and the square {n} by {n} Hilbert matrix
if given only one. The Hilbert matrix is defined as {A(i,j) = 1/(i+j-1)}.
The Hilbert matrix is extremely sensitive to manipulate and invert numerically.

*E.G.

	In> PrettyForm(HilbertMatrix(4))

	/                          \
	| ( 1 ) / 1 \ / 1 \ / 1 \  |
	|       | - | | - | | - |  |
	|       \ 2 / \ 3 / \ 4 /  |
	|                          |
	| / 1 \ / 1 \ / 1 \ / 1 \  |
	| | - | | - | | - | | - |  |
	| \ 2 / \ 3 / \ 4 / \ 5 /  |
	|                          |
	| / 1 \ / 1 \ / 1 \ / 1 \  |
	| | - | | - | | - | | - |  |
	| \ 3 / \ 4 / \ 5 / \ 6 /  |
	|                          |
	| / 1 \ / 1 \ / 1 \ / 1 \  |
	| | - | | - | | - | | - |  |
	| \ 4 / \ 5 / \ 6 / \ 7 /  |
	\                          /

*SEE HilbertInverseMatrix

*CMD HilbertInverseMatrix --- create a Hilbert inverse matrix
*STD
*CALL
	HilbertInverseMatrix(n)
*PARMS

{n} -- positive integer

*DESC

The function {HilbertInverseMatrix} returns the {n} by {n} inverse of the
corresponding Hilbert matrix. All Hilbert inverse matrices have integer
entries that grow in magnitude rapidly.

*E.G.
	In> PrettyForm(HilbertInverseMatrix(4))

	/                                         \
	| ( 16 )   ( -120 )  ( 240 )   ( -140 )   |
	|                                         |
	| ( -120 ) ( 1200 )  ( -2700 ) ( 1680 )   |
	|                                         |
	| ( 240 )  ( -2700 ) ( 6480 )  ( -4200 )  |
	|                                         |
	| ( -140 ) ( 1680 )  ( -4200 ) ( 2800 )   |
	\                                         /

*SEE HilbertMatrix


*CMD ToeplitzMatrix --- create a Toeplitz matrix
*STD
*CALL
	ToeplitzMatrix(N)
*PARMS

{N} -- an $n$-dimensional row vector

*DESC

The function {ToeplitzMatrix} calculates the Toeplitz matrix given
an $n$-dimensional row vector. This matrix has the same entries in
all diagonal columns, from upper left to lower right.

*E.G.

	In> PrettyForm(ToeplitzMatrix({1,2,3,4,5}))

	/                                \
	| ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 )  |
	|                                |
	| ( 2 ) ( 1 ) ( 2 ) ( 3 ) ( 4 )  |
	|                                |
	| ( 3 ) ( 2 ) ( 1 ) ( 2 ) ( 3 )  |
	|                                |
	| ( 4 ) ( 3 ) ( 2 ) ( 1 ) ( 2 )  |
	|                                |
	| ( 5 ) ( 4 ) ( 3 ) ( 2 ) ( 1 )  |
	\                                /


*CMD WronskianMatrix --- create the Wronskian matrix
*STD
*CALL
	WronskianMatrix(func,var)
*PARMS

{func} -- an $n$-dimensional vector of functions

{var} -- a variable to differentiate with respect to

*DESC

The function {WronskianMatrix} calculates the Wronskian matrix
of $n$ functions.

The Wronskian matrix is created by putting each function as the
first element of each column, and filling in the rest of each
column by the ($i-1$)-th derivative, where $i$ is the current row.

The Wronskian matrix is used to verify that the $n$ functions are linearly
independent, usually solutions to a differential equation.
If the determinant of the Wronskian matrix is zero, then the functions
are dependent, otherwise they are independent.

*E.G.
	In> WronskianMatrix({Sin(x),Cos(x),x^4},x);
	Out> {{Sin(x),Cos(x),x^4},{Cos(x),-Sin(x),4*x^3},
	  {-Sin(x),-Cos(x),12*x^2}};
	In> PrettyForm(%)

	/                                                 \
	| ( Sin( x ) )      ( Cos( x ) )      /  4 \      |
	|                                     \ x  /      |
	|                                                 |
	| ( Cos( x ) )      ( -( Sin( x ) ) ) /      3 \  |
	|                                     \ 4 * x  /  |
	|                                                 |
	| ( -( Sin( x ) ) ) ( -( Cos( x ) ) ) /       2 \ |
	|                                     \ 12 * x  / |
	\                                                 /
The last element is a linear combination of the first two, so the determinant is zero:
	In> A:=Determinant( WronskianMatrix( {x^4,x^3,2*x^4 
	  + 3*x^3},x ) )
	Out> x^4*3*x^2*(24*x^2+18*x)-x^4*(8*x^3+9*x^2)*6*x
	  +(2*x^4+3*x^3)*4*x^3*6*x-4*x^6*(24*x^2+18*x)+x^3
	  *(8*x^3+9*x^2)*12*x^2-(2*x^4+3*x^3)*3*x^2*12*x^2;
	In> Simplify(A)
	Out> 0;


*CMD SylvesterMatrix --- calculate the Sylvester matrix of two polynomials
*STD
*CALL
	SylvesterMatrix(poly1,poly2,variable)

*PARMS

{poly1} -- polynomial

{poly2} -- polynomial

{variable} -- variable to express the matrix for

*DESC

The function {SylvesterMatrix} calculates the Sylvester matrix
for a pair of polynomials.

The Sylvester matrix is closely related to the resultant, which
is defined as the determinant of the Sylvester matrix. Two polynomials
share common roots only if the resultant is zero.

*E.G.

	In> ex1:= x^2+2*x-a
	Out> x^2+2*x-a;
	In> ex2:= x^2+a*x-4
	Out> x^2+a*x-4;
	In> A:=SylvesterMatrix(ex1,ex2,x)
	Out> {{1,2,-a,0},{0,1,2,-a},
	  {1,a,-4,0},{0,1,a,-4}};
	In> B:=Determinant(A)
	Out> 16-a^2*a- -8*a-4*a+a^2- -2*a^2-16-4*a;
	In> Simplify(B)
	Out> 3*a^2-a^3;

The above example shows that the two polynomials have common
zeros if $ a = 3 $.

*SEE Determinant, Simplify, Solve, PSolve

