Matrices-Unit19.mws

MATRICES AND MATRIX OPERATIONS: Unit 19

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

-------------------------------------------------------------------

(19) Solution of systems of linear algebraic inhomogeneous equations using Cramer ’ s rule

OBJECTIVES :

• To define a system of linear algebraic inhomogeneous equations.

• To show how a system of such equations may be written in the matrix form.

• To introduce the concepts of the coefficient matrix , solution vector , and inhomogeneous vector .

• To introduce Cramer’ s rule for solving systems of linear algebraic inhomogeneous equations.

• To provide a numerical example for the application of Cramer’ s rule.

• To show how systems of linear algebraic inhomogeneous equations may be solved in a simple way using Maple ’ s functions linsolve or solve .

• To demonstrate that so-called ill-conditioned systems of linear inhomogeneous equations do not pose problems if tackled with Maple .

> restart : with(linalg, copyinto, det, genmatrix, linsolve, multiply, stackmatrix) :

Consider the following system of 4 linear algebraic inhomogeneous equations in 4 variables:

a[11]*x[1]+a[12]*x[2]+a[13]*x[3]+a[14]*x[4] = k[1]

a[21]*x[1]+a[22]*x[2]+a[23]*x[3]+a[24]*x[4] = k[2]

a[31]*x[1]+a[32]*x[2]+a[33]*x[3]+a[34]*x[4] = k[3]

a[41]*x[1]+a[42]*x[2]+a[43]*x[3]+a[44]*x[4] = k[4]

where the term inhomogeneous denotes that at least one of the numbers k[1] ... k[4] is not zero .

Since the number of variables equals the number of equations of this system, it is said to be a square system of linear equations.

This system of equations may be written in the matrix form. To this end, do the following.

• Define the square matrix containing coefficients a[ij] as the coefficient matrix [ A ]:

> A := matrix(4, 4, [ a[11], a[12], a[13], a[14], a[21], a[22], a[23], a[24], a[31], a[32], a[33], a[34], a[41], a[42], a[43], a[44] ]) : A = matrix(A) ;

