diff --git a/books/bookvol10.2.pamphlet b/books/bookvol10.2.pamphlet
index a4ef5e9..211ddc1 100644
--- a/books/bookvol10.2.pamphlet
+++ b/books/bookvol10.2.pamphlet
@@ -12326,9 +12326,1208 @@ digraph pic {
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{MatrixCategory}{MATCAT}
 \pagepic{ps/v102matrixcategory.ps}{MATCAT}{0.60}
+<<MatrixCategory.input>>=
+)set break resume
+)sys rm -f MatrixCategory.output
+)spool MatrixCategory.output
+)set message test on
+)set message auto off
+)clear all
+
+
+--S 1 of 59
+square? matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (1)  true
+--R                                                                Type: Boolean
+--E 1
+
+--S 2 of 59
+diagonal? matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (2)  false
+--R                                                                Type: Boolean
+--E 2
+
+--S 3 of 59
+symmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (3)  false
+--R                                                                Type: Boolean
+--E 3
+
+--S 4 of 59
+antisymmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (4)  false
+--R                                                                Type: Boolean
+--E 4
+
+--S 5 of 59
+z:Matrix(INT):=zero(3,3)
+--R 
+--R
+--R        +0  0  0+
+--R        |       |
+--R   (5)  |0  0  0|
+--R        |       |
+--R        +0  0  0+
+--R                                                         Type: Matrix Integer
+--E 5
+
+--S 6 of 59
+matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+--R 
+--R
+--R        +1  2  3+
+--R        |       |
+--R        |4  5  6|
+--R   (6)  |       |
+--R        |7  8  9|
+--R        |       |
+--R        +1  1  1+
+--R                                                         Type: Matrix Integer
+--E 6
+
+--S 7 of 59
+z:Matrix(INT):=scalarMatrix(3,5)
+--R 
+--R
+--R        +5  0  0+
+--R        |       |
+--R   (7)  |0  5  0|
+--R        |       |
+--R        +0  0  5+
+--R                                                         Type: Matrix Integer
+--E 7
+
+--S 8 of 59
+diagonalMatrix [1,2,3]
+--R 
+--R
+--R        +1  0  0+
+--R        |       |
+--R   (8)  |0  2  0|
+--R        |       |
+--R        +0  0  3+
+--R                                                         Type: Matrix Integer
+--E 8
+
+--S 9 of 59
+diagonalMatrix [matrix [[1,2],[3,4]], matrix [[4,5],[6,7]]]
+--R 
+--R
+--R        +1  2  0  0+
+--R        |          |
+--R        |3  4  0  0|
+--R   (9)  |          |
+--R        |0  0  4  5|
+--R        |          |
+--R        +0  0  6  7+
+--R                                                         Type: Matrix Integer
+--E 9
+
+--S 10 of 59
+coerce([1,2,3])@Matrix(INT)
+--R 
+--R
+--R         +1+
+--R         | |
+--R   (10)  |2|
+--R         | |
+--R         +3+
+--R                                                         Type: Matrix Integer
+--E 10
+
+--S 11 of 59
+transpose([1,2,3])@Matrix(INT)
+--R 
+--R
+--R   (11)  [1  2  3]
+--R                                                         Type: Matrix Integer
+--E 11
+
+--S 12 of 59
+transpose matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1   1    1    1 +
+--R         |                   |
+--R         |1  2   3    4    5 |
+--R         |                   |
+--R   (12)  |1  4   9   16   25 |
+--R         |                   |
+--R         |1  8   27  64   125|
+--R         |                   |
+--R         +1  16  81  256  625+
+--R                                                         Type: Matrix Integer
+--E 12
+
+--S 13 of 59
+squareTop matrix [[j**i for i in 0..2] for j in 1..5]
+--R 
+--R
+--R         +1  1  1+
+--R         |       |
+--R   (13)  |1  2  4|
+--R         |       |
+--R         +1  3  9+
+--R                                                         Type: Matrix Integer
+--E 13
+
+--S 14 of 59
+t1:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (14)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 14
+
+--S 15 of 59
+horizConcat(t1,t1)
+--R 
+--R
+--R         +1  1  1    1    1   1  1  1    1    1 +
+--R         |                                      |
+--R         |1  2  4    8   16   1  2  4    8   16 |
+--R         |                                      |
+--R   (15)  |1  3  9   27   81   1  3  9   27   81 |
+--R         |                                      |
+--R         |1  4  16  64   256  1  4  16  64   256|
+--R         |                                      |
+--R         +1  5  25  125  625  1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 15
+
+--S 16 of 59
+t2:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (16)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 16
+
+--S 17 of 59
+vertConcat(t2,t2)
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R         |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         |1  5  25  125  625|
+--R   (17)  |                  |
+--R         |1  1  1    1    1 |
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R         |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 17
+
+--S 18 of 59
+t3:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (18)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 18
+
+--S 19 of 59
+listOfLists t3
+--R 
+--R
+--R   (19)
+--R   [[1,1,1,1,1],[1,2,4,8,16],[1,3,9,27,81],[1,4,16,64,256],[1,5,25,125,625]]
+--R                                                      Type: List List Integer
+--E 19
+
+--S 20 of 59
+t4:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (20)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 20
+
+--S 21 of 59
+elt(t4,3,3)
+--R 
+--R
+--R   (21)  9
+--R                                                        Type: PositiveInteger
+--E 21
+
+--S 22 of 59
+t5:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (22)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 22
+
+--S 23 of 59
+setelt(t5,3,3,10)
+--R 
+--R
+--R   (23)  10
+--R                                                        Type: PositiveInteger
+--E 23
+
+--S 24 of 59
+t6:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (24)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 24
+
+--S 25 of 59
+swapRows!(t6,2,4)
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R   (25)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 25
+
+--S 26 of 59
+t7:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (26)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 26
+
+--S 27 of 59
+swapColumns!(t7,2,4)
+--R 
+--R
+--R         +1   1   1   1   1 +
+--R         |                  |
+--R         |1   8   4   2  16 |
+--R         |                  |
+--R   (27)  |1  27   9   3  81 |
+--R         |                  |
+--R         |1  64   16  4  256|
+--R         |                  |
+--R         +1  125  25  5  625+
+--R                                                         Type: Matrix Integer
+--E 27
+
+--S 28 of 59
+t8:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (28)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 28
+
+--S 29 of 59
+subMatrix(t8,1,3,2,4)
+--R 
+--R
+--R         +1  1  1 +
+--R         |        |
+--R   (29)  |2  4  8 |
+--R         |        |
+--R         +3  9  27+
+--R                                                         Type: Matrix Integer
+--E 29
+
+--S 30 of 59
+t9:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (30)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 30
+
+--S 31 of 59
+setsubMatrix!(t9,2,2,matrix [[3,3],[3,3]])
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  3  3    8   16 |
+--R         |                  |
+--R   (31)  |1  3  3   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 31
+
+--S 32 of 59
+t0:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (32)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 32
+
+--S 33 of 59
+t0+t0
+--R 
+--R
+--R         +2  2   2    2    2  +
+--R         |                    |
+--R         |2  4   8   16    32 |
+--R         |                    |
+--R   (33)  |2  6   18  54   162 |
+--R         |                    |
+--R         |2  8   32  128  512 |
+--R         |                    |
+--R         +2  10  50  250  1250+
+--R                                                         Type: Matrix Integer
+--E 33
+
+--S 34 of 59
+t0-t0
+--R 
+--R
+--R         +0  0  0  0  0+
+--R         |             |
+--R         |0  0  0  0  0|
+--R         |             |
+--R   (34)  |0  0  0  0  0|
+--R         |             |
+--R         |0  0  0  0  0|
+--R         |             |
+--R         +0  0  0  0  0+
+--R                                                         Type: Matrix Integer
+--E 34
+
+--S 35 of 59
+-t0
+--R 
+--R
+--R         +- 1  - 1  - 1    - 1    - 1 +
+--R         |                            |
+--R         |- 1  - 2  - 4    - 8   - 16 |
+--R         |                            |
+--R   (35)  |- 1  - 3  - 9   - 27   - 81 |
+--R         |                            |
+--R         |- 1  - 4  - 16  - 64   - 256|
+--R         |                            |
+--R         +- 1  - 5  - 25  - 125  - 625+
+--R                                                         Type: Matrix Integer
+--E 35
+
+--S 36 of 59
+t0*t0
+--R 
+--R
+--R         + 5    15    55     225    979  +
+--R         |                               |
+--R         |31   129    573   2637   12405 |
+--R         |                               |
+--R   (36)  |121  547   2551   12121  58315 |
+--R         |                               |
+--R         |341  1593  7585   36561  177745|
+--R         |                               |
+--R         +781  3711  17871  86841  424731+
+--R                                                         Type: Matrix Integer
+--E 36
+
+--S 37 of 59
+1/3*t0
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |-  -  -    -    - |
+--R         |3  3  3    3    3 |
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |-  -  -    -   -- |
+--R         |3  3  3    3    3 |
+--R         |                  |
+--R         |1                 |
+--R   (37)  |-  1  3    9   27 |
+--R         |3                 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |-  -  --  --   ---|
+--R         |3  3   3   3    3 |
+--R         |                  |
+--R         |1  5  25  125  625|
+--R         |-  -  --  ---  ---|
+--R         +3  3   3   3    3 +
+--R                                                Type: Matrix Fraction Integer
+--E 37
+
+--S 38 of 59
+m:=matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |                  |
+--R   (38)  |1  3  9   27   81 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |                  |
+--R         +1  5  25  125  625+
+--R                                                         Type: Matrix Integer
+--E 38
+
+--S 39 of 59
+t0*1/3
+--R 
+--R
+--R         +1  1  1    1    1 +
+--R         |-  -  -    -    - |
+--R         |3  3  3    3    3 |
+--R         |                  |
+--R         |1  2  4    8   16 |
+--R         |-  -  -    -   -- |
+--R         |3  3  3    3    3 |
+--R         |                  |
+--R         |1                 |
+--R   (39)  |-  1  3    9   27 |
+--R         |3                 |
+--R         |                  |
+--R         |1  4  16  64   256|
+--R         |-  -  --  --   ---|
+--R         |3  3   3   3    3 |
+--R         |                  |
+--R         |1  5  25  125  625|
+--R         |-  -  --  ---  ---|
+--R         +3  3   3   3    3 +
+--R                                                Type: Matrix Fraction Integer
+--E 39
+
+--S 40 of 59
+3*t0
+--R 
+--R
+--R         +3  3   3    3    3  +
+--R         |                    |
+--R         |3  6   12  24    48 |
+--R         |                    |
+--R   (40)  |3  9   27  81   243 |
+--R         |                    |
+--R         |3  12  48  192  768 |
+--R         |                    |
+--R         +3  15  75  375  1875+
+--R                                                         Type: Matrix Integer
+--E 40
+
+--S 41 of 59
+c:=coerce([1,2,3,4,5])@Matrix(INT)
+--R 
+--R
+--R         +1+
+--R         | |
+--R         |2|
+--R         | |
+--R   (41)  |3|
+--R         | |
+--R         |4|
+--R         | |
+--R         +5+
+--R                                                         Type: Matrix Integer
+--E 41
+
+--S 42 of 59
+t0*c
+--R 
+--R
+--R         + 15 +
+--R         |    |
+--R         |129 |
+--R         |    |
+--R   (42)  |547 |
+--R         |    |
+--R         |1593|
+--R         |    |
+--R         +3711+
+--R                                                         Type: Matrix Integer
+--E 42
+
+--S 43 of 59
+r:=transpose([1,2,3,4,5])@Matrix(INT)
+--R 
+--R
+--R   (43)  [1  2  3  4  5]
+--R                                                         Type: Matrix Integer
+--E 43
+
+--S 44 of 59
+r*t0
+--R 
+--R
+--R   (44)  [15  55  225  979  4425]
+--R                                                         Type: Matrix Integer
+--E 44
+
+--S 45 of 59
+t0**3
+--R 
+--R
+--R         + 1279    5995     28635     138385    674175  +
+--R         |                                              |
+--R         |15775    74581    358021   1735927    8476705 |
+--R         |                                              |
+--R   (45)  |73655   348927   1677079   8138493   39765355 |
+--R         |                                              |
+--R         |223825  1061251  5103579   24775909  121090455|
+--R         |                                              |
+--R         +533935  2532835  12184195  59162185  289195879+
+--R                                                         Type: Matrix Integer
+--E 45
+
+--S 46 of 59
+t10:=matrix [[2**i for i in 2..4] for j in 1..5]
+--R 
+--R
+--R         +4  8  16+
+--R         |        |
+--R         |4  8  16|
+--R         |        |
+--R   (46)  |4  8  16|
+--R         |        |
+--R         |4  8  16|
+--R         |        |
+--R         +4  8  16+
+--R                                                         Type: Matrix Integer
+--E 46
+
+--S 47 of 59
+exquo(t10,2)
+--R 
+--R
+--R         +2  4  8+
+--R         |       |
+--R         |2  4  8|
+--R         |       |
+--R   (47)  |2  4  8|
+--R         |       |
+--R         |2  4  8|
+--R         |       |
+--R         +2  4  8+
+--R                                              Type: Union(Matrix Integer,...)
+--E 47
+
+--S 48 of 59
+t10/4
+--R 
+--R
+--R         +1  2  4+
+--R         |       |
+--R         |1  2  4|
+--R         |       |
+--R   (48)  |1  2  4|
+--R         |       |
+--R         |1  2  4|
+--R         |       |
+--R         +1  2  4+
+--R                                                Type: Matrix Fraction Integer
+--E 48
+
+--S 49 of 59
+rowEchelon matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         +1  0  0  0  0 +
+--R         |              |
+--R         |0  1  1  1  1 |
+--R         |              |
+--R   (49)  |0  0  2  0  2 |
+--R         |              |
+--R         |0  0  0  6  12|
+--R         |              |
+--R         +0  0  0  0  24+
+--R                                                         Type: Matrix Integer
+--E 49
+
+--S 50 of 59
+columnSpace matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+--R 
+--R
+--R   (50)  [[1,4,7,1],[2,5,8,1]]
+--R                                                    Type: List Vector Integer
+--E 50
+
+--S 51 of 59
+rank matrix [[1,2,3],[4,5,6],[7,8,9]]
+--R 
+--R
+--R   (51)  2
+--R                                                        Type: PositiveInteger
+--E 51
+
+--S 52 of 59
+nullity matrix [[1,2,3],[4,5,6],[7,8,9]]
+--R 
+--R
+--R   (52)  1
+--R                                                        Type: PositiveInteger
+--E 52
+
+--S 53 of 59
+nullSpace matrix [[1,2,3],[4,5,6],[7,8,9]]
+--R 
+--R
+--R   (53)  [[1,- 2,1]]
+--R                                                    Type: List Vector Integer
+--E 53
+
+--S 54 of 59
+determinant matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (54)  288
+--R                                                        Type: PositiveInteger
+--E 54
+
+--S 55 of 59
+minordet matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R   (55)  288
+--R                                                        Type: PositiveInteger
+--E 55
+
+--S 56 of 59
+pfaffian [[0,1,0,0],[-1,0,0,0],[0,0,0,1],[0,0,-1,0]]
+--R 
+--R
+--R   (56)  1
+--R                                                        Type: PositiveInteger
+--E 56
+
+--S 57 of 59
+inverse matrix [[j**i for i in 0..4] for j in 1..5]
+--R 
+--R
+--R         + 5    - 10   10   - 5    1  +
+--R         |                            |
+--R         |  77  107     39   61     25|
+--R         |- --  ---   - --   --   - --|
+--R         |  12   6       2    6     12|
+--R         |                            |
+--R         | 71     59   49     41   35 |
+--R         | --   - --   --   - --   -- |
+--R   (57)  | 24      6    4      6   24 |
+--R         |                            |
+--R         |   7   13          11      5|
+--R         |- --   --   - 3    --   - --|
+--R         |  12    6           6     12|
+--R         |                            |
+--R         |  1     1    1      1     1 |
+--R         | --   - -    -    - -    -- |
+--R         + 24     6    4      6    24 +
+--R                                     Type: Union(Matrix Fraction Integer,...)
+--E 57
+
+--S 58 of 59
+(matrix [[j**i for i in 0..4] for j in 1..5]) ** 2
+--R 
+--R
+--R         + 5    15    55     225    979  +
+--R         |                               |
+--R         |31   129    573   2637   12405 |
+--R         |                               |
+--R   (58)  |121  547   2551   12121  58315 |
+--R         |                               |
+--R         |341  1593  7585   36561  177745|
+--R         |                               |
+--R         +781  3711  17871  86841  424731+
+--R                                                         Type: Matrix Integer
+--E 58
+
+--S 59 of 59
+)show MatrixCategory
+--R 
+--R MatrixCategory(R: Ring,Row: FiniteLinearAggregate t#1,Col: FiniteLinearAggregate t#1)  is a category constructor
+--R Abbreviation for MatrixCategory is MATCAT 
+--R This constructor is exposed in this frame.
+--R Issue )edit bookvol10.2.spad.pamphlet to see algebra source code for MATCAT 
+--R
+--R------------------------------- Operations --------------------------------
+--R ?*? : (Row,%) -> Row                  ?*? : (%,Col) -> Col
+--R ?*? : (Integer,%) -> %                ?*? : (%,R) -> %
+--R ?*? : (R,%) -> %                      ?*? : (%,%) -> %
+--R ?+? : (%,%) -> %                      -? : % -> %
+--R ?-? : (%,%) -> %                      antisymmetric? : % -> Boolean
+--R coerce : Col -> %                     column : (%,Integer) -> Col
+--R copy : % -> %                         diagonal? : % -> Boolean
+--R diagonalMatrix : List % -> %          diagonalMatrix : List R -> %
+--R elt : (%,Integer,Integer,R) -> R      elt : (%,Integer,Integer) -> R
+--R empty : () -> %                       empty? : % -> Boolean
+--R eq? : (%,%) -> Boolean                fill! : (%,R) -> %
+--R horizConcat : (%,%) -> %              listOfLists : % -> List List R
+--R map : (((R,R) -> R),%,%,R) -> %       map : (((R,R) -> R),%,%) -> %
+--R map : ((R -> R),%) -> %               map! : ((R -> R),%) -> %
+--R matrix : List List R -> %             maxColIndex : % -> Integer
+--R maxRowIndex : % -> Integer            minColIndex : % -> Integer
+--R minRowIndex : % -> Integer            ncols : % -> NonNegativeInteger
+--R nrows : % -> NonNegativeInteger       parts : % -> List R
+--R qelt : (%,Integer,Integer) -> R       row : (%,Integer) -> Row
+--R sample : () -> %                      setRow! : (%,Integer,Row) -> %
+--R square? : % -> Boolean                squareTop : % -> %
+--R symmetric? : % -> Boolean             transpose : % -> %
+--R transpose : Row -> %                  vertConcat : (%,%) -> %
+--R #? : % -> NonNegativeInteger if $ has finiteAggregate
+--R ?**? : (%,Integer) -> % if R has FIELD
+--R ?**? : (%,NonNegativeInteger) -> %
+--R ?/? : (%,R) -> % if R has FIELD
+--R ?=? : (%,%) -> Boolean if R has SETCAT
+--R any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+--R coerce : % -> OutputForm if R has SETCAT
+--R columnSpace : % -> List Col if R has EUCDOM
+--R count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+--R count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+--R determinant : % -> R if R has commutative *
+--R elt : (%,List Integer,List Integer) -> %
+--R eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+--R eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+--R eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+--R eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+--R every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+--R exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+--R hash : % -> SingleInteger if R has SETCAT
+--R inverse : % -> Union(%,"failed") if R has FIELD
+--R latex : % -> String if R has SETCAT
+--R less? : (%,NonNegativeInteger) -> Boolean
+--R member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+--R members : % -> List R if $ has finiteAggregate
+--R minordet : % -> R if R has commutative *
+--R more? : (%,NonNegativeInteger) -> Boolean
+--R new : (NonNegativeInteger,NonNegativeInteger,R) -> %
+--R nullSpace : % -> List Col if R has INTDOM
+--R nullity : % -> NonNegativeInteger if R has INTDOM
+--R pfaffian : % -> R if R has COMRING
+--R qsetelt! : (%,Integer,Integer,R) -> R
+--R rank : % -> NonNegativeInteger if R has INTDOM
+--R rowEchelon : % -> % if R has EUCDOM
+--R scalarMatrix : (NonNegativeInteger,R) -> %
+--R setColumn! : (%,Integer,Col) -> %
+--R setelt : (%,List Integer,List Integer,%) -> %
+--R setelt : (%,Integer,Integer,R) -> R
+--R setsubMatrix! : (%,Integer,Integer,%) -> %
+--R size? : (%,NonNegativeInteger) -> Boolean
+--R subMatrix : (%,Integer,Integer,Integer,Integer) -> %
+--R swapColumns! : (%,Integer,Integer) -> %
+--R swapRows! : (%,Integer,Integer) -> %
+--R zero : (NonNegativeInteger,NonNegativeInteger) -> %
+--R ?~=? : (%,%) -> Boolean if R has SETCAT
+--R
+--E 59
+
+)spool
+)lisp (bye)
+ 
+@
+<<MatrixCategory.help>>=
+====================================================================
+MatrixCategory examples
+====================================================================
+
+Predicates:
+
+square?(m) returns true if m is a square matrix
+(if m has the same number of rows as columns) and false otherwise.
+
+  square matrix [[j**i for i in 0..4] for j in 1..5]
+
+diagonal?(m) returns true if the matrix m is square and
+diagonal (i.e. all entries of m not on the diagonal are zero) and
+false otherwise.
+
+  diagonal? matrix [[j**i for i in 0..4] for j in 1..5]
+
+symmetric?(m) returns true if the matrix m is square and
+symmetric (i.e. \spad{m[i,j] = m[j,i]} for all i and j) and false
+otherwise.
+
+  symmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+
+antisymmetric?(m) returns true if the matrix m is square and
+antisymmetric (i.e. m[i,j] = -m[j,i] for all i and j) 
+and false otherwise.
+
+  antisymmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+
+
+Creation
+
+zero(m,n) returns an m-by-n zero matrix.
+
+  z:Matrix(INT):=zero(3,3)
+
+matrix(l) converts the list of lists l to a matrix, where the
+list of lists is viewed as a list of the rows of the matrix.
+
+  matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+
+scalarMatrix(n,r) returns an n-by-n matrix with r's on the
+diagonal and zeroes elsewhere.
+
+  z:Matrix(INT):=scalarMatrix(3,5)
+
+diagonalMatrix(l) returns a diagonal matrix with the elements
+of l on the diagonal.
+
+  diagonalMatrix [1,2,3]
+
+diagonalMatrix([m1,...,mk]) creates a block diagonal matrix
+M with block matrices m1,...,mk down the diagonal,
+with 0 block matrices elsewhere.
+
+More precisly: if ri := nrows mi, ci := ncols mi,
+then m is an (r1+..+rk) by (c1+..+ck) - matrix  with entries
+m.i.j = ml.(i-r1-..-r(l-1)).(j-n1-..-n(l-1)), 
+if (r1+..+r(l-1)) < i <= r1+..+rl and
+   (c1+..+c(l-1)) < i <= c1+..+cl,
+    m.i.j = 0  otherwise.
+
+  diagonalMatrix [matrix [[1,2],[3,4]], matrix [[4,5],[6,7]]]
+
+coerce(col) converts the column col to a column matrix.
+
+  coerce([1,2,3])@Matrix(INT)
+
+transpose(r) converts the row r to a row matrix.
+
+  transpose([1,2,3])@Matrix(INT)
+
+Creation of new matrices from old
+
+transpose(m) returns the transpose of the matrix m.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  transpose m
+
+squareTop(m) returns an n-by-n matrix consisting of the first
+n rows of the m-by-n matrix m. Error: if m < n.
+
+  m:=matrix [[j**i for i in 0..2] for j in 1..5]
+  squareTop m
+
+horizConcat(x,y) horizontally concatenates two matrices with
+an equal number of rows. The entries of y appear to the right
+of the entries of x.  Error: if the matrices
+do not have the same number of rows.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  horizConcat(m,m)
+
+vertConcat(x,y) vertically concatenates two matrices with an
+equal number of columns. The entries of y appear below
+of the entries of x.  Error: if the matrices
+do not have the same number of columns.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  vertConcat(m,m)
+
+Part extractions/assignments
+
+listOfLists(m) returns the rows of the matrix m as a list of lists
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  listOfLists m
+
+elt(x,rowList,colList) returns an m-by-n matrix consisting
+of elements of x, where m = # rowList and n = # colList
+If rowList = [i<1>,i<2>,...,i<m>] and 
+   colList = [j<1>,j<2>,...,j<n>], 
+ then the (k,l)-th entry of elt(x,rowList,colList) is x(i<k>,j<l>).
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  elt(m,3,3)
+
+setelt(x,rowList,colList,y) destructively alters the matrix x.
+If y is m-by-n, 
+   rowList = [i<1>,i<2>,...,i<m>] and
+   colList = [j<1>,j<2>,...,j<n>], 
+ then x(i<k>,j<l>)
+ is set to y(k,l) for k = 1,...,m and l = 1,...,n
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  setelt(m,3,3,10)
+
+swapRows!(m,i,j) interchanges the i-th and j-th
+rows of m. This destructively alters the matrix.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  swapRows!(m,2,4)
+
+swapColumns!(m,i,j) interchanges the i-th and j-th
+columns of m. This destructively alters the matrix.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  swapColumns!(m,2,4)
+
+subMatrix(x,i1,i2,j1,j2) extracts the submatrix [x(i,j)] 
+where the index i ranges from i1 to i2
+and   the index j ranges from j1 to j2.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  subMatrix(m,1,3,2,4)
+
+setsubMatrix(x,i1,j1,y) destructively alters the matrix x. 
+Here x(i,j) is set to y(i-i1+1,j-j1+1) for
+i = i1,...,i1-1+nrows y and j = j1,...,j1-1+ncols y.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  setsubMatrix!(m,2,2,matrix [[3,3],[3,3]])
+
+
+Arithmetic
+
+x + y is the sum of the matrices x and y.
+It is an error if the dimensions are incompatible.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  m+m
+
+x - y is the difference of the matrices x and y.
+It is an error if the dimensions are incompatible.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  m-m
+
+-x returns the negative of the matrix x.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  -m
+
+x * y is the product of the matrices x and y.
+It is an error if the dimensions are incompatible.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  m*m
+
+r*x is the left scalar multiple of the scalar r and the matrix x.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  1/3*m
+
+x * r is the right scalar multiple of the scalar r and the matrix x.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  m*1/3
+
+n * x is an integer multiple.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  3*m
+
+x * c is the product of the matrix x and the column vector c.
+It is an error if the dimensions are incompatible.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  c:=coerce([1,2,3,4,5])@Matrix(INT)
+  m *c
+
+r * x is the product of the row vector r and the matrix x.
+It is an error if the dimensions are incompatible.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  r:=transpose([1,2,3,4,5])@Matrix(INT)
+  r*m
+
+x ** n computes a non-negative integral power of the matrix x.
+It is an error if the matrix is not square.
+
+  m:=matrix [[j**i for i in 0..4] for j in 1..5]
+  m**3
+
+exquo(m,r) computes the exact quotient of the elements
+of m by r, returning "failed" if this is not possible.
+
+  m:=matrix [[2**i for i in 2..4] for j in 1..5]
+  exquo(m,2)
+
+m/r divides the elements of m by r, r must be non-zero.
+
+  m:=matrix [[2**i for i in 2..4] for j in 1..5]
+  m/4
+
+Linear algebra
+
+rowEchelon(m) returns the row echelon form of the matrix m.
+
+  rowEchelon matrix [[j**i for i in 0..4] for j in 1..5]
+
+columnSpace(m) returns a sublist of columns of the matrix m
+
+  columnSpace matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+
+rank(m) returns the rank of the matrix m.
+
+  rank matrix [[1,2,3],[4,5,6],[7,8,9]]
+
+nullity(m) returns the nullity of the matrix m. This is
+the dimension of the null space of the matrix m.
+
+  nullity matrix [[1,2,3],[4,5,6],[7,8,9]]
+
+nullSpace(m) returns a basis for the null space of the matrix m.
+
+  nullSpace matrix [[1,2,3],[4,5,6],[7,8,9]]
+
+determinant(m) returns the determinant of the matrix m.
+It is an error if the matrix is not square.
+
+  determinant matrix [[j**i for i in 0..4] for j in 1..5]
+
+minordet(m) computes the determinant of the matrix m using minors. 
+It is an error if the matrix is not square.
+
+  minordet matrix [[j**i for i in 0..4] for j in 1..5]
+
+pfaffian(m) returns the Pfaffian of the matrix m.
+It is an error if the matrix is not antisymmetric
+
+  pfaffian [[0,1,0,0],[-1,0,0,0],[0,0,0,1],[0,0,-1,0]]
+
+inverse(m) returns the inverse of the matrix m.
+If the matrix is not invertible, "failed" is returned.
+It is an error if the matrix is not square.
+
+  inverse matrix [[j**i for i in 0..4] for j in 1..5]
+
+m**n computes an integral power of the matrix m.
+It is an error if matrix is not square or 
+if the matrix is square but not invertible.
+
+  (matrix [[j**i for i in 0..4] for j in 1..5]) ** 2
+
+@
+
+We define three categories for matrices
+\begin{itemize}
+\item MatrixCategory is the category of all matrices
+\item RectangularMatrixCategory is the category of all matrices 
+of a given dimension
+\item SquareMatrixCategory inherits from RectangularMatrixCategory
+\end{itemize}
+
+The Matrix domain is the domain of all matrices.
+
+All three domains share the same representation, inherited from Matrix.
+Most algorithms are only implemented for Matrix but implemented in
+separate packages.
+
+\begin{itemize}
+\item MatrixLinearAlgebraFunctions is the top-level package that calls
+the other packages
+\item InnerMatrixLinearAlgebraFunctions contains implementations that work
+over a Field
+\item InnerMatrixQuotientFieldFunctions contain implementations that work
+over a quotient field
+\end{itemize}
+Implementations that rely on the representation of matrices used in Matrix
+should be put into these packages. 
 
 {\bf See:}\\
 \pagefrom{TwoDimensionalArrayCategory}{ARR2CAT}
