Ninth Class (Wednesday 25 October 1995)

Goals to accomplish during class

  1. Know about appropriate uses of technology.
  2. Be able to work with matrices in Maple.
  3. Be able to typeset matrices in LaTeX.

Activity in the lecture room

Comments on the previous class and on the homework

Last time we discussed good style in writing mathematics. Here are some recommended books about writing (mathematics) stylishly.

For the homework problem about finding the volume enclosed by two intersecting cylinders, there were two popular solutions.

  1. Find the volume of the piece in the first octant by doing a triple integral, and multiply by eight. This method gives
  2. Use Cavalieri's principle, which says that the volume of a loaf of bread is the integral of the area of a thin slice of bread. Since the cross sections of the volume enclosed by the two cylinders are squares, their areas are simple to determine. This method leads to the integral

Both methods yield the answer 16/3.

Here are some typical Maple plots to illustrate the problem and to exhibit the squares.

Activity in the computer lab

Matrices in Maple

You all know and love systems of simultaneous linear equations. We have seen that one way to solve linear systems is via Maple's solve command. For example, if you set

eqns := {u+v+w=1, 3*u+v=3, u-2*v-w=0};

then you can solve(eqns); to get numerical values for the variables u, v, and w.

Matrices are often an efficient way to handle linear systems. Let's see how Maple deals with matrices.

Open up a Maple session, and load Maple's linear algebra package via the with(linalg): command. (Do not be concerned if you get a message from Maple about new definitions for norm and trace. This message is normal.)

Maple views a matrix as a list of lists. Therefore you can define a matrix with the name A via

A:=matrix( [ [9,13,17], [14,18,22] ] );

Alternatively, you can specify the number of rows and number of columns and give a single list (which Maple will then break up into the appropriate rows). Thus, another way to specify the above matrix is

A:=matrix(2, 3, [9,13,17,14,18,22] );

Still another way to define a matrix is to specify a formula for the entries in terms of the row and column indices. For example, the above matrix can be generated via

A:=matrix(2,3, (i,j)->5*i+4*j);

After you have defined the above matrix A, what happens if you ask Maple for the value A;? If you want to see the entries displayed, you must ask Maple for matrix evaluation via evalm(A);.


Exercise: Use a matrix command to make Maple display the 4x4 Hilbert matrix whose entry in the ith row and jth column is 1/(i+j-1). This matrix shows up in numerical analysis, where it is a standard example of an ill-conditioned matrix. The Hilbert matrix is sufficiently common that Maple has a built-in hilbert command. For comparison with your solution, try the hilbert(4); command.


Maple knows the standard matrix operations of addition, subtraction, multiplication, scalar multiplication, forming inverses, and exponentiation. For the 2x3 matrix A that you defined above, try evalm(A+A); and evalm(4*A); for example.

Since A is a 2x3 matrix, it is not possible to multiply A by itself. Does Maple complain if you ask it for A^2;? Try it. Now try evalm(A^2);.

Since Maple uses the asterisk * for scalar multiplication, Maple needs a different symbol for matrix multiplication. Maple uses &* for matrix multiplication.

The above matrix A is a 2x3 matrix, so its transpose is a 3x2 matrix. Therefore you can multiply A by its transpose (in either order). Try evalm(A&*transpose(A)); to evaluate this product. An alternate syntax that computes the same result is multiply(A, transpose(A));. Do you get the same answer if you form the product in the other order via multiply(transpose(A), A);?

Define B:=evalm(A&*transpose(A));. What does Maple do if you ask for 1/B;? How about B^(-1);? What about evalm(1/B);?

You can also use inverse(B); to display the inverse of a matrix. What happens if you ask for inverse(transpose(A)&*A);? Can you now predict what det(transpose(A)&*A); will return?

