Conversion and IO
Recast:
PUBLIC AC.BinaryOp = {
Args are a StructureElement and a Structure
thisMatrixStructure: Object ← secondArg;
thisMatrixStructureData: MatrixStructureData ← NARROW[thisMatrixStructure.data];
thisStructureElementStructure: Object ← thisMatrixStructureData.elementStructure;
canRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, thisStructureElementStructure];
recastMethod: Method ← AC.LookupMethodInStructure[$recast, thisStructureElementStructure];
refBOOL: REF BOOL;
Already in this structure
IF AC.StructureEqual[firstArg.class, secondArg] THEN RETURN[firstArg]; -- nothing to do
Try to recast into elementStructure
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[canRecastMethod,LIST[firstArg.class, thisStructureElementStructure] ] ];
IF refBOOL^
THEN {
recastElement: Object ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[firstArg, thisStructureElementStructure] ];
RETURN[DiagonalMatrix[recastElement, thisMatrixStructure] ];
};
If a matrix of the right size, try to recast its elements into elementStructure
IF
AC.LookupMethodInStructure[$matrixStructure, firstArg.class]#
NIL
THEN {
inputMatrixStructure: Object ← firstArg.class;
inputMatrixStructureData: MatrixStructureData ← NARROW[inputMatrixStructure.data];
inputStructureElementStructure: Object ← inputMatrixStructureData.elementStructure;
argData: MatrixData ← NARROW[firstArg.data];
resultData: MatrixData;
IF inputMatrixStructureData.nRows # thisMatrixStructureData.nRows THEN RETURN[NIL];
IF inputMatrixStructureData.nCols # thisMatrixStructureData.nCols THEN RETURN[NIL];
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[canRecastMethod,LIST[inputStructureElementStructure, thisStructureElementStructure] ] ];
IF NOT refBOOL^ THEN RETURN[NIL];
result ← Create[thisMatrixStructure];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..thisMatrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..thisMatrixStructureData.nCols]
DO
resultData[i][j] ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[argData[i][j], thisStructureElementStructure] ];
ENDLOOP;
ENDLOOP;
RETURN[result];
};
Can't do it
RETURN[NIL];
};
CanRecast:
PUBLIC AC.BinaryPredicate = {
Args are either [Structure, Structure] or [StructureElement, Structure]
thisMatrixStructure: Object ← secondArg;
thisMatrixStructureData: MatrixStructureData ← NARROW[thisMatrixStructure.data];
thisStructureElementStructure: Object ← thisMatrixStructureData.elementStructure;
canRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, thisStructureElementStructure];
refBOOL: REF BOOL;
firstArgStructure: Object ← IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR;
firstArgStructure = thisMatrixStructure
IF AC.StructureEqual[firstArgStructure, thisMatrixStructure] THEN RETURN[TRUE];
CanRecast firstArgStructure into elementStructure?
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[canRecastMethod,LIST[firstArgStructure, thisStructureElementStructure] ] ];
IF refBOOL^ THEN RETURN[TRUE];
If firstArgStructure a matrix Structure of the right size, CanRecast its elementStructure into this elementStructure?
IF
AC.LookupMethodInStructure[$matrixStructure, firstArgStructure]#
NIL
THEN {
inputMatrixStructure: Object ← firstArgStructure;
inputMatrixStructureData: MatrixStructureData ← NARROW[inputMatrixStructure.data];
inputStructureElementStructure: Object ← inputMatrixStructureData.elementStructure;
IF inputMatrixStructureData.nRows # thisMatrixStructureData.nRows THEN RETURN[FALSE];
IF inputMatrixStructureData.nCols # thisMatrixStructureData.nCols THEN RETURN[FALSE];
refBOOL ← NARROW[AC.ApplyNoLkpNoRecastRef[canRecastMethod,LIST[inputStructureElementStructure, thisStructureElementStructure] ] ];
IF NOT refBOOL^ THEN RETURN[FALSE] ELSE RETURN[TRUE];
};
Out of luck
RETURN[FALSE];
};
ToExpr:
PUBLIC AC.ToExprOp = {
matrixData: MatrixData ← NARROW[in.data];
matrixStructureData: MatrixStructureData ← NARROW[in.class.data];
outMatrix: LIST OF LIST OF MathExpr.EXPR ← NIL;
method: Method ← AC.LookupMethodInStructure[$toExpr, matrixStructureData.elementStructure];
FOR i:
NAT
DECREASING
IN [1..matrixStructureData.nRows]
DO
outRow: LIST OF MathExpr.EXPR ← NIL;
FOR j:
NAT
DECREASING
IN [1..matrixStructureData.nCols]
DO
outRow ← CONS[matrixStructureData.elementStructure.class.toExpr[matrixData[i][j] ], outRow];
outRow ← CONS[NARROW[AC.ApplyNoLkpNoRecastRef[method, LIST[matrixData[i][j] ] ] ], outRow];
ENDLOOP;
outMatrix ← CONS[outRow, outMatrix];
ENDLOOP;
out ← MathConstructors.MakeMatrix[matrixStructureData.nRows, matrixStructureData.nCols, outMatrix];
};
LegalFirstChar:
PUBLIC AC.LegalFirstCharOp = {
SELECT char
FROM
'[ => RETURN[TRUE];
ENDCASE;
RETURN[FALSE];
};
Read:
PUBLIC
AC.ReadOp = {
data: MatrixStructureData ← NARROW[structure.data];
elementStructure: AC.Object ← data.elementStructure;
puncChar: CHAR;
rows: RowSeq ← NEW[RowSeqRec[data.nRows]];
readMethod: AC.Method ← AC.LookupMethodInStructure[$read, elementStructure];
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
IF puncChar # '[ THEN ERROR SyntaxError[$LeftBracketExpected];
FOR i:
NAT
IN [1..data.nRows]
DO
row: Row ← NEW[RowRec[data.nCols]];
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
IF puncChar # '[ THEN ERROR SyntaxError[$LeftBracketExpected];
FOR j:
NAT
IN [1..data.nCols]
DO
row[j] ← AC.ApplyReadMethod[readMethod, in, elementStructure];
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
[]← in.SkipWhitespace[];
IF j < data.nCols THEN IF puncChar # ', THEN ERROR SyntaxError[$CommaExpected];
ENDLOOP;
IF puncChar # '] THEN ERROR SyntaxError[$RightBracketExpected];
rows[i] ← row;
puncChar ← in.GetChar[];
[]← in.SkipWhitespace[];
IF i < data.nRows THEN IF puncChar # ', THEN SyntaxError[$CommaExpected];
ENDLOOP;
IF puncChar # '] THEN ERROR SyntaxError[$RightBracketExpected];
out ← NEW[AC.ObjectRec ← [flavor: StructureElement, class: structure, data: rows] ];
};
FromRope:
PUBLIC
AC.FromRopeOp = {
stream: IO.STREAM ← IO.RIS[in];
out ← Read[stream, structure];
};
ToRope:
PUBLIC
AC.ToRopeOp = {
data: MatrixData ← NARROW[in.data];
matrixStructureData: MatrixStructureData ← NARROW[in.class.data];
elementStructure: AC.Object ← matrixStructureData.elementStructure;
toRopeMethod: AC.Method ← AC.LookupMethodInStructure[$toRope, elementStructure];
out ← "[ ";
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
out ← out.Concat["[ "];
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
out ← out.Concat[NARROW[AC.ApplyNoLkpNoRecastRef[toRopeMethod, LIST[data[i][j] ] ] ] ];
IF j < matrixStructureData.nCols THEN out ← out.Concat[", "];
ENDLOOP;
out ← out.Concat["] "];
IF i < matrixStructureData.nRows THEN out ← out.Concat[", "];
ENDLOOP;
out ← out.Concat["] "];
};
Write:
PUBLIC
AC.WriteOp = {
stream.PutF["\n %g \n", IO.rope[ToRope[in]] ];
};
Arithmetic
Create:
PROC [matrixStructure: Object]
RETURNS [a: Matrix] = {
data: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[matrixStructure.data];
a ←
NEW[
AC.ObjectRec ← [
flavor: StructureElement,
class: matrixStructure,
data: NEW[RowSeqRec[matrixStructureData.nRows]]
] ];
data ← NARROW[a.data];
FOR i: NAT IN [1..matrixStructureData.nRows] DO data[i] ← NEW[RowRec[matrixStructureData.nCols]]; ENDLOOP;
};
Zero:
PUBLIC AC.NullaryOp = {
matrixStructureData: MatrixStructureData ← NARROW[structure.data];
elementStructure: Object ← matrixStructureData.elementStructure;
zeroMethod: Method ← AC.LookupMethodInStructure[$zero, elementStructure];
resultData: MatrixData;
result ← Create[structure];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← AC.ApplyNoLkpNoRecastObject[zeroMethod, LIST[elementStructure] ];
ENDLOOP;
ENDLOOP;
};
One:
PUBLIC AC.NullaryOp = {
data: MatrixStructureData ← NARROW[structure.data];
oneMethod: Method ← AC.LookupMethodInStructure[$one, data.elementStructure];
RETURN[ DiagonalMatrix[
AC.ApplyNoLkpNoRecastObject[oneMethod, LIST[data.elementStructure] ],
structure] ];
};
Add:
PUBLIC
AC.BinaryOp ~ {
firstData: MatrixData ← NARROW[firstArg.data];
secondData: MatrixData ← NARROW[secondArg.data];
resultData: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[firstArg.class.data];
result ← Create[firstArg.class];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← matrixStructureData.elementStructure.class.add[firstData[i][j], secondData[i][j] ];
resultData[i][j] ← AC.ApplyLkpRecastObject[$sum, matrixStructureData.elementStructure, LIST[firstData[i][j], secondData[i][j] ] ];
ENDLOOP;
ENDLOOP;
};
Negate:
PUBLIC
AC.UnaryOp ~ {
argData: MatrixData ← NARROW[arg.data];
resultData: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[arg.class.data];
result ← Create[arg.class];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← matrixStructureData.elementStructure.class.negate[argData[i][j]];
resultData[i][j] ← AC.ApplyLkpRecastObject[$negation, matrixStructureData.elementStructure, LIST[argData[i][j]] ];
ENDLOOP;
ENDLOOP;
};
Subtract:
PUBLIC
AC.BinaryOp ~ {
RETURN[ Add[ firstArg, Negate[ secondArg] ] ];
};
Multiply:
PUBLIC
AC.BinaryOp ~ {
Assumes matrices from same structure, i.e. square
firstData: MatrixData ← NARROW[firstArg.data];
secondData: MatrixData ← NARROW[secondArg.data];
resultData: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[firstArg.class.data];
zero: Object ← matrixStructureData.elementStructure.class.zero[matrixStructureData.elementStructure];
zero: Object ← AC.ApplyLkpRecastObject[$zero, matrixStructureData.elementStructure, LIST[matrixStructureData.elementStructure] ];
result ← Create[firstArg.class];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← zero;
FOR k:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← matrixStructureData.elementStructure.class.add[
resultData[i][j],
matrixStructureData.elementStructure.class.multiply[firstData[i][k], secondData[k][j] ] ]
prod: Object ← AC.ApplyLkpRecastObject[$product, matrixStructureData.elementStructure, LIST[firstData[i][k], secondData[k][j]] ];
resultData[i][j] ← AC.ApplyLkpRecastObject[$sum, matrixStructureData.elementStructure, LIST[resultData[i][j], prod ] ];
ENDLOOP;
ENDLOOP;
ENDLOOP;
};
Power:
PUBLIC
AC.BinaryOp ~ {
-- this simple algorithm is Structure independent
power: INT ← Ints.ToINT[secondArg];
structure: Object ← firstArg.class;
one: Object ← AC.ApplyLkpNoRecastObject[$one, structure, LIST[structure] ];
productMethod: Method ← AC.LookupMethodInStructure[$product, structure];
IF power < 0
THEN {
invertMethod: Method ← AC.LookupMethodInStructure[$invert, structure];
temp: Object;
IF invertMethod = NIL THEN ERROR;
temp ← Power[firstArg, Ints.FromINT[ABS[power] ] ];
RETURN[AC.ApplyNoLkpNoRecastObject[invertMethod, LIST[temp] ] ];
};
IF power = 0 THEN RETURN[one];
result ← firstArg;
FOR i:
INT
IN [2..power]
DO
result ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[firstArg, result] ];
ENDLOOP;
};
Invert:
PUBLIC
AC.UnaryOp ~ {
resultData: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[arg.class.data];
elementStructure: Object ← matrixStructureData.elementStructure;
det: Object ← Determinant[arg];
tempVal: Object;
scratchMatrixRing: Object ← MakeMatrixStructure[elementStructure, matrixStructureData.nRows - 1, matrixStructureData.nCols - 1];
Aij: Matrix ← Create[scratchMatrixRing];
IF matrixStructureData.elementStructure.class.category # field THEN ERROR CantInvertError[matrixStructureData.elementStructure];
IF NOT AC.IsCategory[elementStructure, field] AND NOT AC.IsCategory[elementStructure, divisionAlgebra] THEN ERROR CantInvertError[elementStructure];
result ← Create[arg.class];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
MakeAij[arg, Aij, i, j];
tempVal ← matrixStructureData.elementStructure.class.divide[Determinant[Aij], det]; -- error will be generated here if Determinant[Aij] = 0
tempVal ← AC.ApplyLkpRecastObject[$fraction, matrixStructureData.elementStructure, LIST[Determinant[Aij], det ] ]; -- error will be generated here if Determinant[Aij] = 0
IF NOT Even[i + j] THEN tempVal ← matrixStructureData.elementStructure.class.negate[tempVal];
IF NOT Even[i + j] THEN tempVal ← AC.ApplyLkpRecastObject[$negation, matrixStructureData.elementStructure, LIST[tempVal ] ];
resultData[j][i] ← tempVal;
ENDLOOP;
ENDLOOP;
RETURN[result];
};
Divide:
PUBLIC
AC.BinaryOp~ {
RETURN[ Multiply[ firstArg, Invert[ secondArg] ] ];
};
ScalarMultiply:
PUBLIC
AC.BinaryOp~ {
firstArg is scalar, secondArg is matrix
does its own recasting, so when installed, supplies DesiredArgStructures ← NIL
secondData: MatrixData ← NARROW[secondArg.data];
resultData: MatrixData;
matrixStructureData: MatrixStructureData ← NARROW[secondArg.class.data];
elementStructure: Object ← matrixStructureData.elementStructure;
recastMethod: Method ← AC.LookupMethodInStructure[$recast, elementStructure];
scalar: Object ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[firstArg, elementStructure] ];
productMethod: Method ← AC.LookupMethodInStructure[$product, elementStructure];
IF scalar = NIL THEN TypeError[]; -- recast failed
result ← Create[secondArg.class];
resultData ← NARROW[result.data];
FOR i:
NAT
IN [1..matrixStructureData.nRows]
DO
FOR j:
NAT
IN [1..matrixStructureData.nCols]
DO
resultData[i][j] ← AC.ApplyNoLkpNoRecastObject[productMethod, LIST[scalar, secondData[i][j] ] ];
ENDLOOP;
ENDLOOP;
};
Transpose:
PUBLIC
AC.UnaryOp ~ {
argData: MatrixData ← NARROW[arg.data];
argStructureData: MatrixStructureData ← NARROW[arg.class.data];
resultData: MatrixData;
nRows: NAT ← argStructureData.nRows;
nCols: NAT ← argStructureData.nCols;
resultStructure: Object ← MakeMatrixStructure[argStructureData.elementStructure, nCols, nRows];
result ← Create[resultStructure];
resultData ← NARROW[result.data];
FOR i:
INTEGER
IN [1..argStructureData.nRows]
DO
FOR j:
INTEGER
IN [1..argStructureData.nCols]
DO
resultData[j][i] ← argData[i][j];
ENDLOOP;
ENDLOOP;
RETURN[result];
};
MakeAij:
PROC[a, Aij: Matrix, i,j:
INTEGER] = {
--assume Aij is well formed
n, m: NAT ← 1; --row index, column index for new matrix
firstData: MatrixData ← NARROW[a.data];
secondData: MatrixData ← NARROW[Aij.data];
matrixStructureData: MatrixStructureData ← NARROW[a.class.data];
FOR row:
NAT
IN [1..matrixStructureData.nRows]
DO
IF row = i THEN LOOP; --row index for original matrix
m ← 1;
FOR col:
NAT
IN [1..matrixStructureData.nCols]
DO
--column index for original matrix
IF col = j THEN LOOP;
secondData[n][m] ← firstData[row][col];
m ← m+1;
ENDLOOP;
n ← n+1;
ENDLOOP;
};
Even:
PROC[I:
NAT]
RETURNS[
BOOL] = {
RETURN[
I
MOD 2 = 0]};
Determinant:
PUBLIC
AC.StructuredToGroundOp ~ {
Expansion by minors.
argData: MatrixData ← NARROW[structuredElt.data];
matrixStructureData: MatrixStructureData ← NARROW[structuredElt.class.data];
IF matrixStructureData.nRows = 1 THEN groundElement ← argData[1][1]
ELSE IF matrixStructureData.nRows=2 THEN groundElement ← matrixStructureData.elementStructure.class.subtract[
matrixStructureData.elementStructure.class.multiply[argData[1][1], argData[2][2] ],
matrixStructureData.elementStructure.class.multiply[argData[1][2], argData[2][1] ] ]
ELSE
IF matrixStructureData.nRows=2
THEN {
prod1: Object ← AC.ApplyLkpRecastObject[$product, matrixStructureData.elementStructure, LIST[argData[1][1], argData[2][2] ] ];
prod2: Object ← AC.ApplyLkpRecastObject[$product, matrixStructureData.elementStructure, LIST[argData[1][2], argData[2][1] ] ];
groundElement ← AC.ApplyLkpRecastObject[$difference, matrixStructureData.elementStructure, LIST[prod1, prod2 ] ];
}
ELSE {
i, j: NAT;
zero: Object ← AC.ApplyLkpRecastObject[$zero, matrixStructureData.elementStructure, LIST[matrixStructureData.elementStructure] ];
scratchMatrixRing: Object ← MakeMatrixStructure[matrixStructureData.elementStructure, matrixStructureData.nRows - 1, matrixStructureData.nCols - 1];
Aij: Matrix ← Create[scratchMatrixRing];
groundElement ← zero;
j ← 1; --always use column 1 for now
FOR i
IN [1..matrixStructureData.nRows]
DO
tempVal: Object;
MakeAij[structuredElt, Aij, i, j];
tempVal ← matrixStructureData.elementStructure.class.multiply[ argData[i][j], Determinant[Aij] ];
tempVal ← AC.ApplyLkpRecastObject[$product, matrixStructureData.elementStructure, LIST[argData[i][j], Determinant[Aij] ] ];
IF NOT Even[i + j] THEN tempVal ← matrixStructureData.elementStructure.class.negate[tempVal];
IF NOT Even[i + j] THEN tempVal ← AC.ApplyLkpRecastObject[$negation, matrixStructureData.elementStructure, LIST[tempVal ] ];
groundElement ← matrixStructureData.elementStructure.class.add[groundElement, tempVal];
groundElement ← AC.ApplyLkpRecastObject[$sum, matrixStructureData.elementStructure, LIST[groundElement, tempVal ] ];
ENDLOOP;
};
RETURN[groundElement];
};
Start Code
matrixRingClass: PUBLIC ObjectClass ← NEW[ObjectClassRec ← [
category: ring,
multiply: Multiply,
commutative: FALSE,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
] ];
matrixAlgebraClass: PUBLIC ObjectClass ← NEW[ObjectClassRec ← [
category: algebra,
multiply: Multiply,
commutative: FALSE,
invert: Invert, -- it is up to the user not to try to invert a singular matrix
divide: Divide,
scalarMultiply: ScalarMultiply,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
] ];
matrixClass: AC.Object ← AC.MakeClass["MatrixClass", NIL, NIL];
squareMatricesOverRingClass: AC.Object ← AC.MakeClass["SquareMatricesOverRingClass", matrixClass, NIL]; -- squareMatricesOverRingClass is subclass[matrixClass]
squareMatricesOverFieldClass: AC.Object ← AC.MakeClass["SquareMatricesOverFieldClass", squareMatricesOverRingClass, NIL]; -- squareMatricesOverFieldClass is subclass[squareMatricesOverRingClass]
algebraCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← algebra], NIL, NIL];
ringCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← ring], NIL, NIL];
setCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← set], NIL, NIL];
matrixStructureMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "matrixStructure"];
shortPrintNameMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ShortPrintName], NIL, "shortPrintName"];
recastMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Recast], NIL, "recast"];
canRecastMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← CanRecast], NIL, "canRecast"];
toExprMethod: Method ← AC.MakeMethod[ToExprOp, FALSE, NEW[AC.ToExprOp ← ToExpr], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "toExpr"];
legalFirstCharMethod: Method ← AC.MakeMethod[LegalFirstCharOp, FALSE, NEW[AC.LegalFirstCharOp ← LegalFirstChar], NIL, "legalFirstChar"];
readMethod: Method ← AC.MakeMethod[ReadOp, FALSE, NEW[AC.ReadOp ← Read], NIL, "read"];
fromRopeMethod: Method ← AC.MakeMethod[FromRopeOp, TRUE, NEW[AC.FromRopeOp ← FromRope], NIL, "fromRope"];
toRopeMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ToRope], NIL, "toRope"];
diagonalMatrixMethod: Method ← AC.MakeMethod[UnaryImbedOp, TRUE, NEW[AC.UnaryImbedOp ← DiagonalMatrix], NIL, "diagonalMatrix"]; -- 4/17/87 recast procs need to be able to handle Structure args; could then have non—NIL DesiredArgStructures
matrixMethod: Method ← AC.MakeMethod[MatrixImbedOp, FALSE, NEW[AC.MatrixImbedOp ← MakeMatrix], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "matrix"];
parenMethod: Method ← AC.MakeMethod[UnaryOp, FALSE, NEW[AC.UnaryOp ← AC.Copy], NIL, "paren"];
zeroMethod: Method ← AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp ← Zero], NIL, "zero"];
oneMethod: Method ← AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp ← One], NIL, "one"];
sumMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Add], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "sum"];
negationMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Negate], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "negation"];
differenceMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Subtract], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "difference"];
productMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Multiply], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "product"];
powerMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Power], NEW[AC.UnaryToListOp ← ObjectAndIntDesired], "power"];
invertMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Invert], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "invert"];
fractionMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Divide], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "divide"];
scalarProductMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← ScalarMultiply], NEW[AC.UnaryToListOp ← ElementAndMatrixDesired], "scalarProduct"];
equalMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← Equal], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "equals"];
transposeMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Transpose], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "transpose"];
determinantMethod: Method ← AC.MakeMethod[StructuredToGroundOp, TRUE, NEW[AC.StructuredToGroundOp ← Determinant], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "determinant"];
makeMatrixStructureMethod: Method ← AC.MakeMethod[MatrixStructureConstructor, FALSE, NEW[AC.MatrixStructureConstructor ← MakeMatrixStructure], NIL, "makeMatrixStructure"];
AC.AddMethodToClass[$matrixStructure, matrixStructureMethod, matrixClass];
AC.AddMethodToClass[$category, setCategoryMethod, matrixClass];
AC.AddMethodToClass[$shortPrintName, shortPrintNameMethod, matrixClass];
AC.AddMethodToClass[$recast, recastMethod, matrixClass];
AC.AddMethodToClass[$canRecast, canRecastMethod, matrixClass];
AC.AddMethodToClass[$toExpr, toExprMethod, matrixClass];
AC.AddMethodToClass[$legalFirstChar, legalFirstCharMethod, matrixClass];
AC.AddMethodToClass[$read, readMethod, matrixClass];
AC.AddMethodToClass[$fromRope, fromRopeMethod, matrixClass];
AC.AddMethodToClass[$toRope, toRopeMethod, matrixClass];
AC.AddMethodToClass[$matrix, matrixMethod, matrixClass];
AC.AddMethodToClass[$paren, parenMethod, matrixClass];
AC.AddMethodToClass[$zero, zeroMethod, matrixClass];
AC.AddMethodToClass[$sum, sumMethod, matrixClass];
AC.AddMethodToClass[$negation, negationMethod, matrixClass];
AC.AddMethodToClass[$difference, differenceMethod, matrixClass];
AC.AddMethodToClass[$transp, transposeMethod, matrixClass];
AC.AddMethodToClass[$eqFormula, equalMethod, matrixClass];
AC.AddMethodToClass[$category, ringCategoryMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$one, oneMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$diagonalMatrix, diagonalMatrixMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$product, productMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$pow, powerMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$det, determinantMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$scalarProduct, scalarProductMethod, squareMatricesOverRingClass];
AC.AddMethodToClass[$category, algebraCategoryMethod, squareMatricesOverFieldClass];
AC.AddMethodToClass[$invert, invertMethod, squareMatricesOverFieldClass];
AC.AddMethodToClass[$fraction, fractionMethod, squareMatricesOverFieldClass];
AC.AddMethodToClass[$makeMatrixStructure, makeMatrixStructureMethod, Structures.StructuresClass];