diff --git a/doc/ref/matobj.xml b/doc/ref/matobj.xml
index bcf39d27d8..2b5a387a25 100644
--- a/doc/ref/matobj.xml
+++ b/doc/ref/matobj.xml
@@ -173,10 +173,10 @@ for these matrix objects.
-One implementation of such matrices is given by the
+Two implementation of such matrices is given by the
value
-,
-and any row of these matrices is a vector object in
+,
+and any row of these matrices can be accessed as a vector object in
.
Note that these objects do not lie in
(and in particular not in ),
@@ -190,8 +190,9 @@ in the last position,
that is, the vector and matrix objects insist on being dense.
All rows of a matrix must have the same length and the same base domain.
-<#Include Label="IsPlistVectorRep">
-<#Include Label="IsPlistMatrixRep">
+<#Include Label="IsRowPlistMatrixRep">
+<#Include Label="IsPlistVectorRep">
+<#Include Label="IsPlistMatrixRep">
<#Include Label="RowListMatObj_[]">
<#Include Label="RowListMatObj_[]_ASS">
<#Include Label="RowListMatObj_{}">
diff --git a/lib/matobj2.gd b/lib/matobj2.gd
index 69061b7c90..c20303af88 100644
--- a/lib/matobj2.gd
+++ b/lib/matobj2.gd
@@ -93,7 +93,7 @@
## (see )
## and their dimensions.
## The basic condition is that the entries of vector and matrix objects
-## must either lie in the base domain or naturally embed in the sense that
+## must either lie in the base domain or naturally map into it in the sense that
## addition and multiplication automatically work with elements of the
## base domain;
## for example, a matrix object over a polynomial ring may also contain
diff --git a/lib/matobjplist.gd b/lib/matobjplist.gd
index f2715f05fb..ecc80ad318 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
@@ -59,33 +59,48 @@ DeclareRepresentation( "IsPlistVectorRep",
##
##
## An object obj in
describes
+## a matrix object (see ) that internal stores its
+## entries as a classic GAP matrix, that is as a plain list (see
+## ) of plain lists. Therefore any such GAP matrix
+## can be represented as a , making this
+## representation very versatile, and a good place to start if one wants to
+## adapt code which previously produced such classic GAP matrices to instead
+## produce matrix objects.
+##
+##
+## <#/GAPDoc>
+##
+## Implementation note: a matrix in IsPlistMatrixRep is internally
+## represented as a positional object that stores four entries:
+## - its base domain
+# - the number of rows
+## - the number of columns
+## - a plain list of its rows, each also a plain list
+DeclareRepresentation( "IsPlistMatrixRep",
+ IsListMatrix and IsPositionalObjectRep
+ and IsNoImmediateMethodsObject
+ and HasNumberRows and HasNumberColumns
+ and HasBaseDomain and HasOneOfBaseDomain and HasZeroOfBaseDomain,
+ [] );
+
+
+#############################################################################
+##
+## <#GAPDoc Label="IsRowPlistMatrixRep">
+##
+##
+##
+##
+## An object obj in describes
## a matrix object (see ) that behaves similar to
## a list of its rows, in the sense defined in
## Section .
-## It is internally represented as a positional object
-## (see that stores 4 entries:
-##
-## -
-## its base domain
-## (see
),
-##
-## -
-## an empty vector in the representation of each row,
-##
-## -
-## the number of columns
-## (see
), and
-##
-## -
-## a plain list (see
of its rows,
-## each of them being an object in .
-##
-##
+## Its rows can be accessed as objects in ,
##
##
## <#/GAPDoc>
##
-DeclareRepresentation( "IsPlistMatrixRep",
+DeclareRepresentation( "IsRowPlistMatrixRep",
IsRowListMatrix and IsPositionalObjectRep
and IsNoImmediateMethodsObject
and HasNumberRows and HasNumberColumns
@@ -94,24 +109,16 @@ DeclareRepresentation( "IsPlistMatrixRep",
# 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 2abddc4d6b..c2b2f97837 100644
--- a/lib/matobjplist.gi
+++ b/lib/matobjplist.gi
@@ -18,108 +18,98 @@
# Constructors:
############################################################################
-InstallGlobalFunction( MakePlistVectorType,
- function( basedomain, filter )
- local T, filter2;
- filter2 := filter and IsMutable;
+BindGlobal( "MakeIsPlistVectorRep",
+ function( basedomain, list )
+ local filter, 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);
+ typ := NewType(FamilyObj(basedomain), filter);
+ return Objectify(typ, [ basedomain, list ]);
+ 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;
+
+InstallMethod( NewVector, "for IsPlistVectorRep, a semiring, and a list",
+ [ IsPlistVectorRep, IsSemiring, IsList ],
+ function( filter, basedomain, list )
+ list := ShallowCopy( list );
+ return MakeIsPlistVectorRep( basedomain, list );
end );
-InstallMethod( NewZeroVector, "for IsPlistVectorRep, a ring, and an int",
- [ IsPlistVectorRep, IsRing, IsInt ],
- function( filter, basedomain, l )
- local typ, v;
- typ := MakePlistVectorType(basedomain,IsPlistVectorRep);
- v := [basedomain,Zero(basedomain)*[1..l]];
- Objectify(typ,v);
- return v;
+InstallMethod( NewZeroVector, "for IsPlistVectorRep, a semiring, and an int",
+ [ IsPlistVectorRep, IsSemiring, IsInt ],
+ function( filter, basedomain, len )
+ local list;
+ list := ListWithIdenticalEntries(len, Zero(basedomain));
+ return MakeIsPlistVectorRep( basedomain, list );
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, PlainListCopy);
+ 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 +130,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;
@@ -206,42 +199,20 @@ InstallMethod( Length, "for a plist vector", [ IsPlistVectorRep ],
InstallMethod( ZeroVector, "for an integer and a plist vector",
[ IsInt, IsPlistVectorRep ],
function( l, t )
- local v;
- v := Objectify(TypeObj(t),
- [t![BDPOS],ListWithIdenticalEntries(l,Zero(t![BDPOS]))]);
- if not IsMutable(v) then SetFilterObj(v,IsMutable); fi;
- return v;
+ return NewZeroVector(IsPlistVectorRep, t![BDPOS], l);
end );
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]))]);
- if not IsMutable(v) then SetFilterObj(v,IsMutable); fi;
- return v;
- end );
-
-InstallMethod( Vector, "for a plain list and a plist vector",
- [ IsList and IsPlistRep, IsPlistVectorRep ],
- function( l, t )
- local v;
- v := Objectify(TypeObj(t),[t![BDPOS],l]);
- if not IsMutable(v) then SetFilterObj(v,IsMutable); fi;
- return v;
+ return NewZeroVector(IsPlistVectorRep, m![BDPOS], l);
end );
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;
@@ -348,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",
@@ -361,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",
@@ -456,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",
@@ -501,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;
@@ -533,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;
@@ -568,22 +511,15 @@ 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]];
- end );
-
-
############################################################################
# Representation preserving constructors:
############################################################################
@@ -591,10 +527,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;
@@ -603,48 +538,14 @@ 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] );
- 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] );
+ res := Objectify( TypeObj(m), [m![BDPOS],rows,rows,l] );
if not IsMutable(m) then
SetFilterObj(res,IsMutable);
fi;
@@ -659,82 +560,92 @@ InstallMethod( Matrix, "for a list and a plist matrix",
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];
+ [ IsRowPlistMatrixRep, IsPosInt ],
+ function( m, i )
+ Info(InfoPerformance, 1, "for best performance avoid m[i]; e.g. use m[i,j] instead of m[i][j]");
+ # TODO: should we cache these row vectors?
+ return MakeIsPlistVectorRep( m![BDPOS], m![ROWSPOS][i] );
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;
+ [ IsRowPlistMatrixRep and IsMutable, IsPosInt, IsPlistVectorRep ],
+ function( m, i, v )
+ # TODO: verify that basedomain matches and that Length(v) = NrCols(m) ?
+ m![ROWSPOS][i] := v![ELSPOS];
+ # FIXME: really just assign the content, so that from now on any change to
+ # the vector object will modify the i-th row of ??? yes, this
+ # emulates the old way of things, but it's also dangerous, and often leads to
+ # bugs; perhaps we should instead make a copy / copy over the data only?
end );
InstallMethod( \{\}, "for a plist matrix and a list",
- [ IsPlistMatrixRep, IsList ],
+ [ IsRowPlistMatrixRep, IsList ],
function( m, p )
local l;
l := m![ROWSPOS]{p};
- return Objectify(TypeObj(m),[m![BDPOS],m![EMPOS],m![RLPOS],l]);
+ return Objectify(TypeObj(m),[m![BDPOS],m![NUM_ROWS_POS],m![NUM_COLS_POS],l]);
end );
InstallMethod( Add, "for a plist matrix and a plist vector",
- [ IsPlistMatrixRep and IsMutable, IsPlistVectorRep ],
+ [ IsRowPlistMatrixRep 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 ],
+ [ IsRowPlistMatrixRep and IsMutable, IsPlistVectorRep, IsPosInt ],
function( m, v, p )
Add(m![ROWSPOS],v,p);
end );
InstallMethod( Remove, "for a plist matrix",
- [ IsPlistMatrixRep and IsMutable ],
+ [ IsRowPlistMatrixRep and IsMutable ],
m -> Remove( m![ROWSPOS] ) );
InstallMethod( Remove, "for a plist matrix, and a position",
- [ IsPlistMatrixRep and IsMutable, IsPosInt ],
+ [ IsRowPlistMatrixRep 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 ],
+ [ IsRowPlistMatrixRep, IsPosInt ],
function( m, p )
- return p <= Length(m![ROWSPOS]);
+ # TODO: move this to the generic IsRowListMatrix interface?
+ return p <= NrRows(m);
end );
InstallMethod( Unbind\[\], "for a plist matrix, and a position",
- [ IsPlistMatrixRep and IsMutable, IsPosInt ],
+ [ IsRowPlistMatrixRep and IsMutable, IsPosInt ],
function( m, p )
- if p <> Length(m![ROWSPOS]) then
+ # TODO: move this to the generic IsRowListMatrix interface?
+ if p <> NrRows(m) then
ErrorNoReturn("Unbind\\[\\]: Matrices must stay dense, you cannot Unbind here");
fi;
- Unbind( m![ROWSPOS][p] );
+ Remove(m);
end );
InstallMethod( \{\}\:\=, "for a plist matrix, a list, and a plist matrix",
- [ IsPlistMatrixRep and IsMutable, IsList,
- IsPlistMatrixRep ],
+ [ IsRowPlistMatrixRep and IsMutable, IsList,
+ IsRowPlistMatrixRep ],
function( m, pp, n )
+ # TODO: verify that basedomain matches and that Length(v) = NrCols(m) ?
m![ROWSPOS]{pp} := n![ROWSPOS];
end );
InstallMethod( Append, "for two plist matrices",
- [ IsPlistMatrixRep and IsMutable, IsPlistMatrixRep ],
+ [ IsRowPlistMatrixRep and IsMutable, IsRowPlistMatrixRep ],
function( m, n )
Append(m![ROWSPOS],n![ROWSPOS]);
end );
InstallMethod( ShallowCopy, "for a plist matrix",
- [ IsPlistMatrixRep ],
+ [ IsRowPlistMatrixRep ],
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);
@@ -750,30 +661,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;
@@ -784,11 +677,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",
@@ -796,11 +686,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 );
@@ -821,13 +711,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 );
@@ -839,16 +729,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 );
@@ -858,29 +750,25 @@ 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
- if i = 1 then
- Print("[");
- else
- Print(" ");
- fi;
- Print(m![ROWSPOS][i]![ELSPOS],"\n");
+ Print(NrRows(m),"x",NrCols(m),"-matrix over ",m![BDPOS],": [\n");
+ for i in [1..NrRows(m)] do
+ 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)));
@@ -898,13 +786,19 @@ 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])]);
+ # TODO: 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?
+ # TODO: should we check and enforce the the basedomains are identical?
+ return Objectify(ty,[a![BDPOS],a![NUM_ROWS_POS],a![NUM_COLS_POS],
+ a![ROWSPOS]+b![ROWSPOS]]);
end );
InstallMethod( \-, "for two plist matrices",
@@ -916,8 +810,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",
@@ -930,103 +824,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;
@@ -1036,132 +876,41 @@ 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;
- 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);
- 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;
+ 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);
- if not IsMutable(m) then
- MakeImmutable(n);
- fi;
- return n;
+ # FIXME: if the base domain is not a field, e.g. Integers,
+ # then the inverse we just computed may not be defined over
+ # that base domain. Should we detect this here? Or how else
+ # will we deal with this in general?
+ return NewMatrix(IsPlistMatrixRep, BaseDomain(m), NrCols(m), n);
end );
InstallMethod( RankMat, "for a plist matrix",
@@ -1188,19 +937,23 @@ 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, res;
+ # FIXME/TODO: implement this generic, or optimized for IsPlistMatrixRep?
+ # Right now, we do the latter:
+ trans := TransposedMatMutable(m![ROWSPOS]);
+
+ res := Objectify(TypeObj(m),[m![BDPOS],NrCols(m),NrRows(m),trans]);
+ if not IsMutable(m) then
+ SetFilterObj(res,IsMutable);
+ fi;
+ return res;
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;
@@ -1210,36 +963,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 ],
@@ -1253,24 +987,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",
@@ -1284,13 +1016,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/lib/matrix.gi b/lib/matrix.gi
index f6f70c8c3a..44b485a121 100644
--- a/lib/matrix.gi
+++ b/lib/matrix.gi
@@ -1282,7 +1282,7 @@ InstallOtherMethod( ConstructingFilter,
InstallOtherMethod( BaseDomain,
"generic method for a matrix that is a plain list",
[ IsMatrix and IsPlistRep ],
- mat -> BaseDomain( mat[1] ) );
+ mat -> BaseDomain( Concatenation( mat ) ) );
InstallOtherMethod( OneOfBaseDomain,
"generic method for a matrix that is a plain list",
diff --git a/tst/testinstall/MatrixObj/Matrix.tst b/tst/testinstall/MatrixObj/Matrix.tst
index dcf299f0e8..eb473847c1 100644
--- a/tst/testinstall/MatrixObj/Matrix.tst
+++ b/tst/testinstall/MatrixObj/Matrix.tst
@@ -4,8 +4,8 @@ gap> START_TEST("Matrix.tst");
gap> m := Matrix( [[1,2],[3,4]] );
<2x2-matrix over Rationals>
gap> Display(m);
-<2x2-matrix over Rationals:
-[[ 1, 2 ]
+<2x2-matrix over Rationals: [
+ [ 1, 2 ]
[ 3, 4 ]
]>
@@ -34,8 +34,8 @@ gap> Display(m);
gap> m := Matrix( IsPlistMatrixRep, GF(2), [[1,2],[3,4]] * Z(2) );
<2x2-matrix over GF(2)>
gap> Display(m);
-<2x2-matrix over GF(2):
-[[ Z(2)^0, 0*Z(2) ]
+<2x2-matrix over GF(2): [
+ [ Z(2)^0, 0*Z(2) ]
[ Z(2)^0, 0*Z(2) ]
]>
diff --git a/tst/testinstall/MatrixObj/NewMatrix.tst b/tst/testinstall/MatrixObj/NewMatrix.tst
new file mode 100644
index 0000000000..96bc83fb57
--- /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
diff --git a/tst/testinstall/matrix.tst b/tst/testinstall/matrix.tst
index 23fca73b26..8aad0f343c 100644
--- a/tst/testinstall/matrix.tst
+++ b/tst/testinstall/matrix.tst
@@ -89,9 +89,9 @@ gap> IsLowerTriangularMat([[1,0],[1,1],[1,1]]);
true
#
-gap> m := Z(5)^0 * [[0, 1], [1, 0]];;
+gap> m := Z(5)^0 * [[0, 1], [Z(25), 0]];;
gap> m := GeneratorsWithMemory([m])[1];;
-gap> BaseDomain(m) = GF(5);
+gap> BaseDomain(m) = GF(25);
true
gap> NrRows(m);
2