Maple can perform operations on the individual entries of a matrix. Try map(sin,A); map(evalf,"); for example. You can also refer to individual entries of a matrix. For example, A[2,3]; picks out the entry of A that is in the second row and third column.


Exercise continued: Try the following Maple commands.

Digits:=3; C:=hilbert(4):
inverse(map(evalf,C)); inverse(C);

These commands compute (a) the inverse of a three-digit numerical approximation to the Hilbert matrix and (b) the exact inverse of the Hilbert matrix. Do you see any resemblance between the two inverses? Does this explain the terminology "ill-conditioned"?


Matrices in LaTeX

If Maple can compute it, then LaTeX can typeset it. The Maple command latex(evalm(A)); will produce the following LaTeX code. (I have put in some extra carriage returns for clarity.)

\left[
\begin {array}{ccc}
9&13&17\\
\noalign{\medskip}
14&18&22
\end {array}
\right]

If you put this code inside a LaTeX displaymath environment, you will get the matrix A typeset. (Since matrices are large, they are almost always set as displays.) Here are some points to observe about this code.

(If you \usepackage{amsmath}, and you are willing to settle for centered entries in matrices, then you can replace the array environment with the matrix environment, which does better spacing. The amsmath package also has a pmatrix environment that has enclosing parentheses built in.)

Exercise: Typeset the following matrix. Hint: make Maple do (most of) the work. The (i,j) entry of the matrix is the anti-derivative of the fraction (x^2+i)/(x^2+j).

More matrices with Maple: a simple cipher

As an application of matrices, let's implement a simple cipher. In doing this, we will also see an example of a simple Maple program.

At this point, it would be a good idea to reinitialize your Maple session. (On the File menu, click on New. Then load with(linalg): again.) We are going to be using the alphabetic characters as names for themselves, so if you have A and B defined as matrices, it may cause problems.

The idea behind the cipher is first to translate letters into numbers via A->1, B->2, and so on. After translating a message into a string of numbers, encode the message in the following way. Break the string of numbers into blocks of five, view these blocks as the rows of a matrix, and multiply this matrix on the right by a specified 5x5 matrix. This renders the message unintelligible. However, if the recipient of the message knows the matrix (and hence the inverse matrix), then the recipient can recover the original plain text.

To make the procedure a little more sophisticated, we will do the arithmetic modulo 59.

Here is the 5x5 matrix we will use.

      [ 47  41  31  33  56 ]
      [                    ]
      [  1  12  27  12  57 ]
      [                    ]
      [ 41   1  28  53  58 ]
      [                    ]
      [ 35  24  32  23  34 ]
      [                    ]
      [ 19   9  29   6  26 ]

I generated this random matrix via map(x->modp(x,59), randmatrix(5,5));.

You can cut and paste the definition of the matrix into Maple via

Mtrx:=matrix([[47,41,31,33,56],[1,12,27,12,57],
[41,1,28,53,58],[35,24,32,23,34],[19,9,29,6,26]]);

(I generated this list format for the matrix via convert(",listlist);.)

Your task is to follow the hints to decode this message:

    [ 10  54  21  45  52 ]
    [                    ]
    [ 52   3  57   6  38 ]
    [                    ]
    [ 52   8   8  39  56 ]
    [                    ]
    [ 17   9  56  35  10 ]
    [                    ]
    [  5  27  53   1  23 ]
    [                    ]
    [ 45  17  20   6  27 ]
    [                    ]
    [ 11  19  27  29   6 ]
    [                    ]
    [ 49  35  38  19  43 ]
    [                    ]
    [ 10  50   2   6  23 ]
    [                    ]
    [ 21  11  52  32   4 ]
    [                    ]
    [ 53  21   9  50  43 ]
    [                    ]
    [  5  27  53   1  23 ]
    [                    ]
    [ 36  41  41  49  11 ]
    [                    ]
    [ 17  25  47  25  18 ]
    [                    ]
    [ 49  40  46  19   4 ]
    [                    ]
    [ 42  53  22   3  57 ]
    [                    ]
    [ 48  18   7   9  38 ]
    [                    ]
    [ 29  34  45   0  58 ]
    [                    ]
    [ 13  46  27  46  17 ]
    [                    ]
    [ 52  13  55  35  45 ]
    [                    ]
    [ 30  44   4  42  15 ]

To get this message into your Maple session, cut and paste

Secret:=matrix([[10,54,21,45,52],[52,3,57,6,38],
[52,8,8,39,56],[17,9,56,35,10],
[5,27,53,1,23],[45,17,20,6,27],
[11,19,27,29,6],[49,35,38,19,43],
[10,50,2,6,23],[21,11,52,32,4],
[53,21,9,50,43],[5,27,53,1,23],
[36,41,41,49,11],[17,25,47,25,18],
[49,40,46,19,4],[42,53,22,3,57],
[48,18,7,9,38],[29,34,45,0,58],
[13,46,27,46,17],[52,13,55,35,45],
[30,44,4,42,15]]);

To create the secret message, I first defined a list of the alphabetic characters. This requires a little care. First of all, Maple thinks that I represents the square root of minus one, so I had to undo this convention by aliasing I to itself. Also, I gave punctuation characters symbolic names to avoid confusion (since Maple uses some punctuation characters for special purposes). Here are my definitions, which you will need to copy into your Maple session.

space:=` `: period:=`.`: comma:=`,`: semicolon:=`;`:
colon:=`:`: bang:=`!`: query:=`?`: alias(I=I);
Alphabet:=[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,
S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
q,r,s,t,u,v,w,x,y,z,space,period,comma,
semicolon,colon,bang,query];

Now if you ask Maple for Alphabet[28]; for example, you should get the 28th element of the list Alphabet, which is the lower case letter b.

To convert numbers into letters, define a function NumToAlph as follows.

NumToAlph:=n->Alphabet[ modp(n-1,59) +1 ];

The reason for adding and subtracting 1 in this definition is that modp returns values between 0 and 58, while the index parameter for the list Alphabet runs from 1 to 59. Test this definition by checking NumToAlph(5); and NumToAlph(50); for example.

You can define an inverse function AlphToNum that converts letters into numbers by executing the following do loop.

for counter from 1 to 59 do
  AlphToNum(Alphabet[counter]):=counter:
od:

Notice that there is no semicolon after the do. (Usually one writes a do loop in the form for i from 1 to n do, but in this example single letters are reserved as names of alphabetic characters, so I named the counter in the loop "counter" instead of "i".)

Try AlphToNum(a); and AlphToNum(` `); to confirm that the function is defined correctly.

If you have a message written as a list of alphabetic characters, you can convert it into a list of numbers via map(AlphToNum,CharacterList);. Try converting the list [H,e,l,l,o,space,w,o,r,l,d] for example.

Conversely, if you have a list of numbers, you can convert it to a list of letters via map(NumToAlph,NumberList);. Try converting the list [22, 31, 44, 51, 53, 33, 41, 41, 30, 58] for example. You should get a list of letters inside square brackets. To convert this list into words, try cat(op[1](")); to concatenate the letters in the list.

Now see if you can decode the secret message. You need to multiply the message on the right by the inverse of the matrix Mtrx and then convert back to alphabetic characters.


Exercise: Use Mtrx to encode your own message. Send the message by e-mail to your neighbor for decoding.

Tip: One problem I had to solve before converting my secret message into numeric form was how to change a string of characters into a comma-separated list. (Of course, I could have typed in all the commas, but that would have been tedious.) I wrote the following little Maple procedure. (Maple programs are called procedures. Chapter 13 of the CalcLabs with Maple V manual is an introduction to programming with Maple.)

MessageToList:=proc(Message)
  local cntr,MessageList;
      MessageList := NULL;
      for cntr to length(Message) do
          MessageList := MessageList,substring(Message,cntr .. cntr);
      od;
      MessageList := [MessageList];
end;

Here is a line-by-line explanation of this procedure.

MessageToList:=proc(Message)
This defines a new function named MessageToList. The proc is a Maple keyword that indicates the beginning of a procedure (a program). This procedure defines a function that has one argument, which is named Message. Here Message acts as a dummy variable.
local cntr,MessageList;
The procedure uses two internal variables, which are declared to be local to the procedure. The variable cntr is going to be a counter for a loop, and the variable MessageList is going to hold the comma-separated list.
MessageList := NULL;
This initializes the variable MessageList to be an empty string.
for cntr to length(Message) do
This starts a loop. Notice that there is no semicolon after the do. By default, the counter cntr starts at 1, and it is incremented by one unit each time through the loop. The loop terminates when the counter reaches the length of the string Message (the string that is the input to the procedure).
MessageList := MessageList,substring(Message,cntr .. cntr);
Here the substring function picks out of Message the part starting at the position of the counter and ending at the position of the counter. In other words, it picks out a single character at the position of the counter. Then MessageList is replaced by itself with this character appended following a comma.
od;
This is the word do backwards: it signals the end of the statements that are included in the do loop.
MessageList := [MessageList];
This redefines MessageList to be itself enclosed in brackets, so that it is now a Maple list structure. This list is the output of the procedure.
end;
This marks the end of the procedure.

In summary, this procedure takes one argument Message and runs a loop that picks out each one-character substring at position cntr and appends it to a comma-separated list. The procedure returns that list. The procedure uses two local variables: cntr is the counter for the loop, and MessageList holds the current value of the comma-separated list of characters.

Now executing the Maple command

MessageToList(`Take but degree away, untune that string,
And hark! what discord follows; each thing meets
In mere oppugnancy.
Troilus and Cressida, Act I, scene iii.`);

produces the output

[T, a, k, e,  , b, u, t,  , d, e, g, r, e, e,  , a,

     w, a, y, ,,  , u, n, t, u, n, e,  , t, h, a, t,

      , s, t, r, i, n, g, ,,  , A, n, d,  , h, a, r,

     k, !,  , w, h, a, t,  , d, i, s, c, o, r, d,  ,

     f, o, l, l, o, w, s, ;,  , e, a, c, h,  , t, h,

     i, n, g,  , m, e, e, t, s,  , I, n,  , m, e, r,

     e,  , o, p, p, u, g, n, a, n, c, y, .,  , T, r,

     o, i, l, u, s,  , a, n, d,  , C, r, e, s, s, i,

     d, a, ,,  , A, c, t,  , I, ,,  , s, c, e, n, e,

      , i, i, i, .]

Notice the backquotes ` that I used to convert the poetry into a Maple string. If you cut and paste the poem into Maple, be careful not to introduce newline characters into the string, or Maple will complain.

Going further with matrices in Maple

Homework for after class

  1. LaTeX can nest array environments. Typeset the following matrix. Hint: Maple can assist you; the submatrices are Hilbert matrices.

  2. Continue working on the projects.

/ Home / Contents /


Harold P. Boas

HTML 2.0 Checked! Last modified and validated: Tue Nov 21 16:49:07 1995