Matrices-Unit24.mws

MATRICES AND MATRIX OPERATIONS: Unit 24

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

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

(24) Functions of matrices comprising linear functions

OBJECTIVES :

To provide five step-by-step solved examples for computation of matrix functions with real and complex elements using in each case all the three methods of computation of matrix functions that are employed in Unit (23).

To provide a comparison of the resultant matrix functions by computing the function of each matrix for a given numerical value of the variable.

To include computation of the limit of the resultant matrix function having a discontinuity on the interval of convergence of the function.

To point out a disadvantage of computing matrix functions using truncated Maclaurin’ s series if a display of the resultant matrix was essential.

To reveal a difficulty when Maple does not return any symbolic solutions to a system of transcendental equations and show how to get around such a problem.

> restart : with(linalg, augment, coldim, diag, eigenvals, eigenvects, equal, exponential, rowdim) :

This Unit deals with computation of functions of square matrices whose elements are linear functions of type a*t+b , where t is a real variable and a and b are constant coefficients.

The exponential function of matrices whose elements are linear functions of type a*t , or exp([ A ] t ), is a special case. It is treated separately in more detail in Unit (30) together with specific applications of the function.

A function f of a matrix [ A ( t ) ] whose elements are linear functions of a real variable t may be computed only if the function is well defined for the matrix. [ Refer to Unit (23) for the well-defined function. ]

A well-defined function of a matrix [ A ( t ) ] may be computed using the Cayley-Hamilton theorem, similarity of matrices, or the Maclaurin series representation of the corresponding function f(x) .

However, it should be borne in mind that none of the methods is universal since each has limitations of different nature – refer to Units (22) and (23). Whether a given method is suitable for computation of a matrix function, may be assessed only when both the sought-for function and the matrix are known.

In the examples provided hereunder, the matrices have been carefully constructed such that all the three methods may be used for computation of functions f( [ A ( t ) ] ) that are well defined for these matrices and can be determined without a great computational effort. This has been done for illustrating and comparative purposes.

Example 1

Compute cos( [ A ( t ) ] ) for a ( 2 × 2 ) matrix [ A ( t ) ] given as

> A(t) := matrix(2, 2, [t+2, 0, -t, 2*t-1]) : 'A(t)' = A(t) ;

A(t) = matrix([[t+2, 0], [-t, 2*t-1]])

The power series of cos(x) is convergent for all x [refer to Unit (23)], which implies that cos( [ A ] ) is well defined for every square matrix. This, in turn, means that the function cos( [ A ( t ) ] ) is well defined for every value of t , so it may be computed for this matrix. See also the note at the end of Method 1.

For convenience in computations, let

> B(t) := A(t) : A(t) := 'A(t)' :

Method 1 . Using the Cayley-Hamilton theorem

Step 1 . Having in mind that n = 2 for this matrix, write equation (1) of Unit (23) B for [ A ( t ) ]:

> `cos(A(t))` := a[1] * A(t) + a[0]*U : cos(A(t)) = `cos(A(t))` ; Cos(A(t)) := `cos(A(t))` :

cos(A(t)) = a[1]*A(t)+a[0]*U

Step 2 . Bearing in mind that the unit matrix [ U ] appropriately sized for this case is

> U := diag(1, 1) : U = matrix(U) ;

U = matrix([[1, 0], [0, 1]])

evaluate the matrix equation for cos( [ A ( t ) ] ):

> `cos(A(t))` := evalm(subs(A(t)=B(t), `cos(A(t))`)) : cos(A(t)) = matrix(`cos(A(t))`) ;