+\pageto{RectangularMatrixCategory}{RMATCAT}
+\pageto{SquareMatrixCategory}{SMATCAT}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
@@ -12336,72 +13535,74 @@ digraph pic {
 \cross{MATCAT}{any?} &
 \cross{MATCAT}{coerce} &
 \cross{MATCAT}{column} &
-\cross{MATCAT}{copy} \\
+\cross{MATCAT}{columnSpace} \\
+\cross{MATCAT}{copy} &
 \cross{MATCAT}{count} &
 \cross{MATCAT}{determinant} &
 \cross{MATCAT}{diagonal?} &
-\cross{MATCAT}{diagonalMatrix} &
-\cross{MATCAT}{elt} \\
+\cross{MATCAT}{diagonalMatrix} \\
+\cross{MATCAT}{elt} &
 \cross{MATCAT}{empty} &
 \cross{MATCAT}{empty?} &
 \cross{MATCAT}{eq?} &
-\cross{MATCAT}{eval} &
-\cross{MATCAT}{every?} \\
+\cross{MATCAT}{eval} \\
+\cross{MATCAT}{every?} &
 \cross{MATCAT}{exquo} &
 \cross{MATCAT}{fill!} &
 \cross{MATCAT}{hash} &
-\cross{MATCAT}{horizConcat} &
-\cross{MATCAT}{inverse} \\
+\cross{MATCAT}{horizConcat} \\
+\cross{MATCAT}{inverse} &
 \cross{MATCAT}{latex} &
 \cross{MATCAT}{less?} &
 \cross{MATCAT}{listOfLists} &
-\cross{MATCAT}{map} &
-\cross{MATCAT}{map!} \\
+\cross{MATCAT}{map} \\
+\cross{MATCAT}{map!} &
 \cross{MATCAT}{matrix} &
 \cross{MATCAT}{maxColIndex} &
 \cross{MATCAT}{maxRowIndex} &
-\cross{MATCAT}{member?} &
-\cross{MATCAT}{members} \\
+\cross{MATCAT}{member?} \\
+\cross{MATCAT}{members} &
 \cross{MATCAT}{minColIndex} &
 \cross{MATCAT}{minordet} &
 \cross{MATCAT}{minRowIndex} &
-\cross{MATCAT}{more?} &
-\cross{MATCAT}{ncols} \\
+\cross{MATCAT}{more?} \\
+\cross{MATCAT}{ncols} &
 \cross{MATCAT}{new} &
 \cross{MATCAT}{nrows} &
 \cross{MATCAT}{nullSpace} &
-\cross{MATCAT}{nullity} &
-\cross{MATCAT}{parts} \\
+\cross{MATCAT}{nullity} \\
+\cross{MATCAT}{parts} &
+\cross{MATCAT}{pfaffian} &
 \cross{MATCAT}{qelt} &
 \cross{MATCAT}{qsetelt!} &
-\cross{MATCAT}{rank} &
+\cross{MATCAT}{rank} \\
 \cross{MATCAT}{row} &
-\cross{MATCAT}{rowEchelon} \\
+\cross{MATCAT}{rowEchelon} &
 \cross{MATCAT}{sample} &
 \cross{MATCAT}{scalarMatrix} &
-\cross{MATCAT}{setColumn!} &
+\cross{MATCAT}{setColumn!} \\
 \cross{MATCAT}{setelt} &
-\cross{MATCAT}{setRow!} \\
+\cross{MATCAT}{setRow!} &
 \cross{MATCAT}{setsubMatrix!} &
 \cross{MATCAT}{size?} &
-\cross{MATCAT}{square?} &
+\cross{MATCAT}{square?} \\
 \cross{MATCAT}{squareTop} &
-\cross{MATCAT}{subMatrix} \\
+\cross{MATCAT}{subMatrix} &
 \cross{MATCAT}{swapColumns!} &
 \cross{MATCAT}{swapRows!} &
-\cross{MATCAT}{symmetric?} &
+\cross{MATCAT}{symmetric?} \\
 \cross{MATCAT}{transpose} &
-\cross{MATCAT}{vertConcat} \\
+\cross{MATCAT}{vertConcat} &
 \cross{MATCAT}{zero} &
 \cross{MATCAT}{\#?} &
-\cross{MATCAT}{?**?} &
+\cross{MATCAT}{?**?} \\
 \cross{MATCAT}{?/?} &
-\cross{MATCAT}{?=?} \\
+\cross{MATCAT}{?=?} &
 \cross{MATCAT}{?\~{}=?} &
 \cross{MATCAT}{?*?} &
-\cross{MATCAT}{?+?} &
+\cross{MATCAT}{?+?} \\
 \cross{MATCAT}{-?} &
-\cross{MATCAT}{?-?} \\
+\cross{MATCAT}{?-?} &&&
 \end{tabular}
 
 {\bf Attributes Exported:}
@@ -12430,6 +13631,7 @@ These are implemented by this category:
 \begin{verbatim}
  antisymmetric? : % -> Boolean
  coerce : Col -> %                    
+ columnSpace: % -> List Col if R has EUCDOM
  diagonal? : % -> Boolean
  diagonalMatrix : List % -> %         
  diagonalMatrix : List R -> %
@@ -12437,6 +13639,7 @@ These are implemented by this category:
  exquo : (%,R) -> Union(%,"failed") if R has INTDOM
  horizConcat : (%,%) -> %             
  listOfLists : % -> List List R
+ pfaffian: % -> R if R has COMRING
  matrix : List List R -> %            
  scalarMatrix : (NonNegativeInteger,R) -> %
  setelt : (%,List Integer,List Integer,%) -> %
@@ -12557,32 +13760,56 @@ MatrixCategory(R,Row,Col): Category == Definition where
      square?  : % -> Boolean
        ++ \spad{square?(m)} returns true if m is a square matrix
        ++ (if m has the same number of rows as columns) and false otherwise.
+       ++
+       ++X square matrix [[j**i for i in 0..4] for j in 1..5]
+
      diagonal?: % -> Boolean
        ++ \spad{diagonal?(m)} returns true if the matrix m is square and
        ++ diagonal (i.e. all entries of m not on the diagonal are zero) and
        ++ false otherwise.
+       ++
+       ++X diagonal? matrix [[j**i for i in 0..4] for j in 1..5]
+
      symmetric?: % -> Boolean
        ++ \spad{symmetric?(m)} returns true if the matrix m is square and
        ++ symmetric (i.e. \spad{m[i,j] = m[j,i]} for all i and j) and false
        ++ otherwise.
+       ++
+       ++X symmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+
      antisymmetric?: % -> Boolean
        ++ \spad{antisymmetric?(m)} returns true if the matrix m is square and
        ++ antisymmetric (i.e. \spad{m[i,j] = -m[j,i]} for all i and j) 
        ++ and false otherwise.
+       ++
+       ++X antisymmetric? matrix [[j**i for i in 0..4] for j in 1..5]
+
 
 --% Creation
 
      zero: (NonNegativeInteger,NonNegativeInteger) -> %
        ++ \spad{zero(m,n)} returns an m-by-n zero matrix.
+       ++
+       ++X z:Matrix(INT):=zero(3,3)
+
      matrix: List List R -> %
        ++ \spad{matrix(l)} converts the list of lists l to a matrix, where the
        ++ list of lists is viewed as a list of the rows of the matrix.
+       ++
+       ++X matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+
      scalarMatrix: (NonNegativeInteger,R) -> %
        ++ \spad{scalarMatrix(n,r)} returns an n-by-n matrix with r's on the
        ++ diagonal and zeroes elsewhere.
+       ++
+       ++X z:Matrix(INT):=scalarMatrix(3,5)
+
      diagonalMatrix: List R -> %
        ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
        ++ of l on the diagonal.
+       ++
+       ++X diagonalMatrix [1,2,3]
+
      diagonalMatrix: List % -> %
        ++ \spad{diagonalMatrix([m1,...,mk])} creates a block diagonal matrix
        ++ M with block matrices {\em m1},...,{\em mk} down the diagonal,
@@ -12593,129 +13820,264 @@ MatrixCategory(R,Row,Col): Category == Definition where
        ++ \spad{(r1+..+r(l-1)) < i <= r1+..+rl} and
        ++ \spad{(c1+..+c(l-1)) < i <= c1+..+cl},
        ++ \spad{m.i.j} = 0  otherwise.
+       ++
+       ++X diagonalMatrix [matrix [[1,2],[3,4]], matrix [[4,5],[6,7]]]
+
      coerce: Col -> %
        ++ \spad{coerce(col)} converts the column col to a column matrix.
+       ++
+       ++X coerce([1,2,3])@Matrix(INT)
+
      transpose: Row -> %
        ++ \spad{transpose(r)} converts the row r to a row matrix.
+       ++
+       ++X transpose([1,2,3])@Matrix(INT)
 
 --% Creation of new matrices from old
 
      transpose: % -> %
        ++ \spad{transpose(m)} returns the transpose of the matrix m.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X transpose m
+
      squareTop: % -> %
        ++ \spad{squareTop(m)} returns an n-by-n matrix consisting of the first
        ++ n rows of the m-by-n matrix m. Error: if
        ++ \spad{m < n}.
+       ++
+       ++X m:=matrix [[j**i for i in 0..2] for j in 1..5]
+       ++X squareTop m
+
      horizConcat: (%,%) -> %
        ++ \spad{horizConcat(x,y)} horizontally concatenates two matrices with
        ++ an equal number of rows. The entries of y appear to the right
        ++ of the entries of x.  Error: if the matrices
        ++ do not have the same number of rows.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X horizConcat(m,m)
+
      vertConcat: (%,%) -> %
        ++ \spad{vertConcat(x,y)} vertically concatenates two matrices with an
        ++ equal number of columns. The entries of y appear below
        ++ of the entries of x.  Error: if the matrices
        ++ do not have the same number of columns.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X vertConcat(m,m)
 
 --% Part extractions/assignments
 
      listOfLists: % -> List List R
        ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
        ++ of lists.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X listOfLists m
+
      elt: (%,List Integer,List Integer) -> %
        ++ \spad{elt(x,rowList,colList)} returns an m-by-n matrix consisting
        ++ of elements of x, where \spad{m = # rowList} and \spad{n = # colList}
        ++ If \spad{rowList = [i<1>,i<2>,...,i<m>]} and \spad{colList =
        ++ [j<1>,j<2>,...,j<n>]}, then the \spad{(k,l)}th entry of
        ++ \spad{elt(x,rowList,colList)} is \spad{x(i<k>,j<l>)}.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X elt(m,3,3)
+
      setelt: (%,List Integer,List Integer, %) -> %
        ++ \spad{setelt(x,rowList,colList,y)} destructively alters the matrix x.
        ++ If y is \spad{m}-by-\spad{n}, \spad{rowList = [i<1>,i<2>,...,i<m>]}
        ++ and \spad{colList = [j<1>,j<2>,...,j<n>]}, then \spad{x(i<k>,j<l>)}
        ++ is set to \spad{y(k,l)} for \spad{k = 1,...,m} and \spad{l = 1,...,n}
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X setelt(m,3,3,10)
+
      swapRows_!: (%,Integer,Integer) -> %
        ++ \spad{swapRows!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
        ++ rows of m. This destructively alters the matrix.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X swapRows!(m,2,4)
+
      swapColumns_!: (%,Integer,Integer) -> %
        ++ \spad{swapColumns!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
        ++ columns of m. This destructively alters the matrix.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X swapColumns!(m,2,4)
+
      subMatrix: (%,Integer,Integer,Integer,Integer) -> %
        ++ \spad{subMatrix(x,i1,i2,j1,j2)} extracts the submatrix
        ++ \spad{[x(i,j)]} where the index i ranges from \spad{i1} to \spad{i2}
        ++ and the index j ranges from \spad{j1} to \spad{j2}.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X subMatrix(m,1,3,2,4)
+
      setsubMatrix_!: (%,Integer,Integer,%) -> %
        ++ \spad{setsubMatrix(x,i1,j1,y)} destructively alters the
        ++ matrix x. Here \spad{x(i,j)} is set to \spad{y(i-i1+1,j-j1+1)} for
        ++ \spad{i = i1,...,i1-1+nrows y} and \spad{j = j1,...,j1-1+ncols y}.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X setsubMatrix!(m,2,2,matrix [[3,3],[3,3]])
+
 
 --% Arithmetic
 
      "+": (%,%) -> %
        ++ \spad{x + y} is the sum of the matrices x and y.
        ++ Error: if the dimensions are incompatible.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X m+m
+
      "-": (%,%) -> %
        ++ \spad{x - y} is the difference of the matrices x and y.
        ++ Error: if the dimensions are incompatible.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X m-m
+
      "-":  %    -> %
        ++ \spad{-x} returns the negative of the matrix x.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X -m
+
      "*": (%,%) -> %
        ++ \spad{x * y} is the product of the matrices x and y.
        ++ Error: if the dimensions are incompatible.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X m*m
+
      "*": (R,%) -> %
        ++ \spad{r*x} is the left scalar multiple of the scalar r and the
        ++ matrix x.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X 1/3*m
+
      "*": (%,R) -> %
        ++ \spad{x * r} is the right scalar multiple of the scalar r and the
        ++ matrix x.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X m*1/3
+
      "*": (Integer,%) -> %
        ++ \spad{n * x} is an integer multiple.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X 3*m
+
      "*": (%,Col) -> Col
        ++ \spad{x * c} is the product of the matrix x and the column vector c.
        ++ Error: if the dimensions are incompatible.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X c:=coerce([1,2,3,4,5])@Matrix(INT)
+       ++X m*c
+
      "*": (Row,%) -> Row
        ++ \spad{r * x} is the product of the row vector r and the matrix x.
        ++ Error: if the dimensions are incompatible.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X r:=transpose([1,2,3,4,5])@Matrix(INT)
+       ++X r*m
+
      "**": (%,NonNegativeInteger) -> %
        ++ \spad{x ** n} computes a non-negative integral power of the matrix x.
        ++ Error: if the matrix is not square.
+       ++
+       ++X m:=matrix [[j**i for i in 0..4] for j in 1..5]
+       ++X m**3
+
      if R has IntegralDomain then
        "exquo": (%,R) -> Union(%,"failed")
          ++ \spad{exquo(m,r)} computes the exact quotient of the elements
          ++ of m by r, returning \axiom{"failed"} if this is not possible.
+         ++
+         ++X m:=matrix [[2**i for i in 2..4] for j in 1..5]
+         ++X exquo(m,2)
+
      if R has Field then
        "/": (%,R) -> %
          ++ \spad{m/r} divides the elements of m by r. Error: if \spad{r = 0}.
+         ++
+         ++X m:=matrix [[2**i for i in 2..4] for j in 1..5]
+         ++X m/4
 
 --% Linear algebra
 
      if R has EuclideanDomain then
        rowEchelon: % -> %
          ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+         ++
+         ++X rowEchelon matrix [[j**i for i in 0..4] for j in 1..5]
+
+       columnSpace: % -> List Col
+         ++ \spad{columnSpace(m)} returns a sublist of columns of the matrix m
+         ++ forming a basis of its column space
+         ++
+         ++X columnSpace matrix [[1,2,3],[4,5,6],[7,8,9],[1,1,1]]
+
      if R has IntegralDomain then
        rank: % -> NonNegativeInteger
          ++ \spad{rank(m)} returns the rank of the matrix m.
+         ++
+         ++X rank matrix [[1,2,3],[4,5,6],[7,8,9]]
+
        nullity: % -> NonNegativeInteger
          ++ \spad{nullity(m)} returns the nullity of the matrix m. This is
          ++ the dimension of the null space of the matrix m.
+         ++
+         ++X nullity matrix [[1,2,3],[4,5,6],[7,8,9]]
+
        nullSpace: % -> List Col
          ++ \spad{nullSpace(m)} returns a basis for the null space of
          ++ the matrix m.
+         ++
+         ++X nullSpace matrix [[1,2,3],[4,5,6],[7,8,9]]
+
      if R has commutative("*") then
        determinant: % -> R
          ++ \spad{determinant(m)} returns the determinant of the matrix m.
          ++ Error: if the matrix is not square.
+         ++
+         ++X determinant matrix [[j**i for i in 0..4] for j in 1..5]
+
        minordet: % -> R
          ++ \spad{minordet(m)} computes the determinant of the matrix m using
          ++ minors. Error: if the matrix is not square.
+         ++
+         ++X minordet matrix [[j**i for i in 0..4] for j in 1..5]
+
+     if R has CommutativeRing then
+       pfaffian: % -> R
+         ++ \spad{pfaffian(m)} returns the Pfaffian of the matrix m.
+         ++ Error if the matrix is not antisymmetric
+         ++
+         ++X pfaffian [[0,1,0,0],[-1,0,0,0],[0,0,0,1],[0,0,-1,0]]
      if R has Field then
        inverse: % -> Union(%,"failed")
          ++ \spad{inverse(m)} returns the inverse of the matrix m.
          ++ If the matrix is not invertible, "failed" is returned.
          ++ Error: if the matrix is not square.
+         ++
+         ++X inverse matrix [[j**i for i in 0..4] for j in 1..5]
+
        "**": (%,Integer) -> %
          ++ \spad{m**n} computes an integral power of the matrix m.
          ++ Error: if matrix is not square or if the matrix
          ++ is square but not invertible.
+         ++
+         ++X (matrix [[j**i for i in 0..4] for j in 1..5]) ** 2
 
    add
      minr ==> minRowIndex
@@ -12960,7 +14322,7 @@ MatrixCategory(R,Row,Col): Category == Definition where
            qsetelt_!(ans,i,j,qelt(x,i,j) - qelt(y,i,j))
        ans
 
-     - x == map(- #1,x)
+     - x == map((r1:R):R +-> - r1,x)
 
      a:R * x:% == map((r1:R):R +-> a * r1,x)
 
@@ -13028,6 +14390,61 @@ MatrixCategory(R,Row,Col): Category == Definition where
              sum
          w
 
+     if R has EuclideanDomain then
+       columnSpace M ==
+         M2 := rowEchelon M
+         basis: List Col := []
+         n: Integer := ncols M
+         m: Integer := nrows M
+         indRow: Integer := 1
+         for k in 1..n while indRow <= m repeat
+           if not zero?(M2.(indRow,k)) then
+             basis := cons(column(M,k),basis)
+             indRow := indRow + 1
+         reverse! basis
+
+     if R has CommutativeRing then
+       skewSymmetricUnitMatrix(n:PositiveInteger):% ==
+         matrix [[(if i=j+1 and odd? j
+                    then -1
+                    else if i=j-1 and odd? i
+                           then 1
+                           else 0) for j in 1..n] for i in 1..n]
+
+       SUPR ==> SparseUnivariatePolynomial R
+  
+       PfChar(A:%):SUPR ==
+         n := nrows A
+         (n = 2) => monomial(1$R,2)$SUPR + qelt(A,1,2)::SUPR
+         M:=subMatrix(A,3,n,3,n)
+         r:=subMatrix(A,1,1,3,n)
+         s:=subMatrix(A,3,n,2,2)
+         p:=PfChar(M)
+         d:=degree(p)$SUPR
+         B:=skewSymmetricUnitMatrix((n-2)::PositiveInteger)
+         C:=r*B
+         g:List R := [qelt(C*s,1,1), qelt(A,1,2), 1]
+         if d >= 4 then
+           B:=M*B
+           for i in 4..d by 2 repeat
+             C:=C*B
+             g:=cons(qelt(C*s,1,1),g)
+         g:=reverse! g
+         res:SUPR := 0
+         for i in 0..d by 2 for j in 2..d+2 repeat
+           c:=coefficient(p,i)
+           for e in first(g,j) for k in 2..-d by -2 repeat
+             res:=res+monomial(c*e,(k+i)::NonNegativeInteger)$SUPR
+         res
+
+       pfaffian a ==
+         if antisymmetric? a
+           then if odd? nrows a
+                  then 0
+                  else PfChar(a).0
+           else 
+             error "pfaffian: only defined for antisymmetric square matrices"
+
      if R has IntegralDomain then
        x exquo a ==
          ans := new(nrows x,ncols x,0)
@@ -28737,10 +30154,25 @@ digraph pic {
 \pagehead{RectangularMatrixCategory}{RMATCAT}
 \pagepic{ps/v102rectangularmatrixcategory.ps}{RMATCAT}{0.45}
 
+We define three categories for matrices
+\begin{itemize}
+\item MatrixCategory is the category of all matrices
+\item RectangularMatrixCategory is the category of all matrices 
+of a given dimension
+\item SquareMatrixCategory inherits from RectangularMatrixCategory
+\end{itemize}
+
+RectangularMatrixCategory does not automatically inherit MatrixCategory.
+Note that domains in DirectProductCategory(n,R), which are expected as
+parameters of RectangularMatrixCategory do not satisfy
+FiniteLinearAggregate(R) as required in MatrixCategory.
+
+The RectangularMatrix domain is matrices of fixed dimension.
 {\bf See:}\\
 \pageto{SquareMatrixCategory}{SMATCAT}
 \pagefrom{BiModule}{BMODULE}
 \pagefrom{HomogeneousAggregate}{HOAGG}
+\pagefrom{MatrixCategory}{MATCAT}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
@@ -35366,11 +36798,22 @@ digraph pic {
 \pagehead{SquareMatrixCategory}{SMATCAT}
 \pagepic{ps/v102squarematrixcategory.ps}{SMATCAT}{0.25}
 
+We define three categories for matrices
+\begin{itemize}
+\item MatrixCategory is the category of all matrices
+\item RectangularMatrixCategory is the category of all matrices 
+of a given dimension
+\item SquareMatrixCategory inherits from RectangularMatrixCategory
+\end{itemize}
+
+The SquareMatrix domain is for square matrices of fixed dimension.
+
 {\bf See:}\\
 \pagefrom{BiModule}{BMODULE}
 \pagefrom{DifferentialExtension}{DIFEXT}
 \pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
 \pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{MatrixCategory}{MATCAT}
 \pagefrom{RectangularMatrixCategory}{RMATCAT}
 
 {\bf Exports:}\\
diff --git a/changelog b/changelog
index b8869c9..a025508 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,6 @@
+20090510 tpd src/axiom-website/patches.html 20090510.04.tpd.patch
+20090510 tpd src/algebra/Makefile add MatrixCategory.input, .help
+20090510 tpd books/bookvol10.2 MatrixCategory test, help, examples
 20090510 tpd src/axiom-website/patches.html 20090510.03.tpd.patch
 20090510 tpd books/bookvol10.4 ALGFACT +-> conversion
 20090510 tpd src/axiom-website/patches.html 20090510.02.tpd.patch
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 7e922ae..5f29a1b 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -16478,7 +16478,8 @@ SPADHELP=\
  ${HELP}/LyndonWord.help             ${HELP}/Magma.help \
  ${HELP}/MakeFunction.help           ${HELP}/MappingPackage1.help \
  ${HELP}/MappingPackage2.help        ${HELP}/MappingPackage3.help \
- ${HELP}/Matrix.help                 ${HELP}/Multiset.help \
+ ${HELP}/Matrix.help                 ${HELP}/MatrixCategory.help \
+ ${HELP}/Multiset.help \
  ${HELP}/MultivariatePolynomial.help \
  ${HELP}/NagEigenPackage.help \
  ${HELP}/NagFittingPackage.help \
@@ -16570,7 +16571,8 @@ REGRESS=\
  LyndonWord.regress             Magma.regress \
  MakeFunction.regress           MappingPackage1.regress \
  MappingPackage2.regress        MappingPackage3.regress \
- Matrix.regress                 Multiset.regress \
+ Matrix.regress                 MatrixCategory.regress \
+ Multiset.regress \
  MultivariatePolynomial.regress None.regress \
  NottinghamGroup.regress \
  Octonion.regress               OneDimensionalArray.regress \
@@ -17287,6 +17289,16 @@ ${HELP}/Matrix.help: ${BOOKS}/bookvol10.3.pamphlet
             >${INPUT}/Matrix.input
 	@echo "Matrix (MATRIX)" >>${HELPFILE}
 
+${HELP}/MatrixCategory.help: ${BOOKS}/bookvol10.2.pamphlet
+	@echo 7057 create MatrixCategory.help from \
+           ${BOOKS}/bookvol10.2.pamphlet
+	@${TANGLE} -R"MatrixCategory.help" ${BOOKS}/bookvol10.2.pamphlet \
+           >${HELP}/MatrixCategory.help
+	@cp ${HELP}/MatrixCategory.help ${HELP}/MATCAT.help
+	@${TANGLE} -R"MatrixCategory.input" ${BOOKS}/bookvol10.2.pamphlet \
+            >${INPUT}/MatrixCategory.input
+	@echo "MatrixCategory (MATCAT)" >>${HELPFILE}
+
 ${HELP}/Multiset.help: ${BOOKS}/bookvol10.3.pamphlet
 	@echo 7058 create Multiset.help from ${BOOKS}/bookvol10.3.pamphlet
 	@${TANGLE} -R"Multiset.help" ${BOOKS}/bookvol10.3.pamphlet \
diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html
index a1b3a4f..79d8ce8 100644
--- a/src/axiom-website/patches.html
+++ b/src/axiom-website/patches.html
@@ -1166,5 +1166,7 @@ bookvol10.4 ALGMFACT +-> conversion<br/>
 bookvol10.3 D01AKFA +-> conversion<br/>
 <a href="patches/20090510.03.tpd.patch">20090510.03.tpd.patch</a>
 bookvol10.4 ALGFACT +-> conversion<br/>
+<a href="patches/20090510.04.tpd.patch">20090510.04.tpd.patch</a>
+bookvol10.2 MatrixCategory test, help, examples<br/>
  </body>
 </html>