A = matrix([[a[11], a[12], a[13], a[14]], [a[21], a...

• Define the column matrix containing variables x[i] as the solution vector [ X ]:

> X := matrix(4, 1, [ x[1], x[2], x[3], x[4] ]) : X = matrix(X) ;

X = matrix([[x[1]], [x[2]], [x[3]], [x[4]]])

• Define the column matrix containing numbers k[i] as the inhomogeneous vector [ K ]:

> K := matrix(4, 1, [ k[1], k[2], k[3], k[4] ]) : K = matrix(K) ;

K = matrix([[k[1]], [k[2]], [k[3]], [k[4]]])

* * *

N.B. Both the "solution vector" and "inhomogeneous vector" are column structures and as such, cannot be named "vectors" in Maple – refer to Unit (5). However, because of a customary practice used in textbooks, both names are maintained in this Unit.

* * *

With the matrices defined as above, the system of the equations may now be written in the matrix form

[ A ] [ X ] = [ K ]

or,

> matrix(A) * matrix(X) = matrix(K) ;

matrix([[a[11], a[12], a[13], a[14]], [a[21], a[22]...

Provided that the matrix [ A ] is non-singular , i.e. its determinant is not zero , it follows that the inverse to the matrix [ A ] exists. Multiplying each side of the matrix equation [ A ] [ X ] = [ K ] by Inv [ A ] yields

(Inv [ A ] ) [ A ] [ X ] = (Inv [ A ] ) [ K ]

Since (Inv [ A ] ) [ A ] = [ U ] [see Unit (14)] and [ U ] [ X ] = [ X ] [see Unit (9)], the above simplifies to yield the solution vector in the form

[ X ] = (Inv [ A ] ) [ K ]

or, in "like-in-a-book" form,

> matrix(X) = Inv(matrix(A)) * matrix(K) ;

matrix([[x[1]], [x[2]], [x[3]], [x[4]]]) = Inv(matr...

* * *

N.B. When a solution vector [ X ] exists whose elements simultaneously satisfy all the equations in the system, the equations are said to be consistent . If no solution vector exists having this property, then the equations are said to be inconsistent .

* * *

A useful method of solution for small systems of such equations (maximum 4 equations where computations are to be performed manually) is known as Cramer’ s rule. It states that any unknown x[i] is found as

x[i] = Det([ A , j K ]) / Det([ A ])

The determinant in the numerator is defined as the determinant of the modified coefficient matrix [ A ], in which the j th column is replaced by the inhomogeneous vector [ K ], as indicated by the notation [ A , j K ] .

Exemplarily, the numerator for the unknown x[2] has the form

> i := 1 : j := 2 :

> `det(A, j <– K)` := copyinto(K, A, i, j) : Det(A, ` j <– K`) = Det(matrix(`det(A, j <– K)`)) ;

Det(A,` j <– K`) = Det(matrix([[a[11], k[1], a[13],...

In the denominator, the determinant of the coefficient matrix [ A ] is called the characteristic determinant . For this particular case, it is given by the following expression:

> `det(A)` := det(A) : Det(A) = `det(A)` ;

Det(A) = a[11]*k[2]*a[33]*a[44]-a[11]*k[2]*a[34]*a[...
Det(A) = a[11]*k[2]*a[33]*a[44]-a[11]*k[2]*a[34]*a[...
Det(A) = a[11]*k[2]*a[33]*a[44]-a[11]*k[2]*a[34]*a[...
Det(A) = a[11]*k[2]*a[33]*a[44]-a[11]*k[2]*a[34]*a[...

Numerical example

Solve the following system of 4 equations using Cramer’ s rule:

> Eq[1] := x[1] - 3*x[2] + x[3] - x[4] = -3 :

> Eq[2] := 2*x[1] - x[2] + 3*x[3] + x[4] = 2 :

> Eq[3] := x[1] + x[2] + 2*x[3] + 2*x[4] = 3 :

> Eq[4] := x[1] - 2*x[2] + 4*x[3] + x[4] = 0 :

> Eq[1] ; Eq[2] ; Eq[3] ; Eq[4] ;

x[1]-3*x[2]+x[3]-x[4] = -3

2*x[1]-x[2]+3*x[3]+x[4] = 2

x[1]+x[2]+2*x[3]+2*x[4] = 3

x[1]-2*x[2]+4*x[3]+x[4] = 0

Step 1 . Assign name and value to the number of equations and variables:

> No_Eq := 4 : No_x := 4 : 'No_Eq' = No_Eq ; 'No_x' = No_x ;

No_Eq = 4

No_x = 4

Step 2 . Construct the coefficient matrix [ A ]:

Method 1 . Using the function genmatrix and either of the two alternative methods of specifying the equations and variables:

• enter manually the names of all equations enclosed in brackets, followed by the names of all variables enclosed in brackets, viz.

> A := genmatrix([Eq[1], Eq[2], Eq[3], Eq[4]], [x[1], x[2], x[3], x[4]]) : A = matrix(A) ;

A = matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2...

• create a bracketed sequence (list) of equations, followed by bracketed sequence (list) of variables, viz.

> `seq(Eq[i])` := [seq(Eq[i], i=1..No_Eq)] : `seq(x[i])` := [seq(x[i], i=1..No_x)] :

> A := genmatrix(`seq(Eq[i])`, `seq(x[i])`) : A = matrix(A) ;

A = matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2...

Method 2 . Requiring several steps and the for -loop construct:

(a) Count the number of operands of the left-hand side of each equation:

> for j to No_Eq do if op(select(type, convert(lhs(Eq[j]), list), numeric)) <> NULL then ops(lhs_Eq[j]) := 1 else ops(lhs_Eq[j]) := nops(lhs(Eq[j])) fi : print(No_operands(lhs_Eq[j]) = ops(lhs_Eq[j])) : od :

No_operands(lhs_Eq[1]) = 4

No_operands(lhs_Eq[2]) = 4

No_operands(lhs_Eq[3]) = 4

No_operands(lhs_Eq[4]) = 4

(b) Create lists of operands of the left-hand side of each equation:

> for j to No_Eq do if ops(lhs_Eq[j]) = 1 then L[j] := [lhs(Eq[j])] else L[j] := convert(lhs(Eq[j]), list) fi : print(evaln(L[j]) = L[j]) : od :

L[1] = [x[1], -3*x[2], x[3], -x[4]]

L[2] = [2*x[1], -x[2], 3*x[3], x[4]]

L[3] = [x[1], x[2], 2*x[3], 2*x[4]]

L[4] = [x[1], -2*x[2], 4*x[3], x[4]]

(c) Construct row matrices containing numeric operands of the elements of each list:

> for i to No_x do n := 0 : for j to No_Eq do if has(L[i], x[j]) = false then a[i,j] := 0 else n := n+1 : a[i,j] := op(n, L[i])/x[j] fi : od : RM[i] := matrix(1, No_x, [[seq(a[i,m], m=1..No_x)]]) : print(RM[i] = matrix(RM[i])) : od :

RM[1] = matrix([[1, -3, 1, -1]])

RM[2] = matrix([[2, -1, 3, 1]])

RM[3] = matrix([[1, 1, 2, 2]])

RM[4] = matrix([[1, -2, 4, 1]])

(d) Create a sequence of the row matrices:

> `seq(RM[i])` := seq(matrix(RM[k]), k=1..No_Eq) : sequence(RM['i']) = `seq(RM[i])` ;

sequence(RM[i]) = (matrix([[1, -3, 1, -1]]), matrix...

(e) Construct matrix [ A ] by stacking the row matrices:

> A := stackmatrix(`seq(RM[i])`) : A = matrix(A) ;

A = matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2...

N.B. Method 2 is universal and works even if some coefficients a[ij] in the simultaneous equations are zero . It also works even if one coefficient is non- zero in any equation (the case purely abstractive from mathematical point of view).

If none of the coefficients a[ij] is zero , the following short variant of this method may be used:

> a := matrix(No_x, No_Eq) :

> for i to No_Eq do for j to No_x do a[i,j] := op(j, lhs(Eq[i]))/x[j] od : od :

> A := matrix(a) : A = matrix(A) ;

A = matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2...

Step 3 . Create a copy of matrix [ A ] for the future use (in Step 7):

> C_A := copy(A) : C_A = matrix(C_A) ;

C_A = matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1,...

Step 4 . Define and input the solution vector [ X ]:

Method 1 . Using the for -loop construct:

> x := array(1..No_Eq) : for i to No_x do x[i] := x[i] od : X := convert(x, matrix) : X = matrix(X) ;

X = matrix([[x[1]], [x[2]], [x[3]], [x[4]]])

Method 2 . Using manual inputting of each vector element:

> X := matrix(4, 1, [x[1], x[2], x[3], x[4]]) : X = matrix(X) ;

X = matrix([[x[1]], [x[2]], [x[3]], [x[4]]])

Step 5 . Define and input the inhomogeneous vector [ K ]:

Method 1 . Using the for -loop construct:

> k := array(1..No_Eq) : for i to No_x do k[i] := rhs(Eq[i]) od : K := convert(k, matrix) : K = matrix(K) ;

K = matrix([[-3], [2], [3], [0]])

Method 2 . Using manual inputting of each vector element:

> K := matrix(4, 1, [rhs(Eq[1]), rhs(Eq[2]), rhs(Eq[3]), rhs(Eq[4])]) : K = matrix(K) ;

K = matrix([[-3], [2], [3], [0]])

The system of the equations may now be written in the matrix form, i.e.

> matrix(A) * matrix(X) = matrix(K) ;

matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2, 2]...

Step 6 . Compute the characteristic determinant of the coefficient matrix [ A ]:

> `det(A)` := det(A) : Det(A) = `det(A)` ;

Det(A) = -7

Step 7 . Find the unknowns x[1] ... x[4] :

(a) Finding x[1]

> `det(A, 1 <– K)` := copyinto(K, A, 1, 1) : Det(A, `1 <– K`) = Det(matrix(`det(A, 1 <– K)`)) ;

Det(A,`1 <– K`) = Det(matrix([[-3, -3, 1, -1], [2, ...

> `det(A, 1 <– K)` := det(`det(A, 1 <– K)`) : Det(A, `1 <– K`) = `det(A, 1 <– K)` ;

Det(A,`1 <– K`) = -7

> x[1] := `det(A, 1 <– K)`/`det(A)` : 'x[1]' = x[1] ; x[1] := 'x[1]' :

x[1] = 1

(b) Finding x[2]

> A := matrix(C_A) :

> `det(A, 2 <– K)` := copyinto(K, A, 1, 2) : Det(A, `2 <– K`) = Det(matrix(`det(A, 2 <– K)`)) ;

Det(A,`2 <– K`) = Det(matrix([[1, -3, 1, -1], [2, 2...

> `det(A, 2 <– K)` := det(`det(A, 2 <– K)`) : Det(A, `2 <– K`) = `det(A, 2 <– K)` ;

Det(A,`2 <– K`) = -14

> x[2] := `det(A, 2 <– K)`/`det(A)` : 'x[2]' = x[2] ; x[2] := 'x[2]' :

x[2] = 2

(c) Finding x[3]

> A := matrix(C_A) :

> `det(A, 3 <– K)` := copyinto(K, A, 1, 3) : Det(A, `3 <– K`) = Det(matrix(`det(A, 3 <– K)`)) ;

Det(A,`3 <– K`) = Det(matrix([[1, -3, -3, -1], [2, ...

> `det(A, 3 <– K)` := det(`det(A, 3 <– K)`) : Det(A, `3 <– K`) = `det(A, 3 <– K)` ;

Det(A,`3 <– K`) = -7

> x[3] := `det(A, 3 <– K)`/`det(A)` : 'x[3]' = x[3] ; x[3] := 'x[3]' :

x[3] = 1

(d) Finding x[4]

> A := matrix(C_A) :

> `det(A, 4 <– K)` := copyinto(K, A, 1, 4) : Det(A, `4 <– K`) = Det(matrix(`det(A, 4 <– K)`)) ;

Det(A,`4 <– K`) = Det(matrix([[1, -3, 1, -3], [2, -...

> `det(A, 4 <– K)` := det(`det(A, 4 <– K)`) : Det(A, `4 <– K`) = `det(A, 4 <– K)` ;

Det(A,`4 <– K`) = 7

> x[4] := `det(A, 4 <– K)`/`det(A)` : 'x[4]' = x[4] ; x[4] := 'x[4]' :

x[4] = -1

* * *

N.B. The solution vector [ X ] may be obtained in a simpler way using the linsolve function, viz.

> A := genmatrix(`seq(Eq[i])`, `seq(x[i])`) : X := linsolve(A, K) : X = matrix(X) ;

X = matrix([[1], [2], [1], [-1]])

Extracting the numerical value of each unknown from the solution vector [ X ] gives

> for i to No_Eq do x[i] := X[i,1] : print(evaln(x[i]) = x[i]) : od :

x[1] = 1

x[2] = 2

x[3] = 1

x[4] = -1

* * *

Thus, the solved system of the equations may be written in the matrix form as follows:

> matrix(A) * matrix(X) = matrix(K) ;

matrix([[1, -3, 1, -1], [2, -1, 3, 1], [1, 1, 2, 2]...

Verification of the solution may be performed by evaluating the product of matrices [ A ] and [ X ], viz.

> `AX` := multiply(A, X) : A * X = matrix(`AX`) ;

A*X = matrix([[-3], [2], [3], [0]])

which is equal to the inhomogeneous vector [ K ].

* * *

N.B. The simplest method of solving systems of such equations in Maple is by using the solve (or fsolve ) function. For instructive purposes, this is done hereunder for the above system of equations.

> for i to No_x do x[i] := evaln(x[i]) : od :

> solution := solve({Eq[1], Eq[2], Eq[3], Eq[4]}, {x[1], x[2], x[3], x[4]}) : solution ;

{x[3] = 1, x[2] = 2, x[4] = -1, x[1] = 1}

or

> i := 'i' : `seq(Eq[i])` := {seq(Eq[i], i=1..No_Eq)} : `seq(x[i])` := {seq(x[i], i=1..No_x)} :

> solution := solve(`seq(Eq[i])`, `seq(x[i])`) : solution ;

{x[3] = 1, x[2] = 2, x[4] = -1, x[1] = 1}

Extracting each solution from the unordered solution set gives

> assign(solution) : for i to No_x do x[i] := x[i] : print(evaln(x[i]) = x[i]) : od :

x[1] = 1

x[2] = 2

x[3] = 1

x[4] = -1

> for i to No_x do x[i] := evaln(x[i]) : od :

* * *

N.B. The solution of a system of simultaneous equations may, on occassion, become difficult due to round-off errors if a calculator is used for computations based on Cramer’ s rule. In general, this may take place in solving systems for which the characteristic determinant of the coefficient matrix is close to zero . Such systems are said to be ill-conditioned . A simple example is provided by the system

> Eq[1] := x[1] + x[2] = 4 :

> Eq[2] := x[1] + 1.0001*x[2] = 1 :

> Eq[1] ; Eq[2] ;

x[1]+x[2] = 4

x[1]+1.0001*x[2] = 1

which, however, does not pose a problem when tackled using Maple and any of the methods presented earlier. This is demonstrated hereunder.

Method 1 . Using Cramer’ s rule:

> A := genmatrix([Eq[1], Eq[2]], [x[1], x[2]]) : A = matrix(A) ; C_A := copy(A) :

A = matrix([[1, 1], [1, 1.0001]])

> X := matrix(2, 1, [x[1], x[2]]) : X = matrix(X) ;

X = matrix([[x[1]], [x[2]]])

> K := matrix(2, 1, [rhs(Eq[1]), rhs(Eq[2])]) : K = matrix(K) ;

K = matrix([[4], [1]])

> `det(A)` := det(A) : Det(A) = `det(A)` ;

Det(A) = .1e-3

(a) Finding x[1]

> `det(A, 1 <– K)` := copyinto(K, A, 1, 1) : Det(A, `1 <– K`) = Det(matrix(`det(A, 1 <– K)`)) ;

Det(A,`1 <– K`) = Det(matrix([[4, 1], [1, 1.0001]])...

> `det(A, 1 <– K)` := det(`det(A, 1 <– K)`) : Det(A, `1 <– K`) = `det(A, 1 <– K)` ;

Det(A,`1 <– K`) = 3.0004

> x[1] := `det(A, 1 <– K)`/`det(A)` : 'x[1]' = x[1] ; x[1] := 'x[1]' :

x[1] = 30004.00000

(b) Finding x[2]

> A := matrix(C_A) :

> `det(A, 2 <– K)` := copyinto(K, A, 1, 2) : Det(A, `2 <– K`) = Det(matrix(`det(A, 2 <– K)`)) ;

Det(A,`2 <– K`) = Det(matrix([[1, 4], [1, 1]]))

> `det(A, 2 <– K)` := det(`det(A, 2 <– K)`) : Det(A, `2 <– K`) = `det(A, 2 <– K)` ;

Det(A,`2 <– K`) = -3

> x[2] := `det(A, 2 <– K)`/`det(A)` : 'x[2]' = x[2] ; x[2] := 'x[2]' :

x[2] = -30000.00000

Method 2 . Using the linsolve function:

> A := genmatrix([Eq[1], Eq[2]], [x[1], x[2]]) : A = matrix(A) ;

A = matrix([[1, 1], [1, 1.0001]])

> X := linsolve(A, K) : X = matrix(X) ;

X = matrix([[30004.], [-30000.]])

Extracting the numerical value of either unknown from the solution vector [ X ] gives

> for i to 2 do x[i] := X[i,1] : print(evaln(x[i]) = x[i]) : od :

x[1] = 30004.

x[2] = -30000.

Method 3 . Using the solve function:

> for i to 2 do x[i] := evaln(x[i]) : od :

> solution := solve({Eq[1], Eq[2]}, {x[1], x[2]}) : solution ;

{x[1] = 30004., x[2] = -30000.}

Extracting either solution from the unordered solution set gives

> assign(solution) : for i to 2 do x[i] := x[i] : print(evaln(x[i]) = x[i]) : od :

x[1] = 30004.

x[2] = -30000.

> for i to 2 do x[i] := evaln(x[i]) : od :

* * *

Yet another example of an ill-conditioned system are the simultaneous equations

> Eq[1] := 0.00001*x[1] + x[2] + 0.00001*x[3] = 0.00002 :

> Eq[2] := x[1] + 2*x[2] + x[3] = 1 :

> Eq[3] := 0.00001*x[1] + x[2] - 0.00001*x[3] = 0.00001 :

> Eq[1] ; Eq[2] ; Eq[3] ;

.1e-4*x[1]+x[2]+.1e-4*x[3] = .2e-4

x[1]+2*x[2]+x[3] = 1

.1e-4*x[1]+x[2]-.1e-4*x[3] = .1e-4

The coefficient matrix [ A ] is:

> A := genmatrix([Eq[1], Eq[2], Eq[3]], [x[1], x[2], x[3]]) : A = matrix(A) ;

A = matrix([[.1e-4, 1, .1e-4], [1, 2, 1], [.1e-4, 1...

The characteristic determinant of the coefficient matrix [ A ] has the value:

> `det(A)` := det(A) : Det(A) = `det(A)` ;

Det(A) = .199996e-4

The inhomogeneous vector [ K ] is:

> K := matrix(3, 1, [rhs(Eq[1]), rhs(Eq[2]), rhs(Eq[3])]) : K = matrix(K) ;

K = matrix([[.2e-4], [1], [.1e-4]])

With the default environment variable Digits ( i.e. 10 ) , the solution vector obtained using the linsolve function is:

> X := linsolve(A, K) : X = matrix(X) ;

X = matrix([[.4999799996], [.1000020000e-4], [.5000...

Extracting the numerical value of each unknown from the solution vector [ X ] gives

> for i to 3 do x[i] := X[i,1] : print(evaln(x[i]) = x[i]) : od :

x[1] = .4999799996

x[2] = .1000020000e-4

x[3] = .5000000000

Conclusion : The notion of ill-conditioned systems of linear inhomogeneous equations does not apply at all if Maple is used for solving such systems.

* * *

Proceed to Unit (20) for " Trace of a matrix ".

-------------------------------------------------------------------