cos(A(t)) = matrix([[a[1]*(t+2)+a[0], 0], [-a[1]*t,...

Step 3 . Formulate equation (2) of Unit (23) B corresponding to this case:

> l := lambda : `r(l)` := subs(A(t)=l, U=1, Cos(A(t))) : r(l) = `r(l)` ;

r(lambda) = a[1]*lambda+a[0]

Step 4 . Determine the eigenvalues of [ A ( t ) ]:

> charroots(A(t)) := eigenvals(subs(A(t)=B(t), A(t))) : char_roots(A(t)) = charroots(A(t)) ;

char_roots(A(t)) = (t+2, 2*t-1)

Extracting the individual eigenvalues lambda[i] yields

> No_roots(A(t)) := nops([charroots(A(t))]) :

> for i to No_roots(A(t)) do ch_r[i](A(t)) := charroots(A(t))[i] : print(l[i] = ch_r[i](A(t))) : od :

lambda[1] = t+2

lambda[2] = 2*t-1

Step 5 . Taking notice of the fact that the roots are distinct, formulate equation (3) of Unit (23) B in a general form:

Since the function f(lambda) corresponding to this case is

> `f(l)` := cos(l) : f(l) = `f(l)` ;

f(lambda) = cos(lambda)

therefore, equation (3) assumes the form

> Eq3_f(l) := `f(l)` = `r(l)` : Eq3_f(l) ;

cos(lambda) = a[1]*lambda+a[0]

Step 6 . Obtain a set of equations by substituting either eigenvalue into equation (3):

> for i to No_roots(A(t)) do Eq3_f[i](l) := subs(l=ch_r[i](A(t)), Eq3_f(l)) : print(Eq3_f[i](l)) : od :

cos(t+2) = a[1]*(t+2)+a[0]

cos(2*t-1) = a[1]*(2*t-1)+a[0]

Step 7 . Solve the simultaneous equations for the unknown coefficients:

> solution := solve({Eq3_f[1](l), Eq3_f[2](l)}, {a[0], a[1]}) : solution ;

{a[1] = (cos(2*t-1)-cos(t+2))/(t-3), a[0] = -(-2*co...

Extracting either unknown from the solution set yields

> assign(solution) : for i to No_roots(A(t)) do a[i-1] := a[i-1] : print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = -(-2*cos(t+2)*t+cos(t+2)+t*cos(2*t-1)+2*cos(...

a[1] = (cos(2*t-1)-cos(t+2))/(t-3)

After some re-arrangements, the expressions for both coefficients assume more compact forms, viz.

> a[0] := ((2*t-1)*cos(t+2) - (t+2)*cos(2*t-1))/(t-3) : a[1] := numer(a[1])/denom(a[1]) :

> for i to No_roots(A(t)) do print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = ((2*t-1)*cos(t+2)-(t+2)*cos(2*t-1))/(t-3)

a[1] = (cos(2*t-1)-cos(t+2))/(t-3)

Step 8 . Substitute the values of the coefficients into the matrix cos( [ A ( t ) ] ), simplify the elements of the resultant matrix, and add a distinguishing subscript, say, C_H ( C ayley- H amilton) to its name for future comparative purposes:

> `cos(A(t))[C_H]` := map(simplify, map(x->eval(x), `cos(A(t))`)) :

> cos(A(t))[C_H] = matrix(`cos(A(t))[C_H]`) ;

cos(A(t))[C_H] = matrix([[cos(t+2), 0], [(-cos(2*t-...

> for i to No_roots(A(t)) do a[i-1] := evaln(a[i-1]) : od :

N.B. In general, the function cos( [ A ( t ) ] ) is well defined for every value of t . This is true if the function elements of the matrix function are continuous functions for every t .

It can be easily noticed that the function element a[21](t) in the above matrix has a discontinuity at t = 3 . Therefore, the function cos( [ A ( t ) ] ) may be computed for t = 3 only if a limiting value of the matrix element a[21](t) exists when t tends to 3 . Consequently, this must checked by computing the limit as follows:

> `limit(a[21](t))` := limit(`cos(A(t))[C_H]`[2,1], t=3) : Limit(a[21](t), t=3) = `limit(a[21](t))` ;

Limit(a[21](t),t = 3) = 3*sin(5)

In computational practice, the above check may be omitted and an attempt made to compute the value of the function cos( [ A ( t ) ] ) for t = 3 directly as the limit of the matrix function when t tends to 3 . Thus,

> `lim cos(A(t))[C_H]` := map(limit, `cos(A(t))[C_H]`, t=3) :

> Limit(cos(A(t))[C_H], t=3) = matrix(`lim cos(A(t))[C_H]`) ;

Limit(cos(A(t))[C_H],t = 3) = matrix([[cos(5), 0], ...

Floating-point evaluation yields

> `lim cos(A(t))[C_H]` := evalf(matrix(`lim cos(A(t))[C_H]`)) :

> Limit(cos(A(t))[C_H], t=3) = matrix(`lim cos(A(t))[C_H]`) ;

Limit(cos(A(t))[C_H],t = 3) = matrix([[.2836621855,...

[ For computation of limits of function matrices, refer to Unit (28). ]

Method 2 . Using similarity of matrices

Step 1 . Check if the eigenvalues of [ A ( t ) ] are distinct:

See Step 4 above where the eigenvalues are found to be distinct.

Step 2 . Find the sequence of lists containing eigenvalues and eigenvectors of [ A ( t ) ]:

> `roots&vectors(A(t))` := eigenvects(subs(A(t)=B(t), A(t))) :

> roots_and_vectors(A(t)) = `roots&vectors(A(t))` ;

roots_and_vectors(A(t)) = ([2*t-1, 1, {vector([0, 1...

Step 3 . Extract the eigenvectors v[lambda[i]] corresponding to eigenvalues lambda[i] of [ A ( t ) ]:

> for i to No_roots(A(t)) do e[i] := charroots(A(t))[i] : List[i] := `roots&vectors(A(t))`[i] : od :

> for j to No_roots(A(t)) do for i to No_roots(A(t)) do if List[i][1] = e[j] then Lst[j] := `roots&vectors(A(t))`[i] : fi : od : od :

> for i to No_roots(A(t)) do ch_v[i](A(t)) := op(Lst[i][3]) : print(v[lambda[i]] = eval(ch_v[i](A(t))), ` --> ` * lambda[i] = ch_r[i](A(t))) : od :

v[lambda[1]] = vector([(t-3)/t, 1]), `  -->  `*lamb...

v[lambda[2]] = vector([0, 1]), `  -->  `*lambda[2] ...

Conversion of the eigenvectors v[lambda[i]] into column matrices X[lambda[i]] yields

> for i to No_roots(A(t)) do X[l[i]] := convert(ch_v[i](A(t)), matrix) : print(X[l[i]] = matrix(X[l[i]])) : od :

X[lambda[1]] = matrix([[(t-3)/t], [1]])

X[lambda[2]] = matrix([[0], [1]])

Step 4 . Construct the 'unique' modal matrix [ M ( t ) ] associated with [ A ( t ) ]:

> i := 'i' : `seq(X[l[i]])` := seq(X[l[i]], i=1..coldim(B(t))) : M(t) := augment(`seq(X[l[i]])`) : 'M(t)'=M(t) ;

M(t) = matrix([[(t-3)/t, 0], [1, 1]])

Step 5 . Construct the unique Jordan form [ J ( t ) ] of [ A ( t ) ]:

> J_A := array(diagonal, 1..rowdim(B(t)), 1..coldim(B(t))) :

> for i to rowdim(B(t)) do for j to coldim(B(t)) do if j = i then J_A[i,j] := ch_r[i](A(t)) fi : od : od :

> J(t) := matrix(J_A) : 'J(t)' = J(t) ;

J(t) = matrix([[t+2, 0], [0, 2*t-1]])

Step 6 . Compute the function cosine of matrix [ J ( t ) ]:

> J_A := array(diagonal, 1..rowdim(J(t)), 1..coldim(J(t))) :

> for i to rowdim(J(t)) do for j to coldim(J(t)) do if j = i then J_A[i,j] := cos(J(t)[i,j]) fi : od : od :

> `cos(J(t))` := matrix(J_A) : cos('J(t)') = matrix(`cos(J(t))`) ;

cos(J(t)) = matrix([[cos(t+2), 0], [0, cos(2*t-1)]]...

Step 7 . Compute cos( [ A ( t ) ] ) = [ M ( t ) ] cos( [ J ( t ) ] ) Inv [ M ( t ) ] , simplify the elements of the resultant matrix, and add a distinguishing subscript, say, s_m ( s imilarity of m atrices) to its name for future comparative purposes:

> `cos(A(t))[s_m]` := map(simplify, evalm(M(t) &* `cos(J(t))` &* M(t)^(-1))) :

> cos(A(t))[s_m] = matrix(`cos(A(t))[s_m]`) ;

cos(A(t))[s_m] = matrix([[cos(t+2), 0], [-t*(cos(2*...

The symbolic forms of matrices cos(A(t))[C_H] and cos(A(t))[s_m] are equal.

Method 3 . Using truncated Maclaurin’ s series

Step 1 . Find the eigenvalues of [ A ( t ) ]:

This step was already done earlier to check if the eigenvalues of [ A ( t ) ] are distinct, which was essential for both preceding methods. It is not necessary for this method since the series of cos(x) is convergent for all x , which implies that cos( [ A ( t ) ] ) is well defined for every square matrix.

Step 2 . Write the expression for Maclaurin’ s series representing the function cos(x) and substitute the matrix name for x :

> `cos(A(t))` := U + subs(x=A(t), Sum((-1)^n*x^(2*n)/(2*n)!, n=1..infinity)) : cos(A(t)) = `cos(A(t))` ;

cos(A(t)) = U+Sum((-1)^n*A(t)^(2*n)/(2*n)!,n = 1 .....

Step 3 . Substitute the matrix names with their corresponding matrix structures:

> `cos(A(t))` := subs(A(t)=B(t), U=matrix(U), `cos(A(t))`) : cos(A(t)) = `cos(A(t))` ;

cos(A(t)) = matrix([[1, 0], [0, 1]])+Sum((-1)^n*mat...

Step 4 . Evaluate the matrix cos( [ A ( t ) ] ) with its symbolic elements after truncating the series to its first 50 terms.

At this point, a relative disadvantage of this method appears in comparison with the previous methods: displaying of the matrix for a large number of terms of the Maclaurin series becomes impractical.

Exemplarily, adopt at this point only n = 2 , simplify the element polynomials, and sort the terms of the matrix elements. (Note that Maple sorts the terms of polynomials into descending order.) These operations yield the matrix

> `cos(A(t))` := map(sort, map(simplify, evalm(subs(A(t)=B(t), U + sum((-1)^n*A(t)^(2*n)/(2*n)!, n=1..2))))) : cos(A(t)) = matrix(`cos(A(t))`) ;

cos(A(t)) = matrix([[1/24*t^4+1/3*t^3+1/2*t^2-2/3*t...

However, computational experiments show that the number of series terms adopted, n , should be about 50 to ensure a satisfactory accuracy. On the other hand, it is rather unlikely that a display of such matrices with their symbolic elements would be of any use. Practically, the result of numerical computation of the matrix function for a given value of t is required only.

Consequently, n = 50 is adopted and the resultant matrix is added a distinguishing subscript, say, M_s ( M aclaurin’ s s eries ) to its name for future comparative purposes. Moreover, the functions simplify and sort are dropped, which results in a significant saving of computation time.

Thus, the final expression for cos( [ A ( t ) ] ) computed by this method is adopted as follows:

> `cos(A(t))[M_s]`:= evalm(subs(A(t)=B(t), U + sum((-1)^n*A(t)^(2*n)/(2*n)!, n=1..50))) :

> cos(A(t))[M_s] = subs(x=B(t), matrix(U) + Sum((-1)^n*x^(2*n)/(2*n)!, n=1..50)) ; B(t) := 'B(t)' :

cos(A(t))[M_s] = matrix([[1, 0], [0, 1]])+Sum((-1)^...

Comparison of numerical results of computation of cos( [ A ( t ) ] )

Compute cos( [ A ( t ) ] ) if t = 4 using all the three methods.

> t := 4 :

(a) For Method 1 using the Cayley-Hamilton theorem:

> `cos(A(t))[C_H]` := map(x->eval(x), `cos(A(t))[C_H]`) : cos(A('t'))[C_H] = matrix(`cos(A(t))[C_H]`) ;

cos(A(t))[C_H] = matrix([[cos(6), 0], [-4*cos(7)+4*...

Floating-point evaluation yields

> `cos(A(t))[C_H]` := evalf(matrix(`cos(A(t))[C_H]`)) : cos(A('t'))[C_H] = matrix(`cos(A(t))[C_H]`) ;

cos(A(t))[C_H] = matrix([[.9601702867, 0.], [.82507...

(b) For Method 2 using similarity of matrices:

> `cos(A(t))[s_m]` := map(x->eval(x), `cos(A(t))[s_m]`) : cos(A('t'))[s_m] = matrix(`cos(A(t))[s_m]`) ;

cos(A(t))[s_m] = matrix([[cos(6), 0], [-4*cos(7)+4*...

Floating-point evaluation yields

> `cos(A(t))[s_m]` := evalf(matrix(`cos(A(t))[s_m]`)) : cos(A('t'))[s_m] = matrix(`cos(A(t))[s_m]`) ;

cos(A(t))[s_m] = matrix([[.9601702867, 0.], [.82507...

(c) For Method 3 using truncated Maclaurin’ s series:

> `cos(A(t))[M_s]` := evalf(map(x->eval(x), `cos(A(t))[M_s]`)) :

> cos(A('t'))[M_s] = matrix(`cos(A(t))[M_s]`) ; t := 't' :

cos(A(t))[M_s] = matrix([[.9601702866, 0.], [.82507...

The matrices of (a) and (b) are precisely equal and the matrix of (c) may be considered practically equal to the former ones.

* * *

Example 2

Compute sinh( [ A ( t ) ] ) for a ( 2 × 2 ) matrix [ A ( t ) ] given as

> A(t) := matrix(2, 2, [6*t, -5*t, 2*t, 4*t]) : 'A(t)' = A(t) ;

A(t) = matrix([[6*t, -5*t], [2*t, 4*t]])

The power series of sinh(x) is convergent for all x [refer to Unit (23)], which implies that sinh( [ A ] ) is well defined for every square matrix. This, in turn, means that the function sinh( [ A ( t ) ] ) is well defined for every value of t , so it may be computed for this matrix.

For convenience in computations, let

> B(t) := A(t) : A(t) := 'A(t)' :

Method 1 . Using the Cayley-Hamilton theorem

Step 1 . Having in mind that n = 2 for this matrix, write equation (1) of Unit (23) B for [ A ( t ) ]:

> `sinh(A(t))` := a[1] * A(t) + a[0]*U : sinh(A(t)) = `sinh(A(t))` ; Sinh(A(t)) := `sinh(A(t))` :

sinh(A(t)) = a[1]*A(t)+a[0]*U

Step 2 . With the unit matrix [ U ] as in Example 1, evaluate the matrix equation for sinh( [ A ( t ) ] ):

> `sinh(A(t))` := evalm(subs(A(t)=B(t), `sinh(A(t))`)) : sinh(A(t)) = matrix(`sinh(A(t))`) ;

sinh(A(t)) = matrix([[6*a[1]*t+a[0], -5*a[1]*t], [2...

Step 3 . Formulate equation (2) of Unit (23) B corresponding to this case:

> `r(l)` := subs(A(t)=l, U=1, Sinh(A(t))) : r(l) = `r(l)` ;

r(lambda) = a[1]*lambda+a[0]

Step 4 . Determine the eigenvalues of [ A ( t ) ]:

> charroots(A(t)) := eigenvals(subs(A(t)=B(t), A(t))) : char_roots(A(t)) = charroots(A(t)) ;

char_roots(A(t)) = ((5+3*I)*t, (5-3*I)*t)

Extracting the individual eigenvalues lambda[i] yields

> No_roots(A(t)) := nops([charroots(A(t))]) :

> for i to No_roots(A(t)) do ch_r[i](A(t)) := charroots(A(t))[i] : print(l[i] = ch_r[i](A(t))) : od :

lambda[1] = (5+3*I)*t

lambda[2] = (5-3*I)*t

Note that the eigenvalues are complex numbers.

Step 5 . Taking notice of the fact that the roots are distinct, formulate equation (3) of Unit (23) B in a general form:

Since the function f(lambda) corresponding to this case is

> `f(l)` := sinh(l) : f(l) = `f(l)` ;

f(lambda) = sinh(lambda)

therefore, equation (3) assumes the form

> Eq3_f(l) := `f(l)` = `r(l)` : Eq3_f(l) ;

sinh(lambda) = a[1]*lambda+a[0]

Step 6 . Obtain a set of equations by substituting either eigenvalue into equation (3):

> for i to No_roots(A(t)) do Eq3_f[i](l) := subs(l=ch_r[i](A(t)), Eq3_f(l)) : print(Eq3_f[i](l)) : od :

sinh((5+3*I)*t) = (5+3*I)*a[1]*t+a[0]

sinh((5-3*I)*t) = (5-3*I)*a[1]*t+a[0]

Step 7 . Solve the simultaneous equations for the unknown coefficients:

> solution := solve({Eq3_f[1](l), Eq3_f[2](l)}, {a[0], a[1]}) : solution ;

{a[0] = 1/2*sinh((5-3*I)*t)+5/6*I*sinh((5+3*I)*t)-5...

Extracting either unknown from the solution set yields

> assign(solution) : for i to No_roots(A(t)) do a[i-1] := a[i-1] : print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = 1/2*sinh((5-3*I)*t)+5/6*I*sinh((5+3*I)*t)-5/...

a[1] = -1/6*I*(sinh((5+3*I)*t)-sinh((5-3*I)*t))/t

After some re-arrangements, the expressions for both coefficients are written in more compact forms, viz.

> a[0] := (1/2+5/6*I)*sinh((5+3*I)*t) + (1/2-5/6*I)*sinh((5-3*I)*t) : a[1] := numer(a[1])/denom(a[1]) :

> for i to No_roots(A(t)) do print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = (1/2+5/6*I)*sinh((5+3*I)*t)+(1/2-5/6*I)*sinh...

a[1] = -1/6*I*(sinh((5+3*I)*t)-sinh((5-3*I)*t))/t

Step 8 . Substitute the values of the coefficients into the matrix sinh( [ A ( t ) ]:

> `sinh(A(t))` := map(x->eval(x), `sinh(A(t))`) : sinh(A(t)) = matrix(`sinh(A(t))`) ;

sinh(A(t)) = matrix([[-I*(sinh((5+3*I)*t)-sinh((5-3...
sinh(A(t)) = matrix([[-I*(sinh((5+3*I)*t)-sinh((5-3...

Each element of this matrix may be written in a more compact form after some extra manual re-arrangements, viz.

> `sinh(A(t))`[1,1] := (1/2-I/6)*sinh((5+3*I)*t) + (1/2+I/6)*sinh((5-3*I)*t) :

> `sinh(A(t))`[1,2] := 5*I/6*(sinh((5+3*I)*t) - sinh((5-3*I)*t)) :

> `sinh(A(t))`[2,1] := -I/3*(sinh((5+3*I)*t) - sinh((5-3*I)*t)) :

> `sinh(A(t))`[2,2] := (1/2+I/6)*sinh((5+3*I)*t) + (1/2-I/6)*sinh((5-3*I)*t) :

> for i to rowdim(`sinh(A(t))`) do for j to coldim(`sinh(A(t))`) do print(sinh(A(t))[i,j] = `sinh(A(t))`[i,j]) : od : od :

sinh(A(t))[1,1] = (1/2-1/6*I)*sinh((5+3*I)*t)+(1/2+...

sinh(A(t))[1,2] = 5/6*I*(sinh((5+3*I)*t)-sinh((5-3*...

sinh(A(t))[2,1] = -1/3*I*(sinh((5+3*I)*t)-sinh((5-3...

sinh(A(t))[2,2] = (1/2+1/6*I)*sinh((5+3*I)*t)+(1/2-...

Substitute the above elements into the matrix sinh( [ A ( t ) ] ) and add a distinguishing subscript, say, C_H ( C ayley- H amilton) to the name of the resultant matrix for future comparative purposes:

> `sinh(A(t))[C_H]` := matrix(`sinh(A(t))`) : sinh(A(t))[C_H] = matrix(`sinh(A(t))[C_H]`) ;

sinh(A(t))[C_H] = matrix([[(1/2-1/6*I)*sinh((5+3*I)...

> for i to No_roots(A(t)) do a[i-1] := evaln(a[i-1]) : od :

Method 2 . Using similarity of matrices

Step 1 . Check if the eigenvalues of [ A ( t ) ] are distinct:

See Step 4 above where the eigenvalues are found to be distinct.

Step 2 . Find the sequence of lists containing eigenvalues and eigenvectors of [ A ( t ) ]:

> `roots&vectors(A(t))` := eigenvects(subs(A(t)=B(t), A(t))) :

> roots_and_vectors(A(t)) = `roots&vectors(A(t))` ;

roots_and_vectors(A(t)) = ([(5+3*I)*t, 1, {vector([...

Step 3 . Extract the eigenvectors v[lambda[i]] corresponding to eigenvalues lambda[i] of [ A ( t ) ]:

> for i to No_roots(A(t)) do e[i] := charroots(A(t))[i] : List[i] := `roots&vectors(A(t))`[i] : od :

> for j to No_roots(A(t)) do for i to No_roots(A(t)) do if List[i][1] = e[j] then Lst[j] := `roots&vectors(A(t))`[i] : fi : od : od :

> for i to No_roots(A(t)) do ch_v[i](A(t)) := op(Lst[i][3]) : print(v[lambda[i]] = eval(ch_v[i](A(t))), ` --> ` * lambda[i] = ch_r[i](A(t))) : od :

v[lambda[1]] = vector([-1/2*((-5-3*I)*t+4*t)/t, 1])...

v[lambda[2]] = vector([-1/2*((-5+3*I)*t+4*t)/t, 1])...

Conversion of the eigenvectors v[lambda[i]] into column matrices X[lambda[i]] yields

> for i to No_roots(A(t)) do X[l[i]] := convert(ch_v[i](A(t)), matrix) : print(X[l[i]] = matrix(X[l[i]])) : od :

X[lambda[1]] = matrix([[-1/2*((-5-3*I)*t+4*t)/t], [...

X[lambda[2]] = matrix([[-1/2*((-5+3*I)*t+4*t)/t], [...

Step 4 . Construct the 'unique' modal matrix [ M ( t ) ] associated with [ A ( t ) ]:

> i := 'i' : `seq(X[l[i]])` := seq(X[l[i]], i=1..coldim(B(t))) : M(t) := augment(`seq(X[l[i]])`) : 'M(t)'=M(t) ;

M(t) = matrix([[-1/2*((-5-3*I)*t+4*t)/t, -1/2*((-5+...

Step 5 . Construct the unique Jordan form [ J ( t ) ] of [ A ( t ) ]:

> J_A := array(diagonal, 1..rowdim(B(t)), 1..coldim(B(t))) :

> for i to rowdim(B(t)) do for j to coldim(B(t)) do if j = i then J_A[i,j] := ch_r[i](A(t)) fi : od : od :

> J(t) := matrix(J_A) : 'J(t)' = J(t) ;

J(t) = matrix([[(5+3*I)*t, 0], [0, (5-3*I)*t]])

Step 6 . Compute the function hyperbolic sine of matrix [ J ( t ) ]:

> J_A := array(diagonal, 1..rowdim(J(t)), 1..coldim(J(t))) :

> for i to rowdim(J(t)) do for j to coldim(J(t)) do if j = i then J_A[i,j] := sinh(J(t)[i,j]) fi : od : od :

> `sinh(J(t))` := matrix(J_A) : sinh('J(t)') = matrix(`sinh(J(t))`) ;

sinh(J(t)) = matrix([[sinh((5+3*I)*t), 0], [0, sinh...

Step 7 . Compute sinh( [ A ( t ) ] ) = [ M ( t ) ] sinh( [ J ( t ) ] ) Inv [ M ( t ) ] and simplify the elements of the resultant matrix:

> `sinh(A(t))`:=map(simplify, evalm(M(t) &* `sinh(J(t))` &* M(t)^(-1))) : sinh(A(t))=matrix(`sinh(A(t))`) ;

sinh(A(t)) = matrix([[-1/6*I*(sinh((5+3*I)*t)+3*I*s...

Each element of this matrix may be written in a more compact form, which appears to be identical to the corresponding element of the resultant matrix of Method 1. Thus, the above matrix may be rebuilt by replacing its original elements with the re-arranged elements of matrix sinh(A(t))[C_H] . Consequently, the same matrix elements are used as in Method 1, which are assigned values in the following manner:

> for i to rowdim(`sinh(A(t))`) do for j to coldim(`sinh(A(t))`) do `sinh(A(t))`[i,j] := `sinh(A(t))[C_H]`[i,j] : od : od :

Substitute the above elements into the matrix sinh( [ A ( t ) ] ) and add a distinguishing subscript, say, s_m ( s imilarity of m atrices) to the name of the resultant matrix for future comparative purposes:

> `sinh(A(t))[s_m]` := matrix(`sinh(A(t))`) : sinh(A(t))[s_m] = matrix(`sinh(A(t))[s_m]`) ;

sinh(A(t))[s_m] = matrix([[(1/2-1/6*I)*sinh((5+3*I)...

Therefore, the symbolic forms of matrices sinh(A(t))[C_H] and sinh(A(t))[s_m] are equal.

Method 3 . Using truncated Maclaurin’ s series

Step 1 . Find the eigenvalues of [ A ( t ) ]:

This step was already done earlier to check if the eigenvalues of [ A ( t ) ] are distinct, which was essential for both preceding methods. It is not necessary for this method since the series of sinh(x) is convergent for all x , which implies that sinh( [ A ( t ) ] ) is well defined for every square matrix.

Step 2 . Write the expression for Maclaurin’ s series representing the function sinh(x) and substitute the matrix name for x :

> `sinh(A(t))` := subs(x=A(t), Sum(x^(2*n+1)/(2*n+1)!, n=0..infinity)) : sinh(A(t)) = `sinh(A(t))` ;

sinh(A(t)) = Sum(A(t)^(2*n+1)/(2*n+1)!,n = 0 .. inf...

Step 3 . Substitute the matrix name with its corresponding matrix structure:

> `sinh(A(t))` := subs(A(t)=B(t), `sinh(A(t))`) : sinh(A(t)) = `sinh(A(t))` ;

sinh(A(t)) = Sum(matrix([[6*t, -5*t], [2*t, 4*t]])^...

Step 4 . Evaluate the matrix sinh( [ A ( t ) ] ) with its symbolic elements after truncating the series to its first 50 terms.

Since displaying of the matrix for a large number of terms of the Maclaurin series is impractical, only n = 3 is adopted at this point and the matrix thus obtained is displayed for instructive purposes upon simplification and sorting of its elements:

> `sinh(A(t))`:=map(sort, map(simplify, evalm(subs(A(t)=B(t), sum(A(t)^(2*n+1)/(2*n+1)!, n=0..3))))) :

> sinh(A(t)) = matrix(`sinh(A(t))`) ;

sinh(A(t)) = matrix([[-4778/105*t^7-643/15*t^5+28/3...

In final computation, n = 50 is adopted and the resultant matrix is added a distinguishing subscript, say, M_s ( M aclaurin’ s s eries ) to its name for future comparative purposes. Moreover, the functions simplify and sort are dropped, which results in a significant saving of computation time.

Thus, the final expression for sinh( [ A ( t ) ] ) computed by this method is adopted as follows:

> `sinh(A(t))[M_s]`:= evalm(subs(A(t)=B(t), sum(A(t)^(2*n+1)/(2*n+1)!, n=0..50))) :

> sinh(A(t))[M_s] = subs(x=B(t), Sum(x^(2*n+1)/(2*n+1)!, n=0..50)) ; B(t) := 'B(t)' :

sinh(A(t))[M_s] = Sum(matrix([[6*t, -5*t], [2*t, 4*...

Comparison of numerical results of computation of sinh( [ A ( t ) ] )

Compute sinh( [ A ( t ) ] ) if t = .5 using all the three methods.

> t := 0.5 :

(a) For Method 1 using the Cayley-Hamilton theorem:

> `sinh(A(t))[C_H]` := map(x->eval(x), `sinh(A(t))[C_H]`) : sinh(A('t'))[C_H] = matrix(`sinh(A(t))[C_H]`) ;

sinh(A(t))[C_H] = matrix([[2.466950538+0.*I, -10.19...

Disregarding the meaningless imaginary parts simplifies the above to

> `sinh(A(t))[C_H]` := evalm(Re(`sinh(A(t))[C_H]`)) : sinh(A('t'))[C_H] = matrix(`sinh(A(t))[C_H]`) ;

sinh(A(t))[C_H] = matrix([[2.466950538, -10.1948800...

(b) For Method 2 using similarity of matrices:

> `sinh(A(t))[s_m]`:=map(x->eval(x), `sinh(A(t))[s_m]`) : sinh(A('t'))[s_m]=matrix(`sinh(A(t))[s_m]`) ;

sinh(A(t))[s_m] = matrix([[2.466950538+0.*I, -10.19...

Disregarding the meaningless imaginary parts simplifies the above to

> `sinh(A(t))[s_m]` := evalm(Re(`sinh(A(t))[s_m]`)) : sinh(A('t'))[s_m] = matrix(`sinh(A(t))[s_m]`) ;

sinh(A(t))[s_m] = matrix([[2.466950538, -10.1948800...

(c) For Method 3 using truncated Maclaurin’ s series:

> `sinh(A(t))[M_s]` := evalf(map(x->eval(x), `sinh(A(t))[M_s]`)) :

> sinh(A('t'))[M_s] = matrix(`sinh(A(t))[M_s]`) ; t := 't' :

sinh(A(t))[M_s] = matrix([[2.466950540, -10.1948800...

The matrices of (a) and (b) are precisely equal and the matrix of (c) may be considered practically equal to the former ones.

* * *

Example 3

Compute exp( [ A ( t ) ] ) for a ( 2 × 2 ) matrix [ A ( t ) ] given as

> A(t) := matrix(2, 2, [0, t, -t, 0]) : 'A(t)' = A(t) ;

A(t) = matrix([[0, t], [-t, 0]])

The power series of exp(x) is convergent for all x [refer to Unit (23)], which implies that exp( [ A ] ) is well defined for every square matrix. This, in turn, means that the function exp( [ A ( t ) ] ) is well defined for every value of t , so it may be computed for this matrix.

* * *

N.B. The above matrix [ A ( t ) ] may be written equivalently as the product of a constant matrix [ A ] given as

> A := matrix(2, 2, [0, 1, -1, 0]) : A = matrix(A) ;

A = matrix([[0, 1], [-1, 0]])

and the scalar t , viz.

> A*t = matrix(A) * t ;

A*t = matrix([[0, 1], [-1, 0]])*t

since the product [ A ] t evaluates to the matrix

> `At` := evalm(A * t) : A*t = matrix(`At`) ;

A*t = matrix([[0, t], [-t, 0]])

This easy observation has a deeper meaning when special applications of the function exp([ A ] t ) are examined in Unit (30).

> A := 'A' : A(t) := matrix(`At`) :

* * *

The exponential function of a square matrix may be computed in Maple directly , using the exponential function – refer also to Units (23) and (24). Therefore, computation of exp( [ A ( t ) ] ) using this function is also included in this example as Method 4.

For convenience in computations, let

> B(t) := A(t) : A(t) := 'A(t)' :

Method 1 . Using the Cayley-Hamilton theorem

Step 1 . Having in mind that n = 2 for this matrix, write equation (1) of Unit (23) B for [ A ( t ) ]:

> `exp(A(t))` := a[1] * A(t) + a[0]*U : exp(A(t)) = `exp(A(t))` ; Exp(A(t)) := `exp(A(t))` :

exp(A(t)) = a[1]*A(t)+a[0]*U

Step 2 . With the unit matrix [ U ] as in Example 1, evaluate the matrix equation for exp( [ A ( t ) ] ):

> `exp(A(t))` := evalm(subs(A(t)=B(t), `exp(A(t))`)) : exp(A(t)) = matrix(`exp(A(t))`) ;

exp(A(t)) = matrix([[a[0], a[1]*t], [-a[1]*t, a[0]]...

Step 3 . Formulate equation (2) of Unit (23) B corresponding to this case:

> `r(l)` := subs(A(t)=l, U=1, Exp(A(t))) : r(l) = `r(l)` ;

r(lambda) = a[1]*lambda+a[0]

Step 4 . Determine the eigenvalues of [ A ( t ) ]:

> charroots(A(t)) := eigenvals(subs(A(t)=B(t), A(t))) : char_roots(A(t)) = charroots(A(t)) ;

char_roots(A(t)) = (I*t, -I*t)

Extracting the individual eigenvalues lambda[i] yields

> No_roots(A(t)) := nops([charroots(A(t))]) :

> for i to No_roots(A(t)) do ch_r[i](A(t)) := charroots(A(t))[i] : print(l[i] = ch_r[i](A(t))) : od :

lambda[1] = I*t

lambda[2] = -I*t

Step 5 . Taking notice of the fact that the roots are distinct, formulate equation (3) of Unit (23) B in a general form:

Since the function f(lambda) corresponding to this case is

> `f(l)` := exp(l) : f(l) = `f(l)` ;

f(lambda) = exp(lambda)

therefore, equation (3) assumes the form

> Eq3_f(l) := `f(l)` = `r(l)` : Eq3_f(l) ;

exp(lambda) = a[1]*lambda+a[0]

Step 6 . Obtain a set of equations by substituting either eigenvalue into equation (3):

> for i to No_roots(A(t)) do Eq3_f[i](l) := subs(l=ch_r[i](A(t)), Eq3_f(l)) : print(Eq3_f[i](l)) : od :

exp(I*t) = I*a[1]*t+a[0]

exp(-I*t) = -I*a[1]*t+a[0]

Step 7 . Solve the simultaneous equations for the unknown coefficients:

> solution := solve({Eq3_f[1](l), Eq3_f[2](l)}, {a[0], a[1]}) : solution ;

{a[0] = 1/2*exp(-I*t)+1/2*exp(I*t), a[1] = 1/2*I*(-...

Extracting either unknown from the solution set yields

> assign(solution) : for i to No_roots(A(t)) do a[i-1] := a[i-1] : print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = 1/2*exp(-I*t)+1/2*exp(I*t)

a[1] = 1/2*I*(-exp(I*t)+exp(-I*t))/t

Simplification of either coefficient gives

> for i to No_roots(A(t)) do a[i-1] := simplify(a[i-1]) : print(evaln(a[i-1]) = a[i-1]) : od :

a[0] = cos(t)

a[1] = sin(t)/t

Step 8 . Substitute the values of the coefficients into the matrix exp( [ A ( t ) ] and add a distinguishing subscript, say, C_H ( C ayley- H amilton) to the name of the resultant matrix for future comparative purposes:

> `exp(A(t))[C_H]` := map(x->eval(x), `exp(A(t))`) : exp(A(t))[C_H] = matrix(`exp(A(t))[C_H]`) ;

exp(A(t))[C_H] = matrix([[cos(t), sin(t)], [-sin(t)...

> for i to No_roots(A(t)) do a[i-1] := evaln(a[i-1]) : od :

Method 2 . Using similarity of matrices

Step 1 . Check if the eigenvalues of [ A ( t ) ] are distinct:

See Step 4 above where the eigenvalues are found to be distinct.

Step 2 . Find the sequence of lists containing eigenvalues and eigenvectors of [ A ( t ) ]:

> `roots&vectors(A(t))` := eigenvects(subs(A(t)=B(t), A(t))) :

> roots_and_vectors(A(t)) = `roots&vectors(A(t))` ;

roots_and_vectors(A(t)) = ([I*t, 1, {vector([-I, 1]...

Step 3 . Extract the eigenvectors v[lambda[i]] corresponding to eigenvalues lambda[i] of [ A ( t ) ]:

> for i to No_roots(A(t)) do e[i] := charroots(A(t))[i] : List[i] := `roots&vectors(A(t))`[i] : od :

> for j to No_roots(A(t)) do for i to No_roots(A(t)) do if List[i][1] = e[j] then Lst[j] := `roots&vectors(A(t))`[i] : fi : od : od :

> for i to No_roots(A(t)) do ch_v[i](A(t)) := op(Lst[i][3]) : print(v[lambda[i]] = eval(ch_v[i](A(t))), ` --> ` * lambda[i] = ch_r[i](A(t))) : od :

v[lambda[1]] = vector([-I, 1]), `  -->  `*lambda[1]...

v[lambda[2]] = vector([I, 1]), `  -->  `*lambda[2] ...

Conversion of the eigenvectors v[lambda[i]] into column matrices X[lambda[i]] yields

> for i to No_roots(A(t)) do X[l[i]] := convert(ch_v[i](A(t)), matrix) : print(X[l[i]] = matrix(X[l[i]])) : od :

X[lambda[1]] = matrix([[-I], [1]])

X[lambda[2]] = matrix([[I], [1]])

Step 4 . Construct the 'unique' modal matrix [ M ( t ) ] associated with [ A ( t ) ]:

> i := 'i' : `seq(X[l[i]])` := seq(X[l[i]], i=1..coldim(B(t))) : M(t) := augment(`seq(X[l[i]])`) : 'M(t)'=M(t) ;

M(t) = matrix([[-I, I], [1, 1]])

Step 5 . Construct the unique Jordan form [ J ( t ) ] of [ A ( t ) ]:

> J_A := array(diagonal, 1..rowdim(B(t)), 1..coldim(B(t))) :

> for i to rowdim(B(t)) do for j to coldim(B(t)) do if j = i then J_A[i,j] := ch_r[i](A(t)) fi : od : od :

> J(t) := matrix(J_A) : 'J(t)' = J(t) ;

J(t) = matrix([[I*t, 0], [0, -I*t]])

Step 6 . Compute the function exponential of matrix [ J ( t ) ]:

> J_A := array(diagonal, 1..rowdim(J(t)), 1..coldim(J(t))) :

> for i to rowdim(J(t)) do for j to coldim(J(t)) do if j = i then J_A[i,j] := exp(J(t)[i,j]) fi : od : od :

> `exp(J(t))` := matrix(J_A) : exp('J(t)') = matrix(`exp(J(t))`) ;

exp(J(t)) = matrix([[exp(I*t), 0], [0, exp(-I*t)]])...

Step 7 . Compute exp( [ A ( t ) ] ) = [ M ( t ) ] exp( [ J ( t ) ] ) Inv [ M ( t ) ] :

> `exp(A(t))`:= evalm(M(t) &* `exp(J(t))` &* M(t)^(-1)) : exp(A(t))=matrix(`exp(A(t))`) ;

exp(A(t)) = matrix([[1/2*exp(-I*t)+1/2*exp(I*t), -1...

Simplify the above matrix and add a distinguishing subscript, say, s_m ( s imilarity of m atrices) to the name of the resultant matrix for f