diff --git a/lib/matobjplist.gd b/lib/matobjplist.gd
index a5fa998de7e..d19c20e60c7 100644
--- a/lib/matobjplist.gd
+++ b/lib/matobjplist.gd
@@ -29,7 +29,7 @@
## in a row list matrix
## (see Section ).
## It is internally represented as a positional object
-## (see that stores 2 entries:
+## (see that stores two entries:
##
## -
## its base domain
@@ -45,7 +45,7 @@
## <#/GAPDoc>
##
DeclareRepresentation( "IsPlistVectorRep",
- IsVectorObj and IsPositionalObjectRep, [] );
+ IsVectorObj and IsPositionalObjectRep and IsNoImmediateMethodsObject, [] );
#############################################################################
@@ -60,14 +60,15 @@ DeclareRepresentation( "IsPlistVectorRep",
## a list of its rows, in the sense defined in
## Section
.
## It is internally represented as a positional object
-## (see that stores 4 entries:
+## (see that stores four entries:
##
## -
## its base domain
## (see
),
##
## -
-## an empty vector in the representation of each row,,
+## the number of rows
+## (see
), and
##
## -
## the number of columns
@@ -83,28 +84,20 @@ DeclareRepresentation( "IsPlistVectorRep",
## <#/GAPDoc>
##
DeclareRepresentation( "IsPlistMatrixRep",
- IsRowListMatrix and IsPositionalObjectRep, [] );
+ IsRowListMatrix and IsPositionalObjectRep and IsNoImmediateMethodsObject, [] );
# Some constants for matrix access:
-BindGlobal( "BDPOS", 1 );
-BindGlobal( "EMPOS", 2 );
-BindGlobal( "RLPOS", 3 );
-BindGlobal( "ROWSPOS", 4 );
+# TODO rename these so that one can quickly see that they belong to IsPlist*Rep
+BindConstant( "BDPOS", 1 );
+BindConstant( "NUM_ROWS_POS", 2 );
+BindConstant( "NUM_COLS_POS", 3 );
+BindConstant( "ROWSPOS", 4 );
# For vector access:
-#BindGlobal( "BDPOS", 1 ); # see above
-BindGlobal( "ELSPOS", 2 );
+#BindConstant( "BDPOS", 1 ); # see above
+BindConstant( "ELSPOS", 2 );
# Two filters to speed up some methods:
DeclareFilter( "IsIntVector" );
DeclareFilter( "IsFFEVector" );
-
-############################################################################
-# Constructors:
-############################################################################
-
-#T Should this be documented?
-#T It seems to be just an auxiliary function for the documented constructors.
-DeclareGlobalFunction( "MakePlistVectorType" );
-
diff --git a/lib/matobjplist.gi b/lib/matobjplist.gi
index b484cb273d5..24d53869895 100644
--- a/lib/matobjplist.gi
+++ b/lib/matobjplist.gi
@@ -18,108 +18,90 @@
# Constructors:
############################################################################
-InstallGlobalFunction( MakePlistVectorType,
- function( basedomain, filter )
- local T, filter2;
- filter2 := filter and IsMutable;
+InstallMethod( NewVector, "for IsPlistVectorRep, a semiring, and a list",
+ [ IsPlistVectorRep, IsSemiring, IsList ],
+ function( filter, basedomain, l )
+ local typ;
+ filter := IsPlistVectorRep and IsMutable;
if HasCanEasilyCompareElements(Representative(basedomain)) and
CanEasilyCompareElements(Representative(basedomain)) then
- filter2 := filter2 and CanEasilyCompareElements;
+ filter := filter and CanEasilyCompareElements;
fi;
- if IsIdenticalObj(basedomain,Integers) then
- T := NewType(FamilyObj(basedomain),
- filter2 and IsIntVector);
+ if IsIdenticalObj(basedomain, Integers) then
+ filter := filter and IsIntVector;
elif IsFinite(basedomain) and IsField(basedomain) then
- T := NewType(FamilyObj(basedomain),
- filter2 and IsFFEVector);
- else
- T := NewType(FamilyObj(basedomain),
- filter2);
+ filter := filter and IsFFEVector;
fi;
- return T;
- end);
-
-InstallMethod( NewVector, "for IsPlistVectorRep, a ring, and a list",
- [ IsPlistVectorRep, IsRing, IsList ],
- function( filter, basedomain, l )
- local typ, v;
- typ := MakePlistVectorType(basedomain,IsPlistVectorRep);
- v := [basedomain,ShallowCopy(l)];
- Objectify(typ,v);
- return v;
+ typ := NewType(FamilyObj(basedomain), filter);
+ return Objectify(typ, [ basedomain, ShallowCopy(l) ]);
end );
-InstallMethod( NewZeroVector, "for IsPlistVectorRep, a ring, and an int",
- [ IsPlistVectorRep, IsRing, IsInt ],
+InstallMethod( NewZeroVector, "for IsPlistVectorRep, a semiring, and an int",
+ [ IsPlistVectorRep, IsSemiring, IsInt ],
function( filter, basedomain, l )
- local typ, v;
- typ := MakePlistVectorType(basedomain,IsPlistVectorRep);
- v := [basedomain,Zero(basedomain)*[1..l]];
- Objectify(typ,v);
- return v;
+ l := ListWithIdenticalEntries(l,Zero(basedomain));
+ return NewVector( filter, basedomain, l );
end );
InstallMethod( NewMatrix,
- "for IsPlistMatrixRep, a ring, an int, and a list",
- [ IsPlistMatrixRep, IsRing, IsInt, IsList ],
- function( filter, basedomain, rl, l )
- local nd, filterVectors, m, e, filter2, i;
-
+ "for IsPlistMatrixRep, a semiring, an int, and a list",
+ [ IsPlistMatrixRep, IsSemiring, IsInt, IsList ],
+ function( filter, basedomain, ncols, l )
+ local m;
# If applicable then replace a flat list 'l' by a nested list
- # of lists of length 'rl'.
- if Length(l) > 0 and not IsVectorObj(l[1]) then
- nd := NestingDepthA(l);
- if nd < 2 or nd mod 2 = 1 then
- if Length(l) mod rl <> 0 then
- Error( "NewMatrix: Length of l is not a multiple of rl" );
+ # of lists of length 'ncols'.
+ if Length(l) = 0 then
+ # empty matrix
+ m := [];
+ elif IsVectorObj(l[1]) then
+ # list of vectors
+ # TODO: convert each IsVectorObj to a plist
+ m := List(l, AsPlist);
+ else
+ if NestingDepthA(l) mod 2 = 1 then
+ if Length(l) mod ncols <> 0 then
+ Error( "NewMatrix: Length of is not a multiple of " );
fi;
- l := List([0,rl..Length(l)-rl], i -> l{[i+1..i+rl]});
+ m := List([0,ncols..Length(l)-ncols], i -> l{[i+1..i+ncols]});
+ else
+ m := List(l, ShallowCopy);
fi;
fi;
- filterVectors := IsPlistVectorRep;
- m := 0*[1..Length(l)];
- for i in [1..Length(l)] do
- if IsVectorObj(l[i]) and IsPlistVectorRep(l[i]) then
- m[i] := ShallowCopy(l[i]);
- else
- m[i] := NewVector( filterVectors, basedomain, l[i] );
- fi;
- od;
- e := NewVector(filterVectors, basedomain, []);
- m := [basedomain,e,rl,m];
- filter2 := IsPlistMatrixRep and IsMutable;
+ # FIXME/TODO: should the following test be always performed
+ # or only at a higher assertion level?
+ Assert(0, ForAll(m, row -> Length(row) = ncols));
+ Assert(0, ForAll(m, row -> ForAll(row, x -> x in basedomain)));
+
+ m := [basedomain, Length(m), ncols, m];
+ filter := IsPlistMatrixRep and IsMutable;
if HasCanEasilyCompareElements(Representative(basedomain)) and
CanEasilyCompareElements(Representative(basedomain)) then
- filter2 := filter2 and CanEasilyCompareElements;
+ filter := filter and CanEasilyCompareElements;
fi;
Objectify( NewType(CollectionsFamily(FamilyObj(basedomain)),
- filter2), m );
+ filter), m );
return m;
end );
InstallMethod( NewZeroMatrix,
- "for IsPlistMatrixRep, a ring, and two ints",
- [ IsPlistMatrixRep, IsRing, IsInt, IsInt ],
+ "for IsPlistMatrixRep, a semiring, and two ints",
+ [ IsPlistMatrixRep, IsSemiring, IsInt, IsInt ],
function( filter, basedomain, rows, cols )
- local m,i,e,filter2;
- filter2 := IsPlistVectorRep;
- m := 0*[1..rows];
- e := NewVector(filter2, basedomain, []);
- for i in [1..rows] do
- m[i] := ZeroVector( cols, e );
- od;
- m := [basedomain,e,cols,m];
+ local m;
+ m := NullMat(rows, cols, basedomain);
+ m := [basedomain, rows, cols, m];
Objectify( NewType(CollectionsFamily(FamilyObj(basedomain)),
filter and IsMutable), m );
return m;
end );
InstallMethod( NewIdentityMatrix,
- "for IsPlistMatrixRep, a ring, and an int",
- [ IsPlistMatrixRep, IsRing, IsInt ],
+ "for IsPlistMatrixRep, a semiring, and an int",
+ [ IsPlistMatrixRep, IsSemiring, IsInt ],
function( filter, basedomain, dim )
local mat, one, i;
+ # TODO use ONE_MATRIX_MUTABLE
mat := NewZeroMatrix(filter, basedomain, dim, dim);
one := One(basedomain);
for i in [1..dim] do
@@ -140,28 +122,31 @@ InstallMethod( ViewObj, "for a plist vector", [ IsPlistVectorRep ],
else
Print("<");
fi;
- Print("plist vector over ",v![BDPOS]," of length ",Length(v![ELSPOS]),">");
+ Print("plist vector over ",BaseDomain(v)," of length ",Length(v![ELSPOS]),">");
end );
InstallMethod( PrintObj, "for a plist vector", [ IsPlistVectorRep ],
function( v )
+ local bd;
+ bd := BaseDomain(v);
Print("NewVector(IsPlistVectorRep");
- if IsFinite(v![BDPOS]) and IsField(v![BDPOS]) then
- Print(",GF(",Size(v![BDPOS]),"),",v![ELSPOS],")");
+ if IsFinite(bd) and IsField(bd) then
+ Print(",GF(",Size(bd),"),",v![ELSPOS],")");
else
- Print(",",String(v![BDPOS]),",",v![ELSPOS],")");
+ Print(",",String(bd),",",v![ELSPOS],")");
fi;
end );
InstallMethod( String, "for a plist vector", [ IsPlistVectorRep ],
function( v )
- local st;
+ local bd, st;
+ bd := BaseDomain(v);
st := "NewVector(IsPlistVectorRep";
- if IsFinite(v![BDPOS]) and IsField(v![BDPOS]) then
- Append(st,Concatenation( ",GF(",String(Size(v![BDPOS])),"),",
+ if IsFinite(bd) and IsField(bd) then
+ Append(st,Concatenation( ",GF(",String(Size(bd)),"),",
String(v![ELSPOS]),")" ));
else
- Append(st,Concatenation( ",",String(v![BDPOS]),",",
+ Append(st,Concatenation( ",",String(bd),",",
String(v![ELSPOS]),")" ));
fi;
return st;
@@ -215,8 +200,7 @@ InstallMethod( ZeroVector, "for an integer and a plist matrix",
[ IsInt, IsPlistMatrixRep ],
function( l, m )
local v;
- v := Objectify(TypeObj(m![EMPOS]),
- [m![BDPOS],ListWithIdenticalEntries(l,Zero(m![BDPOS]))]);
+ v := NewZeroVector(IsPlistVectorRep, m![BDPOS], l);
if not IsMutable(v) then SetFilterObj(v,IsMutable); fi;
return v;
end );
@@ -234,12 +218,7 @@ InstallMethod( Vector, "for a list and a plist vector",
[ IsList, IsPlistVectorRep ],
function( l, t )
local v;
- v := ShallowCopy(l);
- if IsGF2VectorRep(l) then
- PLAIN_GF2VEC(v);
- elif Is8BitVectorRep(l) then
- PLAIN_VEC8BIT(v);
- fi;
+ v := PlainListCopy(l);
v := Objectify(TypeObj(t),[t![BDPOS],v]);
if not IsMutable(v) then SetFilterObj(v,IsMutable); fi;
return v;
@@ -340,8 +319,7 @@ InstallMethod( \+, "for two plist vectors",
else
ty := TypeObj(a);
fi;
- return Objectify(ty,
- [a![BDPOS],SUM_LIST_LIST_DEFAULT(a![ELSPOS],b![ELSPOS])]);
+ return Objectify(ty, [a![BDPOS],a![ELSPOS]+b![ELSPOS]]);
end );
InstallMethod( \-, "for two plist vectors",
@@ -353,20 +331,19 @@ InstallMethod( \-, "for two plist vectors",
else
ty := TypeObj(a);
fi;
- return Objectify(ty,
- [a![BDPOS],DIFF_LIST_LIST_DEFAULT(a![ELSPOS],b![ELSPOS])]);
+ return Objectify(ty, [a![BDPOS],a![ELSPOS]-b![ELSPOS]]);
end );
InstallMethod( \=, "for two plist vectors",
[ IsPlistVectorRep, IsPlistVectorRep ],
function( a, b )
- return EQ_LIST_LIST_DEFAULT(a![ELSPOS],b![ELSPOS]);
+ return a![ELSPOS] = b![ELSPOS];
end );
InstallMethod( \<, "for two plist vectors",
[ IsPlistVectorRep, IsPlistVectorRep ],
function( a, b )
- return LT_LIST_LIST_DEFAULT(a![ELSPOS],b![ELSPOS]);
+ return a![ELSPOS] < b![ELSPOS];
end );
InstallMethod( AddRowVector, "for two plist vectors",
@@ -448,39 +425,26 @@ InstallOtherMethod( MultVectorLeft, "for an integer vector, and a small integer"
InstallMethod( \*, "for a plist vector and a scalar",
[ IsPlistVectorRep, IsScalar ],
function( v, s )
- return Objectify( TypeObj(v),
- [v![BDPOS],PROD_LIST_SCL_DEFAULT(v![ELSPOS],s)] );
+ return Objectify( TypeObj(v), [v![BDPOS],v![ELSPOS]*s] );
end );
InstallMethod( \*, "for a scalar and a plist vector",
[ IsScalar, IsPlistVectorRep ],
function( s, v )
- return Objectify( TypeObj(v),
- [v![BDPOS],PROD_SCL_LIST_DEFAULT(s,v![ELSPOS])] );
+ return Objectify( TypeObj(v), [v![BDPOS],s*v![ELSPOS]] );
end );
InstallMethod( \/, "for a plist vector and a scalar",
[ IsPlistVectorRep, IsScalar ],
function( v, s )
- return Objectify( TypeObj(v),
- [v![BDPOS],PROD_LIST_SCL_DEFAULT(v![ELSPOS],s^-1)] );
+ return Objectify( TypeObj(v), [v![BDPOS],v![ELSPOS]/s] );
end );
-InstallMethod( AdditiveInverseSameMutability, "for a plist vector",
- [ IsPlistVectorRep ],
- function( v )
+InstallMethod(LeftQuotient, "for a scalar and a plist vector",
+ [ IsScalar, IsPlistVectorRep ],
+ function( s, v )
return Objectify( TypeObj(v),
- [v![BDPOS],AdditiveInverseSameMutability(v![ELSPOS])] );
- end );
-
-InstallMethod( AdditiveInverseImmutable, "for a plist vector",
- [ IsPlistVectorRep ],
- function( v )
- local res;
- res := Objectify( TypeObj(v),
- [v![BDPOS],AdditiveInverseSameMutability(v![ELSPOS])] );
- MakeImmutable(res);
- return res;
+ [v![BDPOS],LeftQuotient(s,v![ELSPOS])] );
end );
InstallMethod( AdditiveInverseMutable, "for a plist vector",
@@ -493,19 +457,6 @@ InstallMethod( AdditiveInverseMutable, "for a plist vector",
return res;
end );
-InstallMethod( ZeroSameMutability, "for a plist vector", [ IsPlistVectorRep ],
- function( v )
- return Objectify(TypeObj(v),[v![BDPOS],ZeroSameMutability(v![ELSPOS])]);
- end );
-
-InstallMethod( ZeroImmutable, "for a plist vector", [ IsPlistVectorRep ],
- function( v )
- local res;
- res := Objectify(TypeObj(v),[v![BDPOS],ZeroImmutable(v![ELSPOS])]);
- MakeImmutable(res);
- return res;
- end );
-
InstallMethod( ZeroMutable, "for a plist vector", [ IsPlistVectorRep ],
function( v )
local res;
@@ -525,7 +476,7 @@ InstallMethodWithRandomSource( Randomize,
[ IsRandomSource, IsPlistVectorRep and IsMutable ],
function( rs, v )
local bd,i;
- bd := v![BDPOS];
+ bd := BaseDomain(v);
for i in [1..Length(v![ELSPOS])] do
v![ELSPOS][i] := Random( rs, bd );
od;
@@ -560,19 +511,19 @@ InstallMethod( BaseDomain, "for a plist matrix",
InstallMethod( NumberRows, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- return Length(m![ROWSPOS]);
+ return m![NUM_ROWS_POS];
end );
InstallMethod( NumberColumns, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- return m![RLPOS];
+ return m![NUM_COLS_POS];
end );
InstallMethod( DimensionsMat, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- return [Length(m![ROWSPOS]),m![RLPOS]];
+ return [NrRows(m),NrCols(m)];
end );
@@ -583,10 +534,9 @@ InstallMethod( DimensionsMat, "for a plist matrix",
InstallMethod( ZeroMatrix, "for two integers and a plist matrix",
[ IsInt, IsInt, IsPlistMatrixRep ],
function( rows,cols,m )
- local l,t,res;
- t := m![EMPOS];
- l := List([1..rows],i->ZeroVector(cols,t));
- res := Objectify( TypeObj(m), [m![BDPOS],t,cols,l] );
+ local l,res;
+ l := NullMat(rows, cols, m![BDPOS]);
+ res := Objectify( TypeObj(m), [m![BDPOS],rows,cols,l] );
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
@@ -595,138 +545,58 @@ InstallMethod( ZeroMatrix, "for two integers and a plist matrix",
InstallMethod( IdentityMatrix, "for an integer and a plist matrix",
[ IsInt, IsPlistMatrixRep ],
- function( rows,m )
- local i,l,o,t,res;
- t := m![EMPOS];
- l := List([1..rows],i->ZeroVector(rows,t));
+ function( rows, m )
+ local i,l,o,res;
+ l := List([1..rows],i->ListWithIdenticalEntries(rows, Zero(m![BDPOS])));
o := One(m![BDPOS]);
for i in [1..rows] do
- l[i][i] := o;
+ l[i,i] := o;
od;
- res := Objectify( TypeObj(m), [m![BDPOS],t,rows,l] );
+ res := Objectify( TypeObj(m), [m![BDPOS],rows,rows,l] );
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
return res;
end );
-InstallMethod( Matrix, "for a list and a plist matrix",
- [ IsList, IsInt, IsPlistMatrixRep ],
- function( rows,rowlen,m )
- local i,l,nrrows,res,t;
- t := m![EMPOS];
- if Length(rows) > 0 then
- if IsVectorObj(rows[1]) and IsPlistVectorRep(rows[1]) then
- nrrows := Length(rows);
- l := rows;
- elif IsList(rows[1]) then
- nrrows := Length(rows);
- l := ListWithIdenticalEntries(Length(rows),0);
- for i in [1..Length(rows)] do
- l[i] := Vector(rows[i],t);
- od;
- else # a flat initializer:
- nrrows := Length(rows)/rowlen;
- l := ListWithIdenticalEntries(nrrows,0);
- for i in [1..nrrows] do
- l[i] := Vector(rows{[(i-1)*rowlen+1..i*rowlen]},t);
- od;
- fi;
- else
- l := [];
- nrrows := 0;
- fi;
- res := Objectify( TypeObj(m), [m![BDPOS],t,rowlen,l] );
- if not IsMutable(m) then
- SetFilterObj(res,IsMutable);
- fi;
- return res;
- end );
-
-
-############################################################################
-# A selection of list operations:
-############################################################################
-
-InstallOtherMethod( \[\], "for a plist matrix and a positive integer",
-#T Once the declaration of '\[\]' for 'IsMatrixObj' disappears,
-#T we can use 'InstallMethod'.
- [ IsPlistMatrixRep, IsPosInt ],
- function( m, p )
- return m![ROWSPOS][p];
- end );
-
-InstallMethod( \[\]\:\=,
- "for a plist matrix, a positive integer, and a plist vector",
- [ IsPlistMatrixRep and IsMutable, IsPosInt, IsPlistVectorRep ],
- function( m, p, v )
- m![ROWSPOS][p] := v;
- end );
-
-InstallMethod( \{\}, "for a plist matrix and a list",
- [ IsPlistMatrixRep, IsList ],
- function( m, p )
- local l;
- l := m![ROWSPOS]{p};
- return Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],m![RLPOS],l]);
- end );
-
-InstallMethod( Add, "for a plist matrix and a plist vector",
- [ IsPlistMatrixRep and IsMutable, IsPlistVectorRep ],
- function( m, v )
- Add(m![ROWSPOS],v);
- end );
-
-InstallMethod( Add, "for a plist matrix, a plist vector, and a pos. int",
- [ IsPlistMatrixRep and IsMutable, IsPlistVectorRep, IsPosInt ],
- function( m, v, p )
- Add(m![ROWSPOS],v,p);
- end );
-
-InstallMethod( Remove, "for a plist matrix",
- [ IsPlistMatrixRep and IsMutable ],
- m -> Remove( m![ROWSPOS] ) );
-
-InstallMethod( Remove, "for a plist matrix, and a position",
- [ IsPlistMatrixRep and IsMutable, IsPosInt ],
- function( m, p )
- Remove( m![ROWSPOS],p );
- end );
-#T must return the removed row if it was bound
-
-InstallMethod( IsBound\[\], "for a plist matrix, and a position",
- [ IsPlistMatrixRep, IsPosInt ],
- function( m, p )
- return p <= Length(m![ROWSPOS]);
- end );
-
-InstallMethod( Unbind\[\], "for a plist matrix, and a position",
- [ IsPlistMatrixRep and IsMutable, IsPosInt ],
- function( m, p )
- if p <> Length(m![ROWSPOS]) then
- ErrorNoReturn("Unbind\\[\\]: Matrices must stay dense, you cannot Unbind here");
- fi;
- Unbind( m![ROWSPOS][p] );
- end );
-
-InstallMethod( \{\}\:\=, "for a plist matrix, a list, and a plist matrix",
- [ IsPlistMatrixRep and IsMutable, IsList,
- IsPlistMatrixRep ],
- function( m, pp, n )
- m![ROWSPOS]{pp} := n![ROWSPOS];
- end );
-
-InstallMethod( Append, "for two plist matrices",
- [ IsPlistMatrixRep and IsMutable, IsPlistMatrixRep ],
- function( m, n )
- Append(m![ROWSPOS],n![ROWSPOS]);
- end );
-
+# InstallMethod( Matrix, "for a list and a plist matrix",
+# [ IsList, IsInt, IsPlistMatrixRep ],
+# function( rows,rowlen,m )
+# local i,l,nrrows,res;
+# if Length(rows) > 0 then
+# if IsVectorObj(rows[1]) and IsPlistVectorRep(rows[1]) then
+# nrrows := Length(rows);
+# l := rows;
+# elif IsList(rows[1]) then
+# nrrows := Length(rows);
+# l := ListWithIdenticalEntries(Length(rows),0);
+# for i in [1..Length(rows)] do
+# l[i] := Vector(rows[i],t);
+# od;
+# else # a flat initializer:
+# nrrows := Length(rows)/rowlen;
+# l := ListWithIdenticalEntries(nrrows,0);
+# for i in [1..nrrows] do
+# l[i] := Vector(rows{[(i-1)*rowlen+1..i*rowlen]},t);
+# od;
+# fi;
+# else
+# l := [];
+# nrrows := 0;
+# fi;
+# res := Objectify( TypeObj(m), [m![BDPOS],rowlen,l] );
+# if not IsMutable(m) then
+# SetFilterObj(res,IsMutable);
+# fi;
+# return res;
+# end );
+
+# FIXME: does ShallowCopy even make sense for a matrixobj???
InstallMethod( ShallowCopy, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local res;
- res := Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],m![RLPOS],
+ res := Objectify(TypeObj(m),[m![BDPOS],m![NUM_ROWS_POS],m![NUM_COLS_POS],
ShallowCopy(m![ROWSPOS])]);
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
@@ -742,30 +612,12 @@ InstallMethod( PostMakeImmutable, "for a plist matrix",
MakeImmutable( m![ROWSPOS] );
end );
-InstallMethod( ListOp, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- return List(m![ROWSPOS]);
- end );
-
-InstallMethod( ListOp, "for a plist matrix and a function",
- [ IsPlistMatrixRep, IsFunction ],
- function( m, f )
- return List(m![ROWSPOS],f);
- end );
-
-InstallMethod( Unpack, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- return List(m![ROWSPOS],v->ShallowCopy(v![ELSPOS]));
- end );
-
InstallMethod( MutableCopyMat, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local l,res;
- l := List(m![ROWSPOS],ShallowCopy);
- res := Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],m![RLPOS],l]);
+ l := MutableCopyMat(m![ROWSPOS]);
+ res := Objectify(TypeObj(m),[m![BDPOS],NrRows(m),NrCols(m),l]);
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
@@ -776,11 +628,8 @@ InstallMethod( ExtractSubMatrix, "for a plist matrix, and two lists",
[ IsPlistMatrixRep, IsList, IsList ],
function( m, p, q )
local i,l;
- l := m![ROWSPOS]{p};
- for i in [1..Length(l)] do
- l[i] := Objectify(TypeObj(l[i]),[l[i]![BDPOS],l[i]![ELSPOS]{q}]);
- od;
- return Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],Length(q),l]);
+ l := m![ROWSPOS]{p}{q};
+ return Objectify(TypeObj(m),[m![BDPOS],Length(p),Length(q),l]);
end );
InstallMethod( CopySubMatrix, "for two plist matrices and four lists",
@@ -788,11 +637,11 @@ InstallMethod( CopySubMatrix, "for two plist matrices and four lists",
IsList, IsList, IsList, IsList ],
function( m, n, srcrows, dstrows, srccols, dstcols )
local i;
- # This eventually should go into the kernel without creating
- # a intermediate objects:
+ # TODO: this eventually should go into the kernel without creating
+ # any intermediate objects:
for i in [1..Length(srcrows)] do
- n![ROWSPOS][dstrows[i]]![ELSPOS]{dstcols} :=
- m![ROWSPOS][srcrows[i]]![ELSPOS]{srccols};
+ n![ROWSPOS][dstrows[i]]{dstcols} :=
+ m![ROWSPOS][srcrows[i]]{srccols};
od;
end );
@@ -813,13 +662,13 @@ InstallOtherMethod( CopySubMatrix,
InstallMethod( MatElm, "for a plist matrix and two positions",
[ IsPlistMatrixRep, IsPosInt, IsPosInt ],
function( m, row, col )
- return m![ROWSPOS][row]![ELSPOS][col];
+ return m![ROWSPOS][row,col];
end );
InstallMethod( SetMatElm, "for a plist matrix, two positions, and an object",
[ IsPlistMatrixRep and IsMutable, IsPosInt, IsPosInt, IsObject ],
function( m, row, col, ob )
- m![ROWSPOS][row]![ELSPOS][col] := ob;
+ m![ROWSPOS][row,col] := ob;
end );
@@ -831,16 +680,18 @@ InstallMethod( ViewObj, "for a plist matrix", [ IsPlistMatrixRep ],
function( m )
Print("<");
if not IsMutable(m) then Print("immutable "); fi;
- Print(Length(m![ROWSPOS]),"x",m![RLPOS],"-matrix over ",m![BDPOS],">");
+ Print(NrRows(m),"x",NrCols(m),"-matrix over ",m![BDPOS],">");
end );
InstallMethod( PrintObj, "for a plist matrix", [ IsPlistMatrixRep ],
function( m )
+ local bd;
+ bd := BaseDomain(m);
Print("NewMatrix(IsPlistMatrixRep");
- if IsFinite(m![BDPOS]) and IsField(m![BDPOS]) then
- Print(",GF(",Size(m![BDPOS]),"),");
+ if IsFinite(bd) and IsField(bd) then
+ Print(",GF(",Size(bd),"),");
else
- Print(",",String(m![BDPOS]),",");
+ Print(",",String(bd),",");
fi;
Print(NumberColumns(m),",",Unpack(m),")");
end );
@@ -850,29 +701,30 @@ InstallMethod( Display, "for a plist matrix", [ IsPlistMatrixRep ],
local i;
Print("<");
if not IsMutable(m) then Print("immutable "); fi;
- Print(Length(m![ROWSPOS]),"x",m![RLPOS],"-matrix over ",m![BDPOS],":\n");
- for i in [1..Length(m![ROWSPOS])] do
+ Print(NrRows(m),"x",NrCols(m),"-matrix over ",m![BDPOS],":\n");
+ for i in [1..NrRows(m)] do
if i = 1 then
Print("[");
else
Print(" ");
fi;
- Print(m![ROWSPOS][i]![ELSPOS],"\n");
+ Print(m![ROWSPOS][i],"\n");
od;
Print("]>\n");
end );
InstallMethod( String, "for plist matrix", [ IsPlistMatrixRep ],
function( m )
- local st;
+ local bd, st;
+ bd := BaseDomain(m);
st := "NewMatrix(IsPlistMatrixRep";
Add(st,',');
- if IsFinite(m![BDPOS]) and IsField(m![BDPOS]) then
+ if IsFinite(bd) and IsField(bd) then
Append(st,"GF(");
- Append(st,String(Size(m![BDPOS])));
+ Append(st,String(Size(bd)));
Append(st,"),");
else
- Append(st,String(m![BDPOS]));
+ Append(st,String(bd));
Append(st,",");
fi;
Append(st,String(NumberColumns(m)));
@@ -890,13 +742,18 @@ InstallMethod( \+, "for two plist matrices",
[ IsPlistMatrixRep, IsPlistMatrixRep ],
function( a, b )
local ty;
+ # TODO: check that dimensions match?
if not IsMutable(a) and IsMutable(b) then
ty := TypeObj(b);
else
ty := TypeObj(a);
fi;
- return Objectify(ty,[a![BDPOS],a![EMPOS],a![RLPOS],
- SUM_LIST_LIST_DEFAULT(a![ROWSPOS],b![ROWSPOS])]);
+ # FIXME: why do we blindly copy the number of columns from the first argument?
+ # Either need to verify dimensions match, or, if we want to allow adding
+ # arbitrary matrices, then we must use the maximum of the number of columns
+ # here, no?
+ return Objectify(ty,[a![BDPOS],a![NUM_ROWS_POS],a![NUM_COLS_POS],
+ a![ROWSPOS]+b![ROWSPOS]]);
end );
InstallMethod( \-, "for two plist matrices",
@@ -908,8 +765,8 @@ InstallMethod( \-, "for two plist matrices",
else
ty := TypeObj(a);
fi;
- return Objectify(ty,[a![BDPOS],a![EMPOS],a![RLPOS],
- DIFF_LIST_LIST_DEFAULT(a![ROWSPOS],b![ROWSPOS])]);
+ return Objectify(ty,[a![BDPOS],a![NUM_ROWS_POS],a![NUM_COLS_POS],
+ a![ROWSPOS]+b![ROWSPOS]]);
end );
InstallMethod( \*, "for two plist matrices",
@@ -922,103 +779,49 @@ InstallMethod( \*, "for two plist matrices",
else
ty := TypeObj(a);
fi;
- if not a![RLPOS] = Length(b![ROWSPOS]) then
+ if NrCols(a) <> NrRows(b) then
ErrorNoReturn("\\*: Matrices do not fit together");
fi;
if not IsIdenticalObj(a![BDPOS],b![BDPOS]) then
ErrorNoReturn("\\*: Matrices not over same base domain");
fi;
- l := ListWithIdenticalEntries(Length(a![ROWSPOS]),0);
- for i in [1..Length(l)] do
- if b![RLPOS] = 0 then
- l[i] := b![EMPOS];
- else
- v := a![ROWSPOS][i];
- w := ZeroVector(b![RLPOS],b![EMPOS]);
- for j in [1..a![RLPOS]] do
- AddRowVector(w,b![ROWSPOS][j],v[j]);
- od;
- l[i] := w;
- fi;
- od;
+ l := a![ROWSPOS]*b![ROWSPOS];
if not IsMutable(a) and not IsMutable(b) then
MakeImmutable(l);
fi;
- return Objectify( ty, [a![BDPOS],a![EMPOS],b![RLPOS],l] );
+ return Objectify( ty, [a![BDPOS],a![NUM_ROWS_POS],b![NUM_COLS_POS],l] );
end );
InstallMethod( \=, "for two plist matrices",
[ IsPlistMatrixRep, IsPlistMatrixRep ],
function( a, b )
- return EQ_LIST_LIST_DEFAULT(a![ROWSPOS],b![ROWSPOS]);
+ return a![ROWSPOS] = b![ROWSPOS];
end );
InstallMethod( \<, "for two plist matrices",
[ IsPlistMatrixRep, IsPlistMatrixRep ],
function( a, b )
- return LT_LIST_LIST_DEFAULT(a![ROWSPOS],b![ROWSPOS]);
- end );
-
-InstallMethod( AdditiveInverseSameMutability, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local l;
- l := List(m![ROWSPOS],AdditiveInverseSameMutability);
- if not IsMutable(m) then
- MakeImmutable(l);
- fi;
- return Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
- end );
-
-InstallMethod( AdditiveInverseImmutable, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local l,res;
- l := List(m![ROWSPOS],AdditiveInverseImmutable);
- res := Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
- MakeImmutable(res);
- return res;
+ return a![ROWSPOS] < b![ROWSPOS];
end );
InstallMethod( AdditiveInverseMutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local l,res;
- l := List(m![ROWSPOS],AdditiveInverseMutable);
- res := Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
+ l := AdditiveInverseMutable(m![ROWSPOS]);
+ res := Objectify( TypeObj(m), [m![BDPOS],m![NUM_ROWS_POS],m![NUM_COLS_POS],l] );
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
return res;
end );
-InstallMethod( ZeroSameMutability, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local l;
- l := List(m![ROWSPOS],ZeroSameMutability);
- if not IsMutable(m) then
- MakeImmutable(l);
- fi;
- return Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
- end );
-
-InstallMethod( ZeroImmutable, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local l,res;
- l := List(m![ROWSPOS],ZeroImmutable);
- res := Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
- MakeImmutable(res);
- return res;
- end );
-
InstallMethod( ZeroMutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local l,res;
- l := List(m![ROWSPOS],ZeroMutable);
- res := Objectify( TypeObj(m), [m![BDPOS],m![EMPOS],m![RLPOS],l] );
+ l := ZeroMutable(m![ROWSPOS]);
+ res := Objectify( TypeObj(m), [m![BDPOS],m![NUM_ROWS_POS],m![NUM_COLS_POS],l] );
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
@@ -1028,132 +831,37 @@ InstallMethod( ZeroMutable, "for a plist matrix",
InstallMethod( IsZero, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- local i;
- for i in [1..Length(m![ROWSPOS])] do
- if not IsZero(m![ROWSPOS][i]) then
- return false;
- fi;
- od;
- return true;
+ return IsZero(m![ROWSPOS]); # TODO: check that this results in "optimal" code
end );
InstallMethod( IsOne, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- local i,j,n;
- if Length(m![ROWSPOS]) <> m![RLPOS] then
- #Error("IsOne: Matrix must be square");
- return false;
- fi;
- n := m![RLPOS];
- for i in [1..n] do
- if not IsOne(m![ROWSPOS][i]![ELSPOS][i]) then return false; fi;
- for j in [1..i-1] do
- if not IsZero(m![ROWSPOS][i]![ELSPOS][j]) then return false; fi;
- od;
- for j in [i+1..n] do
- if not IsZero(m![ROWSPOS][i]![ELSPOS][j]) then return false; fi;
- od;
- od;
- return true;
- end );
-
-InstallMethod( OneSameMutability, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local o;
- if m![RLPOS] <> Length(m![ROWSPOS]) then
- #Error("OneSameMutability: Matrix is not square");
- #return;
- return fail;
- fi;
- o := IdentityMatrix(m![RLPOS],m);
- if not IsMutable(m) then
- MakeImmutable(o);
- fi;
- return o;
+ return IsOne(m![ROWSPOS]); # TODO: check that this results in "optimal" code
end );
InstallMethod( OneMutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- if m![RLPOS] <> Length(m![ROWSPOS]) then
+ if NrCols(m) <> NrRows(m) then
#Error("OneMutable: Matrix is not square");
#return;
return fail;
fi;
- return IdentityMatrix(m![RLPOS],m);
- end );
-
-InstallMethod( OneImmutable, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local o;
- if m![RLPOS] <> Length(m![ROWSPOS]) then
- #Error("OneImmutable: Matrix is not square");
- #return;
- return fail;
- fi;
- o := IdentityMatrix(m![RLPOS],m);
- MakeImmutable(o);
- return o;
+ return NewIdentityMatrix(IsPlistMatrixRep,NrCols(m));
end );
-# For the moment we delegate to the fast kernel arithmetic for plain
-# lists of plain lists:
-
InstallMethod( InverseMutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local n;
- if m![RLPOS] <> Length(m![ROWSPOS]) then
- #Error("InverseMutable: Matrix is not square");
- #return;
- return fail;
- fi;
- # Make a plain list of lists:
- n := List(m![ROWSPOS],x->x![ELSPOS]);
- n := InverseMutable(n); # Invert!
- if n = fail then return fail; fi;
- return Matrix(n,Length(n),m);
- end );
-
-InstallMethod( InverseImmutable, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local n;
- if m![RLPOS] <> Length(m![ROWSPOS]) then
- #Error("InverseMutable: Matrix is not square");
- #return;
+ if NrCols(m) <> NrRows(m) then
return fail;
fi;
# Make a plain list of lists:
- n := List(m![ROWSPOS],x->x![ELSPOS]);
- n := InverseMutable(n); # Invert!
+ n := InverseMutable(m![ROWSPOS]);
if n = fail then return fail; fi;
- n := Matrix(n,Length(n),m);
- MakeImmutable(n);
- return n;
- end );
-
-InstallMethod( InverseSameMutability, "for a plist matrix",
- [ IsPlistMatrixRep ],
- function( m )
- local n;
- if m![RLPOS] <> Length(m![ROWSPOS]) then
- #Error("InverseMutable: Matrix is not square");
- #return;
- return fail;
- fi;
- # Make a plain list of lists:
- n := List(m![ROWSPOS],x->x![ELSPOS]);
- n := InverseMutable(n); # Invert!
- if n = fail then return fail; fi;
- n := Matrix(n,Length(n),m);
- if not IsMutable(m) then
- MakeImmutable(n);
- fi;
- return n;
+ return NewMatrix(IsPlistMatrixRep, BaseDomain(m), NrCols(m), n);
end );
InstallMethod( RankMat, "for a plist matrix",
@@ -1180,19 +888,22 @@ InstallMethodWithRandomSource( Randomize,
InstallMethod( TransposedMatMutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
- local i,n,v;
- n := ListWithIdenticalEntries(m![RLPOS],0);
- for i in [1..m![RLPOS]] do
- v := Vector(List(m![ROWSPOS],v->v![ELSPOS][i]),m![EMPOS]);
- n[i] := v;
- od;
- return Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],Length(m![ROWSPOS]),n]);
+ local trans;
+ # FIXME/TODO: implement this generic, or optimized for IsPlistMatrixRep?
+ # Right now, we do the latter:
+ trans := TransposedMatMutable(m![ROWSPOS]);
+
+
+ # FIXME: using TypeObj(m) below is probably wrong, as it
+ # may set IsMutable incorrectly
+ return Objectify(TypeObj(m),[m![BDPOS],NrCols(m),NrRows(m),trans]);
end );
InstallMethod( TransposedMatImmutable, "for a plist matrix",
[ IsPlistMatrixRep ],
function( m )
local n;
+ # TODO: this could be a generic implementation
n := TransposedMatMutable(m);
MakeImmutable(n);
return n;
@@ -1202,36 +913,17 @@ InstallMethod( \*, "for a plist vector and a plist matrix",
[ IsPlistVectorRep, IsPlistMatrixRep ],
function( v, m )
local i,res,s;
- res := ZeroVector(m![RLPOS],m![EMPOS]);
- for i in [1..Length(v![ELSPOS])] do
- s := v![ELSPOS][i];
- if not IsZero(s) then
- AddRowVector(res,m![ROWSPOS][i],v![ELSPOS][i]);
- fi;
- od;
+ # TODO: should we verify that Length(v) = NrRows(m)?
+ res := ZeroVector(NrCols(m),v);
+ res![ELSPOS] := v![ELSPOS] * m![ROWSPOS];
if not IsMutable(v) and not IsMutable(m) then
MakeImmutable(res);
fi;
return res;
end );
-#InstallMethod( \^, "for a plist vector and an integer",
-# [ IsPlistMatrixRep, IsInt ],
-# function( m, i )
-# local mi;
-# if m![RLPOS] <> Length(m![ROWSPOS]) then
-# #Error("\\^: Matrix must be square");
-# #return;
-# return fail;
-# fi;
-# if i = 0 then return OneSameMutability(m);
-# elif i > 0 then return POW_OBJ_INT(m,i);
-# else
-# mi := InverseSameMutability(m);
-# if mi = fail then return fail; fi;
-# return POW_OBJ_INT( mi, -i );
-# fi;
-# end );
+# TODO: what about \* for a matrix and a vector?
+
InstallMethod( ConstructingFilter, "for a plist vector",
[ IsPlistVectorRep ],
@@ -1245,24 +937,22 @@ InstallMethod( ConstructingFilter, "for a plist matrix",
return IsPlistMatrixRep;
end );
-InstallMethod( ChangedBaseDomain, "for a plist vector, and a domain",
- [ IsPlistVectorRep, IsRing ],
+InstallMethod( ChangedBaseDomain, "for a plist vector, and a semiring",
+ [ IsPlistVectorRep, IsSemiring ],
function( v, r )
return NewVector( IsPlistVectorRep, r, v![ELSPOS] );
end );
-InstallMethod( ChangedBaseDomain, "for a plist matrix, and a domain",
- [ IsPlistMatrixRep, IsRing ],
+InstallMethod( ChangedBaseDomain, "for a plist matrix, and a semiring",
+ [ IsPlistMatrixRep, IsSemiring ],
function( m, r )
return NewMatrix(IsPlistMatrixRep, r, NumberColumns(m),
List(m![ROWSPOS], x-> x![ELSPOS]));
end );
-InstallMethod( CompatibleVector, "for a plist matrix",
+InstallMethod( CompatibleVectorFilter, "for a plist matrix",
[ IsPlistMatrixRep ],
- function( v )
- return NewZeroVector(IsPlistVectorRep,BaseDomain(v),NumberRows(v));
- end );
+ M -> IsPlistVectorRep );
InstallMethod( NewCompanionMatrix,
"for IsPlistMatrixRep, a polynomial and a ring",
@@ -1276,13 +966,12 @@ InstallMethod( NewCompanionMatrix,
Error("CompanionMatrix: polynomial is not monic");
return fail;
fi;
- ll := NewMatrix(IsPlistMatrixRep,bd,n,[]);
+ ll := NewZeroMatrix(IsPlistMatrixRep,bd,n,n);
l := Vector(-l{[1..n]},CompatibleVector(ll));
for i in [1..n-1] do
- Add(ll,ZeroMutable(l));
- ll[i][i+1] := one;
+ ll[i,i+1] := one;
od;
- Add(ll,l);
+ ll![ROWSPOS][n] := l; # FIXME: we need a function to copy a vector into a row?
return ll;
end );
diff --git a/tst/testinstall/MatrixObj/NewMatrix.tst b/tst/testinstall/MatrixObj/NewMatrix.tst
new file mode 100644
index 00000000000..250f68f3fca
--- /dev/null
+++ b/tst/testinstall/MatrixObj/NewMatrix.tst
@@ -0,0 +1,30 @@
+# IsPlistMatrixRep
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ ] ); Display(last);
+<0x3-matrix over Integers>
+<0x3-matrix over Integers:
+]>
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ 1, 2, 3 ] ); Display(last);
+<1x3-matrix over Integers>
+<1x3-matrix over Integers:
+[[ 1, 2, 3 ]
+]>
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ 1, 2, 3, 4, 5, 6 ] ); Display(last);
+<2x3-matrix over Integers>
+<2x3-matrix over Integers:
+[[ 1, 2, 3 ]
+ [ 4, 5, 6 ]
+]>
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ [1, 2, 3], [4, 5, 6] ] ); Display(last);
+<2x3-matrix over Integers>
+<2x3-matrix over Integers:
+[[ 1, 2, 3 ]
+ [ 4, 5, 6 ]
+]>
+
+# IsPlistMatrixRep errors
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ 1 ] );
+Error, NewMatrix: Length of is not a multiple of
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ 1, 2 ] );
+Error, NewMatrix: Length of is not a multiple of
+gap> NewMatrix(IsPlistMatrixRep, Integers, 3, [ 1, 2, 3, 4 ] );
+Error, NewMatrix: Length of is not a multiple of