MATRICES AND MATRIX OPERATIONS: Unit 1
Dr. Wlodzislaw Kostecki
The Papua New Guinea University of Technology (PNGUT)
Department of Electrical and Communication Engineering
Lae, Morobe Province
Papua New Guinea
Copyright 2000 by Wlodzislaw Kostecki
All rights reserved
-------------------------------------------------------------------
(1)
Introduction
OBJECTIVES
:
To provide a collection of the necessary definitions of, and concepts associated with, matrices.
To present notational conventions adopted for all the Units.
To introduce
Maple
s library package
linalg
containing functions required for matrix operations.
To introduce the concepts of a
one-dimensional list
or
array
and
two-dimensional list
or
list of lists
.
To introduce
Maple
s type-checking function
type
and the
Boolean
values
and
returned by it.
To show alternative methods of defining and inputting matrices with
Maple
.
To illustrate methods of creating matrices whose elements depend on their location in a matrix.
To show alternative methods of substituting data for matrix elements.
To show alternative methods of evaluation of matrices entered with symbolic elements whose numerical values become known in a later phase of computation.
To introduce the rule of
last-name evaluation
used by
Maple
as applied to matrices and illustrate its implications.
To specify the functions from outside of the
linalg
package, which are contained in
Maple
s
main
library and are able to perform operations on matrices.
To present alternative methods of unassigning a matrix structure from a name.
1.1
Basic definitions and notational conventions
A matrix is an ordered or systematic
(
rectangular
)
array
of
scalars
, called
elements
, which are arranged in
rows and
columns and enclosed in brackets. Such a matrix is said to be of order (or size, or dimension)
(
)
(
read:
by
)
.
The elements of a matrix are double-subscripted to denote their location in the matrix, the
row
index
preceding the
column
index
. The subscript indices
must
be
natural numbers
, which may or may not be separated by the comma refer to Section 1.2 for more details.
The
scalars
may be
real numbers
,
complex numbers
, or
functions
of some parameter.
A matrix is
real-valued
(
or
real
)
if
all
its elements are
real numbers
or
real-valued functions
. A matrix is
complex-valued
(
or
complex
)
if at least
one
element is a
complex number
or a
complex-valued function
.
If
all
elements of a matrix are
numbers
, whether
real
or
complex
, then it is called a
constant
matrix. If
all
elements of a matrix are
integers
, then it is called an
integer
matrix.
Two matrices are
equal
if they have the same order and their corresponding elements are equal.
A matrix is
square
if the number of rows is equal to the number of columns. Such a matrix is said to be of order
(
)
or
(
)
. A square matrix whose associated determinant is non-vanishing
(
is not
)
is called a
non-singular
matrix.
A matrix containing only
one
column is called a
column matrix
.
Its order is
(
)
. A matrix containing only
one
row is called a
row matrix
. Its order is
(
)
.
N.B.
In textbooks, the names
column vector
and
row vector
are used interchangeably with
column matrix
and
row matrix
, respectively. In
Maple
, the
vector
is a
row
object and is
not
a matrix, and the concept of "column vector" does
not
exist at all refer to Unit (3) for more details.
Operations on matrices are performed using functions and commands contained in a
Maple
library package called
linalg
(
lin
ear
alg
ebra package), which is loaded with the
with
command. The package includes over
functions and procedures.
The
with(linalg)
command is used in every Unit in such a way that the functions necessary for a given Unit are specified, e.g.
with(linalg, det, inverse, multiply, rowdim)
. This results in loading
only
a few functions, not
all
the contents of the package. It should be noted that although the function
matrix
belongs to the
linalg
package, it need not be specified since this function is also included in
Maple
s
main
library.
* * *
NOTE 1:
In textbooks, a matrix is frequently designated by a single boldface capital letter often enclosed in brackets, e.g. [
A
]. Wherever possible, the same notation is used in the text of all the Units. In
Maple
, a matrix is identified by a non-bracketed name, e.g. A. Consequently, in commands found in the Units, most often capitals are used to denote matrices, e.g. A, M, U, V, Z, Y, CM, RM.
Where
functions
of
constant
matrices are involved, such matrices are denoted in text as
cos(
[
A
]
),
ln(
[
A
]
),
etc. Where
functions
of matrices comprising
functions
of a real variable
t
are involved, such matrices are denoted as
sin(
[
A
(
)
]
),
exp(
[
A
(
)
]
),
etc. If mathematical expressions of functions of matrices are involved in text, then the following matrix designations are used:
tan(
A
),
sinh(A(
t
)),
etc.
Where a
function
is applied to all elements of a matrix, such matrices are denoted as
A_exp
,
A_ln
,
A_sin
,
A_sqrt
, etc.
NOTE 2:
Various notational methods are found in textbooks for the names of certain matrices, using the characters
'
(
or
as a superscript
)
and
*
(
or
t
as a subscript or
T
as a superscript
)
to denote the
inverse
and the
transpose
of a matrix, respectively. For all the Units, the following names are adopted for unification and convenience in displaying results:
Abs(
A
)
for the
absolute value
of the elements of a matrix [
A
],
Adj(
A
)
for the
adjoint
of a square matrix [
A
],
Arg(
A
)
for the
principal argument
of the elements of a matrix [
A
],
char_eq(
A
)
for the
characteristic equation
of a square matrix [
A
],
char_poly(
A
)
for the
characteristic polynomial
of a square matrix [
A
],
char_roots(
A
)
for the
characteristic roots
or
eigenvalues
of a square matrix [
A
],
char_vectors(
A
)
for the
characteristic vectors
or
eigenvectors
of a square matrix [
A
],
Cofactor(
)
for the
cofactor
of an element
of a square matrix [
A
],
Cofactor(
A
)
for the
cofactor matrix
associated with a square matrix [
A
],
Conj(
A
)
for the
conjugate
of a complex matrix [
A
],
Det(
A
)
for the
determinant
of a square matrix [
A
],
Inv(
A
)
for the
inverse
of a square non-singular matrix [
A
],
Minor(
)
for the
minor
of an element
of a square matrix [
A
],
roots_and_vectors(
A
)
for the sequence of lists containing
characteristic roots
and
vectors
of a square matrix [
A
],
Trace(
A
)
for the
trace
of a square matrix [
A
],
Transp(
A
)
for the
transpose
of a matrix [
A
].
Moreover, the following auxiliary names are adopted:
Antisym(
A
)
for the
antisymmetric part
of a square matrix [
A
] defined as
(
[
A
]
Transp
[
A
]
)
,
Sym(
A
)
for the
symmetric part
of a square matrix [
A
] defined as
(
[
A
]
+
Transp
[
A
]
)
,
(
A
)
for the
th column of a matrix [
A
],
(
A
)
for the
th row of a matrix [
A
].
(1.2)
Entering matrices and substituting data for matrix elements
>
restart : with(linalg, adjoint, det, entermatrix, orthog, randmatrix, rowdim, transpose) :
In
Maple
, there are several alternative methods of entering matrices and substituting data for matrix elements. An overview of these methods is presented hereunder.
A
.
Defining and inputting matrices
For example, consider a
(
)
matrix [
A
] containing symbolic elements.
Method 1
. Using the
matrix
function, type the matrix elements in brackets containing bracketed elements of each consecutive row:
>
A := matrix([ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ]) : A = matrix(A) ;
N.B.
Equivalent to the above short command is defining first a
two-dimensional list
or
list of lists
, i.e.
>
LL := [ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ] : 'LL' = LL ;
and then, converting it into a matrix using the
convert
and
matrix
functions, viz.
>
A := convert(LL, matrix) : A = matrix(A) ;
Method 2
. Using the
matrix
function, specify the number of matrix rows (e.g.,
2
) followed by the number of columns (e.g.,
3
) and then, type the matrix elements in brackets row-by-row:
>
A := matrix(2, 3, [a[11], a[12], a[13], a[21], a[22], a[23]]) : A = matrix(A) ;
N.B.
Equivalent to the above short command is defining first a
one-dimensional list
or
array
, i.e.
>
L := [a[11], a[12], a[13], a[21], a[22], a[23]] : 'L' = L ;
and then, converting it into a matrix using the
matrix
function, viz.
>
A := matrix(2, 3, L) : A = matrix(A) ;
Method 3
. Using the
array
function, type the array elements in brackets containing bracketed elements of each consecutive row:
>
A := array([ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ]) : A = matrix(A) ;
N.B.
Equivalent to the above short command is defining first a
two-dimensional list
or
list of lists
, i.e.
>
LL := [ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ] : 'LL' = LL ;
and then, converting it into a matrix using the
convert
and
matrix
functions, viz.
>
A := convert(LL, matrix) : A = matrix(A) ;
Method 4
. Using the
array
function, specify the range of array rows (e.g.,
1..2
) followed by the range of columns (e.g.,
1..3
) and then, type the array elements in brackets containing bracketed elements of each consecutive row:
>
A := array(1..2, 1..3, [ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ]) : A = matrix(A) ;
N.B.
Equivalent to the above short command is defining first a
two-dimensional list
or
list of lists
, i.e.
>
LL := [ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ] : 'LL' = LL ;
and then, converting it into a matrix using the
convert
and
matrix
functions, viz.
>
A := convert(LL, matrix) : A = matrix(A) ;
Method 5
. Using the
convert
function, type the elements in brackets containing bracketed elements of each consecutive row and then, convert this two-dimensional structure into a
matrix
:
>
A := convert([ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ], matrix) : A = matrix(A) ;
N.B.
Equivalent to the above short command is defining first a
two-dimensional list
or
list of lists
, i.e.
>
LL := [ [a[11], a[12], a[13]], [a[21], a[22], a[23]] ] : 'LL' = LL ;
and then, converting it into a matrix using the
convert
and
matrix
functions, viz.
>
A := convert(LL, matrix) : A = matrix(A) ;
B.
Substituting data for matrix elements
For example, consider
(
)
matrices [
A
], [
B
], and [
V
], and
(
)
matrix [
E
] to illustrate
non-interactive
methods, and
(
)
matrix [
F
] to illustrate the
interactive
method.
Method 1
. Assign values to matrix elements
prior to
defining a matrix
>
a[11]:=2 : a[12]:=1 : a[13]:=0 : a[21]:=1 : a[22]:=-1 : a[23]:=3 : a[31]:=0 : a[32]:=6 : a[33]:=2 :
and then, define a matrix of desired size using the same symbolic names for its elements:
>
A := matrix([[a[11], a[12], a[13]], [a[21], a[22], a[23]], [a[31], a[32], a[33]]]) : A = matrix(A) ;
N.B.
This method is useful where a set of data is to be presented in the matrix form. To this end, type first the data in a manner indicating that a
two-dimensional ordered structure
is involved, i.e.
>
data_list:=[ [a, b, c], [d, e, f] ] : 'data_list'=data_list ; type(data_list, list) ; type(data_list, listlist) ;
This is a
two-dimensional list
, or
list of lists
, as verified by both
Boolean
values
returned by the type-checking function
type
.
Then, convert the two-dimensional list (list of lists) into a matrix using the
convert
and
matrix
functions, viz.
>
A := convert(data_list, matrix) : A = matrix(A) ;
Method 2
. Declare the name and dimensions of a matrix,
>
B := matrix(3, 3) :
or, equivalently,
>
B := matrix(3, 3, [ ]) : B := array(1..3, 1..3) : B := array(1..3, 1..3, [ ]) :
assign values to its elements,
>
B[1,1]:=-2 : B[1,2]:=3 : B[1,3]:=1 : B[2,1]:=0 : B[2,2]:=3 : B[2,3]:=0 : B[3,1]:=4 : B[3,2]:=5 : B[3,3]:=2 :
and input/display the matrix:
>
B := matrix(B) : B = matrix(B) ;
Notice the difference in the way of assigning values to matrix elements in
Methods 1
and
2
if a capital letter is used as the name of a matrix, viz.
in
Method 1
:
lower-case letters
must
be used for the symbolic indexed matrix elements and the index digits may
not
be separated by the comma.
in
Method 2
:
upper-case letters
must
be used for the symbolic indexed matrix elements and the comma
must
separate the index digits
.
Also notice at this point that matrix names
cannot
be subscripted in the way, which is used in indexing variables, i.e. an attempt to assign a matrix structure to single-indexed names like
B[1]
(
)
or
B[a]
(
)
will result in an error message. Indexing matrix names follows different rules.
Two cases of indexed matrix names should be distinguished.
Case 1
when an indexed name is to be assigned a matrix structure.
A matrix name may
only
be added a subscript, which consists of
two
natural numbers separated by the comma, neither of the numbers being greater than the number of rows or columns, respectively, of a matrix structure assigned to the subscripted name. For example, the following indexed name and matrix assignment are correct:
>
B[2,3] := matrix(2, 3, [b[11], b[12], b[13], b[21], b[22], b[23]]) : B[2,3] = matrix(B[2,3]) ;
Case 2
when an indexed name is
not
to be assigned a matrix structure.
A matrix name may
only
be added a subscript, which consists of
two
strings separated by the coma and
formed by enclosing any sequence of characters in a pair of backquotes. For instance, the following indexed names may be used:
>
B[`(11`,`23)`] = matrix(2, 3, [b[11], b[12], b[13], b[21], b[22], b[23]]) ;
>
B[`(2 rows`,`3 columns)`] = matrix(2, 3, [b[11], b[12], b[13], b[21], b[22], b[23]]) ;
Method 3
. Define a matrix using symbolic names for its elements
>
V := array(1..3, 1..3, [[v[11], v[12], v[13]], [v[21], v[22], v[23]], [v[31], v[32], v[33]]]) :
then use the
subs
function to
subs
titute the symbolic names in the
matrix
function with the given values, and input/display the matrix:
>
V := subs(v[11]=8, v[12]=2, v[13]=1, v[21]=1, v[22]=3, v[23]=0, v[31]=4, v[32]=2, v[33]=1, matrix(V)) : V =matrix(V) ;
Method 4
. If a matrix containing functions of symbolic elements has been defined and input, e.g.
>
E := matrix(2, 3, [(3*a-2*b)^2, 1/4*exp(b/a), -2*tan(2*a/(a^2+b^2)), 2*cos(a/b), 4/7*sinh(2*a^2+b), 3/5*a^(-sin(b))]) : E = matrix(E) ;
and numerical data for the symbolic elements are determined and input in a later phase of computations, e.g.
>
a := 1.75 : b := -0.25 : 'a' = a ; 'b' = b ;
then floating-point evaluation of matrix [
E
] may be performed using any of the following alternative methods.
(a) Using the function
map
together with the arrow-type functional operator,
(
x->
)
, and the function
eval
:
>
E = map(x->eval(x), E) ;
(b) Using the functions
evalf
and
subs
together with any of the functions
eval
,
matrix
,or
op
:
>
E = evalf(subs('a'=a, 'b'=b, eval(E))) ; E = evalf(subs('a'=a, 'b'=b, matrix(E))) ; E = evalf(subs('a'=a, 'b'=b, op(E))) ;
Notice the single unevaluation quotes that
must
surround each data
name
in method (b).
Method 5
. This is an
interactive
method, which uses the
entermatrix
function prompting the user to enter the number of element values equal to the number of symbolic elements in a pre-defined matrix.
Step 1
. Define a matrix using symbolic names for its elements:
>
F := matrix(2, 2, [f[11], f[12], f[21], f[22]]) : F = matrix(F) ;
Step 2
. Enter values (numerical or symbolic) of the elements of [
F
] given, for instance, as
,
,
,
.
The values entered
must
be terminated with the semi-colon
.
>
F := entermatrix(F) :
enter element 1,1 >
-2;
enter element 1,2 >
3;
enter element 2,1 >
4;
enter element 2,2 >
6;
Step 3
. Input/display the matrix containing the values entered:
>
F = matrix(F) ;
* * *
N.B.
Matrices whose elements are to be a function of the element location, i.e.
may be created using either of the following alternative methods.
For example, create a
(
)
matrix [
A
] whose elements are given by the function
Method 1
. Using the double
for
-loop construct:
>
A := array(1..4, 1..5) : for i to 4 do for j to 5 do A[i,j] := 2*i^3 - 3*j^2 : od : od :
>
A := matrix(A) : A = matrix(A) ;
Method 2
. Using the special call
matrix(m, n, fnc)
and
Maple
s arrow-type definition of the function
fnc
acting on the locations
(
i
,
j
):
>
fnc := (i, j) -> 2*i^3 - 3*j^2 : A := matrix(4, 5, fnc) : A = matrix(A) ;
* * *
N.B.
If
all
the symbolic or numerical elements of a pre-defined and input matrix are to be substituted with (overwritten by) the same
integer
, then using the
map
and
op
functions is the simplest way. For instance, substitute all elements of the above matrix [
A
] with the integer
:
>
A := map(op(12), A) : A = matrix(A) ;
* * *
N.B.
If
all
the symbolic or numerical elements of a matrix are to be substituted with (overwritten by) an arbitrary non-integer
real
or
complex number
, some
symbolic
element, or
function
of a real variable or complex number, the
map
function together with the arrow-type functional operator,
(
x->
)
, should be used. For instance, substitute all elements of the above matrix [
A
] with the result of the product
:
>
A := map(x -> 2*I*cos(1.27), A) : A = matrix(A) ;
* * *
N.B.
For creating example matrices, the
randmatrix
function may be used, which returns an
(
)
matrix with random integers from the interval
.
For example, create a
(
)
matrix [
R
] with random entries.
>
R := randmatrix(3, 4) : R = matrix(R) ;
An optional argument may be used together with the
randmatrix
function, which will create a special type of random matrix. The option may be
diagonal
,
symmetric
,
antisymmetric
,
sparse
,
unimodular
, or
identity
. Refer to Units (7) and (9) for the definitions of these matrices.
* * *
If
variation
of constants given in the form of symbolic elements of a matrix [
P
]
>
P := matrix(2, 3, [G, H, J, K, N, T]) : P = matrix(P) ;
is to be done, i.e. each element is to be made a function of a single variable
,
,
then the following command should be used:
>
P := P(x) : 'P(x)' = matrix(P) ;
* * *
A matrix [
M
] whose elements are to be a function of a variable
,
which function is to depend on the element location in the matrix may be created using
Maple
s arrow-type definition of the function
fnc
and the special call
matrix(m, n, fnc)
, e.g.
>
fnc := (i, j) -> (3*i - 2*j)*t^(2*i + 3*j) : M(t) := matrix(2, 3, fnc) ;
* * *
N.B.
Unlike in computations where names retain the assigned objects (values, functions, etc.), in
matrix
computations the name assigned a matrix does
not
"carry over" the structure assigned. This means that if the name V has been assigned the matrix [
V
] (as is the case earlier in this Unit), then typing in the name does
not
return the
matrix
but the
variable
name to which it is assigned, i.e.
>
V ;
This special rule used by
Maple
in the evaluation of data structures including
arrays
and
matrices
is called
last-name evaluation
.
Consequently, any operation applied to a matrix name returns a result of a given operation performed on the
variable
used as the matrix name, e.g.
>
V + 1 ; V^2 ;
There are, however, some functions that do not belong to the
linalg
package but will recognise the pre-defined matrix structure assigned to the name and perform the respective operations on the matrix, viz.
Function
copy
that duplicates data structures:
>
copy(V) ;
Function
entries
that displays an unordered sequence of the bracketed entries of data structures:
>
entries(V) ;
Function
evalm
that
eval
uates
m
atrices and expressions involving matrices both symbolically and numerically:
>
evalm(V) ;
Function
indices
that displays an unordered sequence of the bracketed indices of the entries of data structures:
>
indices(V) ;
Although the above four functions are not included in the
linalg
package, each of them is specifically designed to work on data structures only.
Some other commands and operators from
Maple
s
main
library that recognise the matrix structure "behind" its name and perform the respective operation on the pre-defined matrix are as follows.
Function
convert
together with a suitable parameter (e.g.
listlist
) that converts an expression to another form:
>
convert(V, listlist) ;
Function
print
that displays the values of the expressions appearing as arguments:
>
print(V) ;
Type-checking
Boolean
function
type
that checks if the first parameter is of type specified by the second parameter:
>
type(V, matrix) ;
Function
map
used together with the arrow-type functional operator,
(
x->
)
, that applies a function or procedure to all the operands (components) of expressions, including matrices. In the example below, the function applied to V is multiplication of each element of matrix [
V
] by the scalar
:
>
map(x->x*mu, V) ;
A pair of empty parentheses placed immediately after the matrix name that displays the matrix:
>
V() ;
Subscript notation, or bracketed indices separated by the comma
[i, j]
that extracts the element of matrix [
V
] at the specified location
(
i
,
j
),
e.g.:
>
V[3,1] ;
Function
conjugate
that computes the complex conjugate of complex-numbered expressions, including matrices. If a complex-numbered matrix [
Z
] is given as
>
Z := matrix(2, 3, [-5*I, 2+6*I, I, 4+8*I, 3, 6-10*I]) : Z = matrix(Z) ;
then
>
conjugate(Z) = evalm(conjugate(Z)) ;
There are two commands in
Maple
s
main
library that force full evaluation of a matrix name to the elements of the matrix, viz.
Function
eval
that fully
eval
uates expressions, including matrices:
>
eval(V) ;
Function
op
that extracts
op
erands (components) of expressions, including matrices. For the latter, the function returns all the components in the matrix form:
>
op(V) ;
Needless to say that all the functions and commands contained in the
linalg
package recognise the matrix structure "behind" its name and perform the relevant operations on the matrix, e.g.
>
adjoint(V) ; det(V) ; orthog(V) ; rowdim(V) ; transpose(V) ;
To "inform" a function from outside of the
linalg
package that the name V has been assigned a matrix structure, the aforementioned commands
eval
and
op
or function
matrix
may be used, e.g.
>
eval(V) + 1 ; (op(V))^2 ; 3/4*matrix(V) ;
[ How to execute the above operations, refer to the pertinent Units. ]
In summary, using any of the following commands will re-assign the matrix structure to the name V:
>
V := copy(V) : V := evalm(V) : V := eval(V) : V := op(V) : V := matrix(V) : V := V() ;
* * *
If a matrix name is to be unassigned the structure of a pre-defined matrix, any of the following alternative methods may be used.
Method 1
. Using the procedure
unassign
, viz.
>
type(V, matrix) ; unassign(V) : V ; type(V , matrix) ;
Method 2
. Using single quotes
(
'
'
)
enclosing the matrix name, viz.
>
type(E, matrix) ; E := 'E' : E ; type(E , matrix) ;
Method 3
. Using the
evaln
function that
eval
uates the expression to its
n
ame, viz.
>
type(R, matrix) ; R := evaln(R) : R ; type(R , matrix) ;
The first
Boolean
value
verifies that a name carries the pre-defined matrix structure before unassigning, and the second
Boolean
value
verifies that the name has been unassigned the matrix
structure.
* * *
N.B.
A matrix name of type [
M
(
)
] retains the structure assigned. To display such a name together with a pre-defined matrix structure, enclose it in a pair of single quotes, viz.
>
'M(t)' = M(t) ;
* * *
Proceed to Unit (2) for "
Extracting components of matrices
".
-------------------------------------------------------------------