From 3e2c0765495859cac87ac7fd54c5cd91d998a76e Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 23 Feb 2022 10:56:29 -0700 Subject: [PATCH 1/4] ENHANCE: ImmutableVector/Matrix use matobjs. if given over large Integers mod n. Subsequent changes in groups code and meataxe to ensure code works. (Added methods for GeneralisedEigenvalues, TriangulizeMat, Check in Echelonization, better field determination in DirectSumMat) --- lib/grpmat.gi | 75 +++++++++++++++++++++++++++++++++++++++ lib/matrix.gd | 4 +-- lib/matrix.gi | 65 +++++++++++++++++++++++++++------- lib/meataxe.gi | 95 ++++++++++++++++++++++++++++++-------------------- lib/vecmat.gi | 69 +++++++++++++++++++++++++++++++----- lib/vspcrow.gi | 3 ++ 6 files changed, 250 insertions(+), 61 deletions(-) diff --git a/lib/grpmat.gi b/lib/grpmat.gi index f876e65a1c..49d77c4c14 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -972,6 +972,81 @@ local G,fam,typ,f; return G; end ); +# ditto for nonprime ZmodnZ +InstallMethod( GroupWithGenerators, "list of zmodnz matrices", + [ IsZmodnZObjNonprimeCollCollColl ], +#T ??? +function( gens ) +local G,typ,f; + + if not IsFinite(gens) then TryNextMethod(); fi; + typ:=MakeGroupyType(FamilyObj(gens), + IsGroup and IsAttributeStoringRep + and HasGeneratorsOfMagmaWithInverses + and IsFinitelyGeneratedGroup and HasIsEmpty and IsFinite, + gens,false,true); + + f:=DefaultScalarDomainOfMatrixList(gens); + gens:=List(Immutable(gens),i->ImmutableMatrix(f,i)); + + G:=rec(); + ObjectifyWithAttributes(G,typ,GeneratorsOfMagmaWithInverses,AsList(gens)); + + if IsField(f) then SetDefaultFieldOfMatrixGroup(G,f);fi; + + return G; +end ); + +InstallMethod( GroupWithGenerators, + "list of zmodnz matrices with identity", IsCollsElms, + [ IsZmodnZObjNonprimeCollCollColl,IsMultiplicativeElementWithInverse and + IsZmodnZObjNonprimeCollColl], +function( gens, id ) +local G,typ,f; + + if not IsFinite(gens) then TryNextMethod(); fi; + typ:=MakeGroupyType(FamilyObj(gens), IsGroup and IsAttributeStoringRep + and HasGeneratorsOfMagmaWithInverses and IsFinitelyGeneratedGroup + and HasIsEmpty and IsFinite and HasOne, + gens,id,true); + + f:=DefaultScalarDomainOfMatrixList(gens); + gens:=List(Immutable(gens),i->ImmutableMatrix(f,i)); + id:=ImmutableMatrix(f,id); + + G:=rec(); + ObjectifyWithAttributes(G,typ,GeneratorsOfMagmaWithInverses,AsList(gens), + One,id); + + if IsField(f) then SetDefaultFieldOfMatrixGroup(G,f);fi; + + return G; +end ); + +InstallMethod( GroupWithGenerators, + "empty list of zmodnz matrices with identity", true, + [ IsList and IsEmpty, + IsMultiplicativeElementWithInverse and IsZmodnZObjNonprimeCollColl], +function( gens, id ) +local G,fam,typ,f; + + if not IsFinite(gens) then TryNextMethod(); fi; + typ:=MakeGroupyType(FamilyObj([id]), IsGroup and IsAttributeStoringRep + and HasGeneratorsOfMagmaWithInverses and HasOne and IsTrivial, + gens,id,true); + + f:=DefaultScalarDomainOfMatrixList([id]); + id:=ImmutableMatrix(f,id); + + G:=rec(); + ObjectifyWithAttributes(G,typ,GeneratorsOfMagmaWithInverses,AsList(gens), + One,id); + + if IsField(f) then SetDefaultFieldOfMatrixGroup(G,f);fi; + + return G; +end ); + ############################################################################# ## diff --git a/lib/matrix.gd b/lib/matrix.gd index ff8051a2b3..e5114bea05 100644 --- a/lib/matrix.gd +++ b/lib/matrix.gd @@ -625,7 +625,7 @@ DeclareOperation( "TriangulizedNullspaceMatDestructive", [ IsMatrix and IsMutabl ## ## <#/GAPDoc> ## -DeclareOperation( "GeneralisedEigenvalues", [ IsRing, IsMatrix ] ); +DeclareOperation( "GeneralisedEigenvalues", [ IsRing, IsMatrixOrMatrixObj ] ); DeclareSynonym( "GeneralizedEigenvalues", GeneralisedEigenvalues ); ############################################################################# @@ -644,7 +644,7 @@ DeclareSynonym( "GeneralizedEigenvalues", GeneralisedEigenvalues ); ## ## <#/GAPDoc> ## -DeclareOperation( "GeneralisedEigenspaces", [ IsRing, IsMatrix ] ); +DeclareOperation( "GeneralisedEigenspaces", [ IsRing, IsMatrixOrMatrixObj ] ); DeclareSynonym( "GeneralizedEigenspaces", GeneralisedEigenspaces ); diff --git a/lib/matrix.gi b/lib/matrix.gi index 4aef74f6e0..87b20a7744 100644 --- a/lib/matrix.gi +++ b/lib/matrix.gi @@ -2174,14 +2174,14 @@ InstallMethod( NullspaceMatDestructive, [ IsOrdinaryMatrix and IsMutable], mat -> SemiEchelonMatTransformationDestructive(mat).relations ); -InstallMethod( TriangulizedNullspaceMat, - "generic method for ordinary matrices", - [ IsOrdinaryMatrix ], +InstallOtherMethod( TriangulizedNullspaceMat, + "generic method for matrices", + [ IsMatrixOrMatrixObj ], mat -> TriangulizedNullspaceMatDestructive( MutableCopyMatrix( mat ) ) ); -InstallMethod( TriangulizedNullspaceMatDestructive, - "generic method for ordinary matrices", - [ IsOrdinaryMatrix and IsMutable], +InstallOtherMethod( TriangulizedNullspaceMatDestructive, + "generic method for matrices", + [ IsMatrixOrMatrixObj and IsMutable], function( mat ) local ns; ns := SemiEchelonMatTransformationDestructive(mat).relations; @@ -2258,8 +2258,8 @@ end ); #M GeneralisedEigenvalues( , ) ## InstallMethod( GeneralisedEigenvalues, - "for a matrix", - [ IsField, IsMatrix ], + "for a matrix or matrix obj", + [ IsField, IsMatrixOrMatrixObj ], function( F, A ) return Set( Factors( UnivariatePolynomialRing(F), MinimalPolynomial(F, A,1) ) ); end ); @@ -2269,8 +2269,8 @@ InstallMethod( GeneralisedEigenvalues, #M GeneralisedEigenspaces( , ) ## InstallMethod( GeneralisedEigenspaces, - "for a matrix", - [ IsField, IsMatrix ], + "for a matrix or matrix obj", + [ IsField, IsMatrixOrMatrixObj ], function( F, A ) return List( GeneralisedEigenvalues( F, A ), eval -> VectorSpace( F, TriangulizedNullspaceMat( Value( eval, A ) ) ) ); @@ -2488,6 +2488,9 @@ BindGlobal("DoSemiEchelonMatTransformationDestructive", function(f, mat ) vectors := []; T := IdentityMat( nrows, f ); + if IsMatrixObj(mat) then + T:=Matrix(f,T); + fi; coeffs := []; relations := []; @@ -3261,6 +3264,17 @@ local m; return m; end); +InstallOtherMethod( TriangulizedMat,"list of vectore", [IsList], +function ( mat ) +local m; + m:=MutableCopyMatrix(mat); + TriangulizeMat(m); + return m; +end); + + + + InstallOtherMethod( TriangulizedMat, "for an empty list", [ IsList and IsEmpty ], mat -> []); @@ -4043,15 +4057,40 @@ InstallGlobalFunction( DirectSumMat, function (arg) m:= arg[r]; r:=r+1; od; if m <> [ ] then - F:= DefaultField( m[1,1] ); + r:=[]; + for c in arg do + if HasBaseDomain(c) then + Add(r,BaseDomain(c)); + else + Add(r,DefaultFieldOfMatrix(c)); + fi; + od; + F:=r[1]; + for c in r{[2..Length(r)]} do + if not IsSubset(F,c) then + if IsSubset(c,F) then + F:=c; + else + Error("build field/ring"); + fi; + fi; + od; + else F:= Rationals; fi; - res:=List(NullMat(Sum(arg,Length),Sum(arg,f),F),ShallowCopy); + res:=[Sum(arg,Length),Sum(arg,f)]; + if ForAny(arg,IsMatrixObj) then + res:=ZeroMatrix(F,res[1],res[2]); + else + res:=List(NullMat(res[1],res[2],F),ShallowCopy); + fi; r:=0; c:=0; for m in arg do - res{r+[1..Length(m)]}{c+[1..f(m)]}:=m; + #res{r+[1..Length(m)]}{c+[1..f(m)]}:=m; + CopySubMatrix(m,res,[1..NrRows(m)],r+[1..Length(m)], + [1..NrCols(m)], c+[1..f(m)]); r:=r+Length(m); c:=c+f(m); od; diff --git a/lib/meataxe.gi b/lib/meataxe.gi index 5248325b81..7fabdcf154 100644 --- a/lib/meataxe.gi +++ b/lib/meataxe.gi @@ -381,21 +381,36 @@ SMTX_SpinnedBasis:=function( arg ) ngens:=Length(matrices); fi; ans:=[]; - if Length(v)=0 then - return []; - fi; - if not IsList(v[1]) then - v:=[v]; - fi; zero:=Zero(matrices[1][1][1]); - ans:=ShallowCopy(Basis(VectorSpace(F,v))); - if Length(ans)=0 then - return ans; + if IsList(v) and Length(v)=0 then + return []; + elif IsMatrix(v) then + TriangulizeMat(v); + ans:=Filtered(v,x->not IsZero(x)); + elif IsList(v) and IsVectorObj(v[1]) then + v:=TriangulizedMat(Matrix(F,v)); + ans:=Filtered(List(v),x->not IsZero(x)); + else + # single vector (as vector or list) + ans:=[v]; fi; + + + #ans:=ShallowCopy(Basis(VectorSpace(F,v))); + + ans:=Filtered(ans,x->not IsZero(x)); + if Length(ans)=0 then return ans; fi; ans:=List(ans, v -> ImmutableVector(F,v)); dim:=Length(ans[1]); subdim:=Length(ans); leadpos:=SubGModLeadPos(ans,dim,subdim,zero); + for i in [1..Length(ans)] do + w:=ans[i]; + j:=w[PositionNonZero(w)]; + if not IsOne(j) then + ans[i]:=j^-1*ans[i]; + fi; + od; i:=1; while i <= subdim do @@ -508,8 +523,8 @@ local s, c, q, leadpos, zero, zerov, smatrices, newg, im, newim, k, subi, # merit a basechange # first extend the basis - sub:=ShallowCopy(sub); - Append(sub,One(matrices[1]){Difference([1..dim],leadpos)}); + sub:=List(sub); + Append(sub,List(One(matrices[1])){Difference([1..dim],leadpos)}); sub:=ImmutableMatrix(F,sub); subi:=sub^-1; qmats:=[]; @@ -519,12 +534,12 @@ local s, c, q, leadpos, zero, zerov, smatrices, newg, im, newim, k, subi, for g in matrices do g:=sub*g*subi; if s then - h:=g{sr}{sr}; + h:=ExtractSubMatrix(g,sr,sr); h:=ImmutableMatrix(F,h); Add(smats,h); fi; if q then - h:=g{qr}{qr}; + h:=ExtractSubMatrix(g,qr,qr); h:=ImmutableMatrix(F,h); Add(qmats,h); fi; @@ -909,7 +924,7 @@ local g1,g2,coefflist,M,pol; fi; Add(coefflist, g2); od; - Info(InfoMeatAxe,2,"Evaluated random element in algebra."); + Info(InfoMeatAxe,3,"Evaluated random element in algebra."); pol:=CharacteristicPolynomialMatrixNC(F,M,1); return [M,coefflist,pol]; end; @@ -1031,7 +1046,7 @@ SMTX_IrreducibilityTest:=function( module ) # To choose random element, first add on a new generator as a product of # two randomly chosen unequal existing generators # Record the product in newgenlist. - Info(InfoMeatAxe,1,"Choosing random element number ",count); + Info(InfoMeatAxe,3,"Choosing random element number ",count); M:=SMTX.SMCoRaEl(matrices,ngens,newgenlist,dim,F); @@ -1043,7 +1058,7 @@ SMTX_IrreducibilityTest:=function( module ) idmat:=M^0; orig_pol:=pol; - Info(InfoMeatAxe,2,"Evaluated characteristic polynomial. Time = ", + Info(InfoMeatAxe,3,"Evaluated characteristic polynomial. Time = ", Runtime()-rt0,"."); # Now we extract the irreducible factors of pol starting with those # of low degree @@ -1058,7 +1073,7 @@ SMTX_IrreducibilityTest:=function( module ) else fac:=Factors(R, pol: factoroptions:=rec(onlydegs:=[deg])); fac:=Filtered(fac,i->DegreeOfLaurentPolynomial(i)=deg); - Info(InfoMeatAxe,2,Length(fac)," factors of degree ",deg, + Info(InfoMeatAxe,3,Length(fac)," factors of degree ",deg, ", Time = ",Runtime()-rt0,"."); fi; until fac <> [] or deg = maxdeg; @@ -1374,7 +1389,7 @@ local matrices, ngens, M, mat, N, newgenlist, coefflist, orig_ngens, " random elements and failed ", "to find a good one. Type return to keep trying."); fi; - Info(InfoMeatAxe,2,"Choosing random element number ",count,"."); + Info(InfoMeatAxe,3,"Choosing random element number ",count,"."); M:=SMTX.SMCoRaEl(matrices,ngens,newgenlist,dim,F); ngens:=Length(matrices); @@ -1384,7 +1399,7 @@ local matrices, ngens, M, mat, N, newgenlist, coefflist, orig_ngens, M:=M[1]; idmat:=M^0; - Info(InfoMeatAxe,2,"Evaluated characteristic polynomial. Time = ", + Info(InfoMeatAxe,3,"Evaluated characteristic polynomial. Time = ", Runtime()-rt0,"."); # That is necessary in case p is defined over a smaller field that F. oldpol:=pol; @@ -1400,7 +1415,7 @@ local matrices, ngens, M, mat, N, newgenlist, coefflist, orig_ngens, else fac:=Factors(R, pol: factoroptions:=rec(onlydegs:=[deg])); fac:=Filtered(fac,i->DegreeOfLaurentPolynomial(i)<=deg); - Info(InfoMeatAxe,2,Length(fac)," factors of degree ",deg, + Info(InfoMeatAxe,3,Length(fac)," factors of degree ",deg, ", Time = ",Runtime()-rt0,"."); sfac:=Set(fac); fi; @@ -1459,24 +1474,25 @@ SMTX.GoodElementGModule:=SMTX_GoodElementGModule; ## SMTX_FrobeniusAction:=function( arg ) local L, d, p, M, one, zero, R, h, v, w, i, j, nd, ans, - A, basis; + A, basis,fld; - if Length(arg) = 2 then - A:=arg[1]; - v:=arg[2]; + fld:=arg[1]; + A:=arg[2]; + v:=arg[3]; + if Length(arg) = 3 then basis:=0; - elif Length(arg) = 3 then - A:=arg[1]; - v:=arg[2]; - basis:=arg[3]; + elif Length(arg) = 4 then + basis:=arg[4]; else - return Error("usage: SMTX.FrobeniusAction( , , [, ] )"); + return Error("usage: SMTX.FrobeniusAction(, , , [, ] )"); fi; one :=One(A[1][1]); zero:=Zero(one); d:=Length( A ); M:=ListWithIdenticalEntries(Length(A[1]) + 1,zero); - ConvertToVectorRep(M,DefaultField(v)); + M:=ImmutableVector(fld,M); + v:=ImmutableVector(fld,v); + A:=ImmutableMatrix(fld,A); # L[i] (length d) will contain a vector with head entry 1 at position i, # which is in the current block. @@ -1515,6 +1531,7 @@ local L, d, p, M, one, zero, R, h, v, w, i, j, nd, ans, if h <= d then #AH replaced Copy by ShallowCopy as only vector is used if basis <> 0 then basis[j]:=ShallowCopy(v); fi; + R[h]:=p * w[h]^-1; L[h]:=w * w[h]^-1; j:=j + 1; @@ -1708,7 +1725,7 @@ local dim, ndim, gcd, div, e, ct, F, q, ok, basisN:=[]; Info(InfoMeatAxe,2, "Calc. Frobenius action of element from group algebra on nullspace."); - M0:=SMTX.FrobeniusAction(M,v,basisN); + M0:=SMTX.FrobeniusAction(F,M,v,basisN); zero:=Zero(F); one:= One(F); @@ -1757,15 +1774,18 @@ local dim, ndim, gcd, div, e, ct, F, q, ok, # A matrix product gives us the basis for B in terms of the # original basis for the module. basisBN:=[]; - C0:=SMTX.FrobeniusAction(C^pow,v0,basisBN); + C0:=SMTX.FrobeniusAction(F,C^pow,v0,basisBN); C:=[]; until Length(C0) = e; Info(InfoMeatAxe,2,"Found one."); - basisB:=ShallowCopy(basisBN * basisN); + basisB:=List( + ImmutableMatrix(F,basisBN) * + ImmutableMatrix(F,basisN)); else C0:=M0; basisB:=ShallowCopy(basisN); fi; + C0:=ImmutableMatrix(F,C0); # Now try to extend basisB to a basis for the whole module, by # translating it by the generating matrices. Info(InfoMeatAxe,2,"Trying to extend basis to whole module."); @@ -1807,7 +1827,7 @@ local dim, ndim, gcd, div, e, ct, F, q, ok, SMTX.SetCentMat(module, Pinv * centmat * P); # get the base right # We will also record the minimal polynomial of C0 (and hence of # centmat) in case we need it at some future date. - SMTX.SetCentMatMinPoly(module, MinimalPolynomialMatrixNC(F,C0,1)); + SMTX.SetCentMatMinPoly(module, MinimalPolynomial(F,C0,1)); return false; fi; Info(InfoMeatAxe,2,"But it didn't."); @@ -1986,7 +2006,7 @@ SMTX_CollectedFactors:= function( module ) # build the submodule formed by their images mat:=Concatenation(homs); TriangulizeMat(mat); - mat:=Filtered(mat,i->not IsZero(i)); + mat:=Filtered(List(mat),i->not IsZero(i)); mat:=ImmutableMatrix(field,mat); if Length(mat) mat[j] * gens2[i] then - Print(i,j,"\n"); Error("matrix does not define a homomorphism"); fi; od; @@ -3422,7 +3443,7 @@ SMTX_InvariantQuadraticForm:=function( module ) # Matrix must be symplectic - perhaps it must be? for i in [1..dim] do if ciso[i][i] <> z then - Print("Non-symplectic failure!\n"); + #Print("Non-symplectic failure!\n"); return fail; fi; od; diff --git a/lib/vecmat.gi b/lib/vecmat.gi index 9585cb6ce9..cb0c684624 100644 --- a/lib/vecmat.gi +++ b/lib/vecmat.gi @@ -1560,8 +1560,14 @@ end); #F ImmutableMatrix( , [,] ) ## BindGlobal("DoImmutableMatrix", function(field,matrix,change) -local sf, rep, ind, ind2, row, i,big,l; - if not (IsPlistRep(matrix) or IsGF2MatrixRep(matrix) or +local sf, rep, ind, ind2, row, i,big,l,nr; + if IsMatrixObj(matrix) then + if field=BaseDomain(matrix) then + return Immutable(matrix); + else + return ImmutableMatrix(field,Unpack(matrix)); + fi; + elif not (IsPlistRep(matrix) or IsGF2MatrixRep(matrix) or Is8BitMatrixRep(matrix)) then # if empty or not list based, simply return `Immutable'. return Immutable(matrix); @@ -1570,6 +1576,9 @@ local sf, rep, ind, ind2, row, i,big,l; sf:=field; elif IsField(field) then sf:=Size(field); + elif IsZmodnZObjNonprimeCollection(field) then + # slight abuse of ``field'' variable name + sf:=Size(field); else # not a field return Immutable(matrix); @@ -1586,10 +1595,16 @@ local sf, rep, ind, ind2, row, i,big,l; rep:=IsPlistRep; fi; + if IsPlistRep(matrix) and not ForAll(matrix,IsPlistRep) then + nr:=Length(matrix); + else + nr:=NrRows(matrix); + fi; + # get the indices of the rows that need changing the representation. ind:=[]; # rows to convert ind2:=[]; # rows to rebuild - for i in [1..NrRows(matrix)] do + for i in [1..nr] do if not rep(matrix[i]) then if big or IsLockedRepresentationVector(matrix[i]) or (IsMutable(matrix[i]) and not change) then @@ -1619,10 +1634,20 @@ local sf, rep, ind, ind2, row, i,big,l; fi; # rebuild some rows - if big then - for i in ind2 do - matrix[i]:=List(matrix[i],j->j); # plist conversion - od; + if IsZmodnZObjNonprimeCollection(field) then + matrix:=Matrix(field,matrix); + big:=true; + elif big then + if sf<>infinity and IsPrimeInt(sf) and sf>MAXSIZE_GF_INTERNAL then + if not (IsMatrixObj(matrix) and not IsMutable(matrix)) then + if field=sf then field:=Integers mod sf;fi; + matrix:=Matrix(field,matrix); + fi; + else + for i in ind2 do + matrix[i]:=List(matrix[i],j->j); # plist conversion + od; + fi; else for i in ind2 do row := ShallowCopy(matrix[i]); @@ -1643,12 +1668,20 @@ local sf, rep, ind, ind2, row, i,big,l; return matrix; end); -InstallMethod( ImmutableMatrix,"general,2",[IsObject,IsMatrix],0, +InstallOtherMethod( ImmutableMatrix,"general,2", +[IsObject,IsMatrixOrMatrixObj],0, function(f,m) return DoImmutableMatrix(f,m,false); end); -InstallOtherMethod( ImmutableMatrix,"general,3",[IsObject,IsMatrix,IsBool],0, +InstallOtherMethod( ImmutableMatrix,"List of vectors", +[IsObject,IsList],0, +function(f,m) + if not ForAll(m,x->IsList(x) or IsVector(x)) then TryNextMethod();fi; + return DoImmutableMatrix(f,m,false); +end); + +InstallOtherMethod(ImmutableMatrix,"general,3",[IsObject,IsMatrixOrMatrixObj,IsBool],0, DoImmutableMatrix); InstallOtherMethod( ImmutableMatrix,"field,8bit",[IsField,Is8BitMatrixRep],0, @@ -1703,10 +1736,28 @@ end); ## InstallMethod( ImmutableVector,"general,2",[IsObject,IsRowVector],0, function(f,v) +local sf; + if (IsInt(f) and f>MAXSIZE_GF_INTERNAL) or + (IsField(f) and Size(f)>MAXSIZE_GF_INTERNAL) then + if IsInt(f) then + sf:=f; + else + sf:=Size(f); + fi; + if sf<>infinity and IsPrimeInt(sf) then + if f=sf then f:=Integers mod sf;fi; + return Immutable(Vector(f,v)); + fi; + fi; ConvertToVectorRepNC(v,f); return Immutable(v); end); +InstallOtherMethod( ImmutableVector,"vectorObj,2",[IsObject,IsVectorObj],0, +function(f,v) + return Immutable(v); +end); + InstallOtherMethod( ImmutableVector,"general,3",[IsObject,IsRowVector,IsBool],0, function(f,v,change) ConvertToVectorRepNC(v,f); diff --git a/lib/vspcrow.gi b/lib/vspcrow.gi index c60f074358..38868c5956 100644 --- a/lib/vspcrow.gi +++ b/lib/vspcrow.gi @@ -1066,6 +1066,9 @@ InstallMethod( CanonicalBasis, # Make a copy to avoid changing the original argument. B:= List( GeneratorsOfLeftModule( V ), ShallowCopy ); + if ForAny(B,IsVectorObj) then + B:=List(B,Unpack); + fi; m:= Length( B ); n:= Length( B[1] ); From ce52f029b53799bf3334789cfc9ab360f6dadefb Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 2 Mar 2022 16:47:48 -0700 Subject: [PATCH 2/4] Improved interaction with zmodnz vectors/mats improved binary ops, if one partner is list. Improved view if small. Methiods for `DefaultScalarDomainOfMatrixList`, Hash key, Determinant. Do not use vectorObj for polynomial coeffients --- lib/dicthf.gi | 21 ++++++--- lib/grpffmat.gi | 19 ++++++-- lib/grpmat.gi | 7 +++ lib/matobjnz.gi | 114 +++++++++++++++++++++++++++++++++++++++++++----- lib/overload.g | 2 +- lib/polyfinf.gi | 6 ++- lib/ratfun1.gi | 8 +++- 7 files changed, 153 insertions(+), 24 deletions(-) diff --git a/lib/dicthf.gi b/lib/dicthf.gi index 77f5de7bcb..d35cc50c85 100644 --- a/lib/dicthf.gi +++ b/lib/dicthf.gi @@ -110,14 +110,21 @@ local f,n,bytelen,data,qq,i; return function(v) local x,sy,p; sy := 0; - for x in v do - p := Position(f, x); + if IsZmodnZVectorRep(v) then + for x in v![ELSPOS] do + sy := n*sy + (x-1); + od; + else + for x in v do + p := Position(f, x); # want to be quick: Assume no failures -# if p = fail then -# Error("NumberFFVector: Vector not over specified field"); -# fi; - sy := n*sy + (p-1); - od; +# if p = fail then +# Error("NumberFFVector: Vector not over specified field"); +# fi; + sy := n*sy + (p-1); + od; + fi; + return sy; end; fi; diff --git a/lib/grpffmat.gi b/lib/grpffmat.gi index 3e308c21a5..7f72d525fe 100644 --- a/lib/grpffmat.gi +++ b/lib/grpffmat.gi @@ -39,8 +39,14 @@ end ); InstallMethod(FieldOfMatrixList,"finite field matrices",true, [IsListOrCollection and IsFFECollCollColl],0, function(l) -local deg, i, j, char; +local deg, i, j, char,B; if Length(l)=0 then Error("list must be nonempty");fi; + if ForAll( l, HasBaseDomain ) then + B:= BaseDomain( l[1] ); + if ForAll( l, x -> B = BaseDomain( x ) ) then + return B; + fi; + fi; deg := 1; for i in l do for j in i do @@ -58,8 +64,15 @@ end); InstallMethod(DefaultScalarDomainOfMatrixList,"finite field matrices",true, [IsListOrCollection and IsFFECollCollColl],0, function(l) -local deg, i, j, char,m; -if Length(l)=0 then Error("list must be nonempty");fi; +local deg, i, j, char,m,B; + if Length(l)=0 then Error("list must be nonempty");fi; + if ForAll( l, HasBaseDomain ) then + B:= BaseDomain( l[1] ); + if ForAll( l, x -> B = BaseDomain( x ) ) then + return B; + fi; + fi; + deg := 1; for i in l do # treat compact matrices quickly diff --git a/lib/grpmat.gi b/lib/grpmat.gi index 49d77c4c14..c586dd1058 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -240,6 +240,7 @@ local field, dict, acts, start, j, zerov, zero, dim, base, partbas, heads, else Error("illegal action"); fi; + start:=List(start,x->ImmutableVector(field,x)); zerov:=Zero(start[1]); zero:=zerov[1]; @@ -355,7 +356,13 @@ local field, dict, acts, start, j, zerov, zero, dim, base, partbas, heads, if v<>zerov then Add(base,orb[i]); Add(partbas,ShallowCopy(orb[i])); + if ForAny(partbas,IsVectorObj) then + partbas:=Matrix(BaseDomain(partbas[1]),partbas); + fi; TriangulizeMat(partbas); + if IsMatrixObj(partbas) then + partbas:=ShallowCopy(RowsOfMatrix(partbas)); + fi; heads:=List(partbas,PositionNonZero); if Length(partbas)>=dim then # full dimension reached diff --git a/lib/matobjnz.gi b/lib/matobjnz.gi index 227154fe8a..3224e01c32 100644 --- a/lib/matobjnz.gi +++ b/lib/matobjnz.gi @@ -69,13 +69,20 @@ InstallMethod( NewZeroVector, "for IsZmodnZVectorRep, a ring, and an int", end ); InstallMethod( ViewObj, "for a zmodnz vector", [ IsZmodnZVectorRep ], - function( v ) +function( v ) +local l; if not IsMutable(v) then Print(""); + Print("vector mod ",Size(v![BDPOS])); + l:=Length(v![ELSPOS]); + if 0"); + else + Print(" of length ",Length(v![ELSPOS]),">"); + fi; end ); InstallMethod( PrintObj, "for a zmodnz vector", [ IsZmodnZVectorRep ], @@ -395,6 +402,25 @@ local i,m; fi; end ); +InstallOtherMethod( AddRowVector, "for plist, zmodnz vector, and a scalar", + [ IsPlistRep and IsMutable, IsZmodnZVectorRep, IsObject ], +function( a, b, s ) +local i,m; + if not ForAll(a,IsModulusRep) then TryNextMethod();fi; + for i in [1..Length(a)] do + a[i]:=a[i]+b[i]*s; + od; +end); + +InstallOtherMethod( AddRowVector, "for plist, plist vector, and a scalar", + [ IsPlistRep and IsMutable, IsPlistVectorRep, IsObject ], +function( a, b, s ) +local i,m; + for i in [1..Length(a)] do + a[i]:=a[i]+b[i]*s; + od; +end); + InstallMethod( AddRowVector, "for two zmodnz vectors, a scalar, and two positions", [ IsZmodnZVectorRep and IsMutable, IsZmodnZVectorRep, @@ -731,9 +757,16 @@ InstallMethod( Matrix, "for a list and a zmodnz matrix", InstallMethod( ViewObj, "for a zmodnz matrix", [ IsZmodnZMatrixRep ], function( m ) + local l; Print("<"); if not IsMutable(m) then Print("immutable "); fi; - Print(Length(m![ROWSPOS]),"x",m![RLPOS],"-matrix over ",m![BDPOS],">"); + l:=[Length(m![ROWSPOS]),m![RLPOS]]; + if Product(l)<=9 and Product(l)<>0 then + Print("matrix mod ",Size(m![BDPOS]),": ", + List(m![ROWSPOS],x->x![ELSPOS]),">"); + else + Print(l[1],"x",l[2],"-matrix mod ",Size(m![BDPOS]),">"); + fi; end ); InstallMethod( PrintObj, "for a zmodnz matrix", [ IsZmodnZMatrixRep ], @@ -1046,12 +1079,32 @@ InstallMethod( \*, "for two zmodnz matrices",IsIdenticalObj, return Objectify( ty, [a![BDPOS],a![EMPOS],b![RLPOS],l] ); end ); +InstallMethod(\*,"for zmodnz matrix and ordinary matrix",IsIdenticalObj, + [IsZmodnZMatrixRep,IsMatrix], +function(a,b) + return Matrix(BaseDomain(a),List(RowsOfMatrix(a),x->x*b)); +end); + + InstallMethod( \=, "for two zmodnz matrices",IsIdenticalObj, [ IsZmodnZMatrixRep, IsZmodnZMatrixRep ], function( a, b ) return EQ_LIST_LIST_DEFAULT(a![ROWSPOS],b![ROWSPOS]); end ); +InstallMethod( \=, "for zmodnz matrix and matrix",IsIdenticalObj, + [ IsZmodnZMatrixRep, IsMatrix ], + function( a, b ) + return Unpack(a)=b; + end ); + +InstallMethod( \=, "for matrix and zmodnz matrix",IsIdenticalObj, + [ IsMatrix, IsZmodnZMatrixRep ], + function( a, b ) + return a=Unpack(b); + end ); + + InstallMethod( \<, "for two zmodnz matrices",IsIdenticalObj, [ IsZmodnZMatrixRep, IsZmodnZMatrixRep ], function( a, b ) @@ -1302,9 +1355,7 @@ InstallMethod( TransposedMatImmutable, "for a zmodnz matrix", return n; end ); -InstallMethod( \*, "for a zmodnz vector and a zmodnz matrix", - IsElmsColls, [ IsZmodnZVectorRep, IsZmodnZMatrixRep ], - function( v, m ) +ZMZVECMAT:=function( v, m ) local i,res,s,r; r:=BaseDomain(v); # do arithmetic over Z first so that we reduce only once @@ -1325,11 +1376,17 @@ InstallMethod( \*, "for a zmodnz vector and a zmodnz matrix", MakeImmutable(res); fi; return res; - end ); + end; -InstallOtherMethod( \*, "for a plist vector and a zmodnz matrix", - IsElmsColls, [ IsList, IsZmodnZMatrixRep ], - function( v, m ) +InstallMethod( \*, "for a zmodnz vector and a zmodnz matrix", + IsElmsColls, [ IsZmodnZVectorRep, IsZmodnZMatrixRep ], + ZMZVECMAT); + +InstallOtherMethod( \^, "for a zmodnz vector and a zmodnz matrix", + IsElmsColls, [ IsZmodnZVectorRep, IsZmodnZMatrixRep ], + ZMZVECMAT); + +PLISTVECZMZMAT:=function( v, m ) local i,res,s,r; r:=BaseDomain(m); # do arithmetic over Z first so that we reduce only once @@ -1350,7 +1407,42 @@ InstallOtherMethod( \*, "for a plist vector and a zmodnz matrix", MakeImmutable(res); fi; return res; - end ); + end; + +InstallOtherMethod( \*, "for a plist vector and a zmodnz matrix", + IsElmsColls, [ IsList, IsZmodnZMatrixRep ], + PLISTVECZMZMAT); + +InstallOtherMethod( \^, "for a plist vector and a zmodnz matrix", + IsElmsColls, [ IsList, IsZmodnZMatrixRep ], + PLISTVECZMZMAT); + +ZMZVECTIMESPLISTMAT:=function( v, m ) + local i,res,s,r; + r:=BaseDomain(v); + # do arithmetic over Z first so that we reduce only once + res:=ListWithIdenticalEntries(Length(m[1]),Zero(r)); + for i in [1..Length(v)] do + s := v[i]; + if not IsZero(s) then + AddRowVector(res,m[i],s); + fi; + od; + res:=Vector(r,res); + + if not IsMutable(v) and not IsMutable(m) then + MakeImmutable(res); + fi; + return res; + end; + +InstallOtherMethod( \*, "for a zmodnz vector and plist matrix", + IsElmsColls, [ IsZmodnZVectorRep, IsMatrix ], + ZMZVECTIMESPLISTMAT); + +InstallOtherMethod( \^, "for a zmodnz vector and plist matrix", + IsElmsColls, [ IsZmodnZVectorRep, IsMatrix ], + ZMZVECTIMESPLISTMAT); InstallMethod( CompatibleVector, "for a zmodnz matrix", [ IsZmodnZMatrixRep ], diff --git a/lib/overload.g b/lib/overload.g index fa4ba342dd..2a773ab935 100644 --- a/lib/overload.g +++ b/lib/overload.g @@ -121,7 +121,7 @@ InstallMethod( DerivedSeries, [ IsGroup ], DerivedSeriesOfGroup ); ## DeclareOperation( "Determinant", [ IsObject ] ); -InstallMethod( Determinant, [ IsMatrix ], DeterminantMat ); +InstallMethod( Determinant, [ IsMatrixOrMatrixObj ], DeterminantMat ); InstallMethod( Determinant, [ IsClassFunction ], DeterminantOfCharacter ); diff --git a/lib/polyfinf.gi b/lib/polyfinf.gi index 04acdb184b..289eb2c4d8 100644 --- a/lib/polyfinf.gi +++ b/lib/polyfinf.gi @@ -104,7 +104,11 @@ local br, ind, c, facs, deg, px, pow, cyc, gcd,d,powc,fc,fam; #px := LaurentPolynomialByExtRepNC( # FamilyObj(f), [One(br)],1, ind ); # pow := px; - px:=ImmutableVector(br, [Zero(br),-One(br)]); + if IsFinite(br) and IsField(br) and Size(br)>MAXSIZE_GF_INTERNAL then + px:=Immutable([Zero(br),-One(br)]); + else + px:=ImmutableVector(br, [Zero(br),-One(br)]); + fi; powc:=-px; fc:=CoefficientsOfLaurentPolynomial(f)[1]; fam:=FamilyObj(One(br)); diff --git a/lib/ratfun1.gi b/lib/ratfun1.gi index 1d7ca3d9dd..234a171672 100644 --- a/lib/ratfun1.gi +++ b/lib/ratfun1.gi @@ -42,7 +42,13 @@ local f,typ,lc; # slightly better to do this after the Length has been determined if IsFFECollection(coeff) and IS_PLIST_REP(coeff) then - coeff := ImmutableVector(DefaultRing(coeff), coeff); + f:=DefaultRing(coeff); + if IsFinite(f) and Size(f)>MAXSIZE_GF_INTERNAL then + # do not pack Zmodnz objects into vectors + coeff := Immutable(coeff); + else + coeff := ImmutableVector(f, coeff); + fi; fi; From 5f73dc4f08f330dc1b9f773f38e9a078278ae1ee Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 19 Apr 2022 15:34:00 -0600 Subject: [PATCH 3/4] Methods for row spaces by vector objects Needed to make groups of matrix objects feasible --- lib/grpmat.gi | 3 +- lib/matrix.gi | 39 +++++++++++++-- lib/vecmat.gi | 3 +- lib/vspcrow.gi | 125 ++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 154 insertions(+), 16 deletions(-) diff --git a/lib/grpmat.gi b/lib/grpmat.gi index c586dd1058..775ec29037 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -356,7 +356,8 @@ local field, dict, acts, start, j, zerov, zero, dim, base, partbas, heads, if v<>zerov then Add(base,orb[i]); Add(partbas,ShallowCopy(orb[i])); - if ForAny(partbas,IsVectorObj) then + # filter for vector objects, not compressed FF vectors + if ForAny(partbas,x->IsVectorObj(x) and not IsDataObjectRep(x)) then partbas:=Matrix(BaseDomain(partbas[1]),partbas); fi; TriangulizeMat(partbas); diff --git a/lib/matrix.gi b/lib/matrix.gi index 87b20a7744..1df6c180bd 100644 --- a/lib/matrix.gi +++ b/lib/matrix.gi @@ -2185,6 +2185,11 @@ InstallOtherMethod( TriangulizedNullspaceMatDestructive, function( mat ) local ns; ns := SemiEchelonMatTransformationDestructive(mat).relations; + if IsPlistRep(ns) and Length(ns)>0 + # filter for vector objects, not compressed FF vectors + and ForAll(ns,x->IsVectorObj(x) and not IsDataObjectRep(x)) then + ns:=Matrix(BaseDomain(mat),ns); + fi; TriangulizeMat(ns); return ns; end ); @@ -2272,8 +2277,15 @@ InstallMethod( GeneralisedEigenspaces, "for a matrix or matrix obj", [ IsField, IsMatrixOrMatrixObj ], function( F, A ) - return List( GeneralisedEigenvalues( F, A ), eval -> - VectorSpace( F, TriangulizedNullspaceMat( Value( eval, A ) ) ) ); + local M,S,eval; + S:=[]; + for eval in GeneralisedEigenvalues(F,A) do + M:=TriangulizedNullspaceMat( Value( eval, A ) ); + if IsMatrixObj(M) and not IsMatrix(M) then + M:=RowsOfMatrix(M); fi; + Add(S,VectorSpace(F,M)); + od; + return S; end ); ############################################################################# @@ -2436,6 +2448,27 @@ InstallMethod( SemiEchelonMat, return SemiEchelonMatDestructive( copymat ); end ); +InstallOtherMethod( SemiEchelonMat, + "generic method for list of vector objects", + [ IsList ], + function( mat ) + local copymat, v, vc, f; + # filter for vector objects, not compressed FF vectors + if not (ForAll(mat,x->IsVectorObj(x) and not IsDataObjectRep(x)) + and Length(mat)>0) then + TryNextMethod(); + fi; + copymat := []; + if Length(mat)>0 then + f := BaseDomain(mat[1]); + for v in mat do + vc := ShallowCopy(v); + Add(copymat, vc); + od; + fi; + return SemiEchelonMatDestructive(Matrix(f, copymat )); +end ); + ############################################################################# ## @@ -3023,7 +3056,7 @@ function( M1, M2 ) return [ sum, int ]; end ); -InstallOtherMethod( SumIntersectionMat,"MatricObject", IsIdenticalObj, +InstallOtherMethod( SumIntersectionMat,"MatrixObject", IsIdenticalObj, [ IsMatrixObj, IsMatrixObj ], function( M1, M2 ) local n, # number of columns diff --git a/lib/vecmat.gi b/lib/vecmat.gi index cb0c684624..9d3cb4f778 100644 --- a/lib/vecmat.gi +++ b/lib/vecmat.gi @@ -1595,7 +1595,8 @@ local sf, rep, ind, ind2, row, i,big,l,nr; rep:=IsPlistRep; fi; - if IsPlistRep(matrix) and not ForAll(matrix,IsPlistRep) then + # cannot use NrRows consistently, as input might be mixed format + if IsList(matrix) then nr:=Length(matrix); else nr:=NrRows(matrix); diff --git a/lib/vspcrow.gi b/lib/vspcrow.gi index 38868c5956..1b40df4f80 100644 --- a/lib/vspcrow.gi +++ b/lib/vspcrow.gi @@ -155,6 +155,48 @@ InstallMethod( LeftModuleByGenerators, return V; end ); +InstallOtherMethod( LeftModuleByGenerators, + "for division ring and list of vector objects", + IsElmsColls, + [ IsDivisionRing, IsList ], + # ensure it ranks above the generic method + function( F, mat ) + local V,typ; + + # filter for vector objects, not compressed FF vectors + if not ForAll(mat,x->IsVectorObj(x) and not IsDataObjectRep(x)) then + TryNextMethod(); + fi; + typ:=IsAttributeStoringRep and HasIsEmpty and IsFiniteDimensional; + if ForAll( mat, row -> IsSubset( F, BaseDomain(row) ) ) then + typ:=typ and IsGaussianRowSpace; + else + typ:=typ and IsVectorSpace and IsRowModule and IsNonGaussianRowSpace; + fi; + + if Length(mat)>0 and ForAny(mat,x->not IsZero(x)) then + typ:=typ and IsNonTrivial; + else + typ:=typ and IsTrivial; + fi; + + if HasIsFinite(F) then + if IsFinite(F) then + typ:=typ and IsFinite; + else + typ:=typ and HasIsFinite; # i.e. not finite + fi; + fi; + + V:= Objectify( NewType( FamilyObj( mat ), typ), rec() ); + + SetLeftActingDomain( V, F ); + SetGeneratorsOfLeftModule( V, AsList( mat ) ); + SetDimensionOfVectors( V, Length( mat[1] ) ); + + return V; + end ); + ############################################################################# ## @@ -289,11 +331,8 @@ InstallMethod( LinearCombination, IsCollsElms, ## #M Coefficients( , ) . method for semi-ech. basis of Gaussian space ## -InstallMethod( Coefficients, - "for semi-ech. basis of a Gaussian row space, and a row vector", - IsCollsElms, - [ IsBasis and IsSemiEchelonBasisOfGaussianRowSpaceRep, IsRowVector ], - function( B, v ) + +COEFFS_SEMI_ECH_BASIS:=function( B, v ) local vectors, # basis vectors of `B' heads, # heads info of `B' len, # length of `v' @@ -333,8 +372,19 @@ InstallMethod( Coefficients, # Return the coefficients. return coeff; - end ); + end; +InstallMethod( Coefficients, + "for semi-ech. basis of a Gaussian row space, and a row vector", + IsCollsElms, + [ IsBasis and IsSemiEchelonBasisOfGaussianRowSpaceRep, IsRowVector ], + COEFFS_SEMI_ECH_BASIS); + +InstallMethod( Coefficients, + "for semi-ech. basis of a Gaussian row space, and vector object", + IsCollsElms, + [ IsBasis and IsSemiEchelonBasisOfGaussianRowSpaceRep, IsVectorObj ], + COEFFS_SEMI_ECH_BASIS); ############################################################################# ## @@ -640,16 +690,24 @@ InstallMethod( SemiEchelonBasis, return B; end ); -InstallMethod( SemiEchelonBasis, - "for Gaussian row space and matrix", +InstallOtherMethod( SemiEchelonBasis, + "for Gaussian row space and list of vector objects", IsIdenticalObj, - [ IsGaussianRowSpace, IsMatrix ], + [ IsGaussianRowSpace, IsList ], function( V, gens ) local heads, # heads info for the basis B, # the basis, result gensi, # immutable copy + flag, v; # loop over vector space generators + flag:=false; + if ForAll(gens,x->IsVectorObj(x) and not IsDataObjectRep(x)) then + flag:=true; + elif not IsMatrix(gens) then + TryNextMethod(); + fi; + # Check that the vectors form a semi-echelonized basis. heads:= HeadsInfoOfSemiEchelonizedMat( gens, DimensionOfVectors( V ) ); if heads = fail then @@ -669,6 +727,7 @@ InstallMethod( SemiEchelonBasis, fi; SetUnderlyingLeftModule( B, V ); gensi := ImmutableMatrix(LeftActingDomain(V), gens); + if flag then gensi:=RowsOfMatrix(gensi);fi; SetBasisVectors( B, gensi ); B!.heads:= heads; @@ -713,6 +772,40 @@ InstallMethod( SemiEchelonBasisNC, return B; end ); +InstallOtherMethod( SemiEchelonBasisNC, + "for Gaussian row space and list of vector objects", + IsIdenticalObj, + [ IsGaussianRowSpace, IsList ], + function( V, gens ) + local B, # the basis, result + gensi; # immutable copy + + # filter for vector objects, not compressed FF vectors + if not ForAll(gens,x->IsVectorObj(x) and not IsDataObjectRep(x)) then + TryNextMethod(); + fi; + + B:= Objectify( NewType( FamilyObj( gens ), + IsFiniteBasisDefault + and IsSemiEchelonized + and IsSemiEchelonBasisOfGaussianRowSpaceRep ), + rec() ); + if IsEmpty( gens ) then + SetIsEmpty( B, true ); + else + SetIsRectangularTable( B, true ); + fi; + SetUnderlyingLeftModule( B, V ); + gensi := RowsOfMatrix(ImmutableMatrix(LeftActingDomain(V), gens)); + SetBasisVectors( B, gens ); + + # Provide the `heads' information. + B!.heads:= HeadsInfoOfSemiEchelonizedMat( gens, DimensionOfVectors( V ) ); + + # Return the basis. + return B; + end ); + ############################################################################# ## @@ -881,9 +974,18 @@ InstallMethod( Intersection2, S:= Intersection2( AsVectorSpace( S, V ), AsVectorSpace( S, W ) ); else - # Compute the intersection of two spaces over the same field. + # Compute the intersection of two spaces over the same field. + if ForAll(GeneratorsOfLeftModule(V), + x->IsVectorObj(x) and not IsDataObjectRep(x)) + and ForAll(GeneratorsOfLeftModule(W), + x->IsVectorObj(x) and not IsDataObjectRep(x)) then + mat:= SumIntersectionMat( Matrix(LeftActingDomain(V), + GeneratorsOfLeftModule( V )),Matrix(LeftActingDomain(W), + GeneratorsOfLeftModule( W ) ))[2]; + else mat:= SumIntersectionMat( BasisVectors(SemiEchelonBasis( V )), BasisVectors(SemiEchelonBasis( W )) )[2]; + fi; #T why not just the generators if no basis is known yet? if IsEmpty( mat ) then S:= TrivialSubspace( V ); @@ -1066,7 +1168,8 @@ InstallMethod( CanonicalBasis, # Make a copy to avoid changing the original argument. B:= List( GeneratorsOfLeftModule( V ), ShallowCopy ); - if ForAny(B,IsVectorObj) then + # filter for vector objects, not compressed FF vectors + if ForAny(B,x->IsVectorObj(x) and not IsDataObjectRep(x)) then B:=List(B,Unpack); fi; m:= Length( B ); From 759c4d5febf5a9237dd5682f8a6c88ad1b47d3c7 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 25 Feb 2022 16:32:35 -0700 Subject: [PATCH 4/4] Added/Changed tests for changes New tests for MeatAxe/Group operations using zmodnz matrix objects, Subsequent changed output in tests Don't check for view format of matrices in HPCGAP which for some reason keeps old format. --- tst/testinstall/MatrixObj/IdentityMatrix.tst | 4 ++-- tst/testinstall/MatrixObj/ZeroMatrix.tst | 6 +++--- tst/testinstall/MatrixObj/ZeroVector.tst | 4 ++-- tst/testinstall/vecmat.tst | 10 ++-------- tst/testinstall/zmodnz.tst | 4 +--- tst/teststandard/opers/Matobjnz.tst | 17 +++++++++++++++++ 6 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 tst/teststandard/opers/Matobjnz.tst diff --git a/tst/testinstall/MatrixObj/IdentityMatrix.tst b/tst/testinstall/MatrixObj/IdentityMatrix.tst index fa7b07e327..b9a0d48890 100644 --- a/tst/testinstall/MatrixObj/IdentityMatrix.tst +++ b/tst/testinstall/MatrixObj/IdentityMatrix.tst @@ -88,9 +88,9 @@ Error, IdentityMatrix: the dimension must be non-negative # gap> IdentityMatrix(Integers mod 4, 2); -<2x2-matrix over (Integers mod 4)> + gap> IdentityMatrix(Integers mod 4, 0); -<0x0-matrix over (Integers mod 4)> +<0x0-matrix mod 4> gap> IdentityMatrix(Integers mod 4, -1); Error, IdentityMatrix: the dimension must be non-negative diff --git a/tst/testinstall/MatrixObj/ZeroMatrix.tst b/tst/testinstall/MatrixObj/ZeroMatrix.tst index 2affaa554b..495fe9b55a 100644 --- a/tst/testinstall/MatrixObj/ZeroMatrix.tst +++ b/tst/testinstall/MatrixObj/ZeroMatrix.tst @@ -94,11 +94,11 @@ gap> ZeroMatrix(Integers, 2, 0); # gap> ZeroMatrix(Integers mod 4, 2, 3); -<2x3-matrix over (Integers mod 4)> + gap> ZeroMatrix(Integers mod 4, 0, 3); -<0x3-matrix over (Integers mod 4)> +<0x3-matrix mod 4> gap> ZeroMatrix(Integers mod 4, 2, 0); -<2x0-matrix over (Integers mod 4)> +<2x0-matrix mod 4> # gap> ZeroMatrix(GF(2), 2, 3); diff --git a/tst/testinstall/MatrixObj/ZeroVector.tst b/tst/testinstall/MatrixObj/ZeroVector.tst index de4aa2b3d1..6d435d617c 100644 --- a/tst/testinstall/MatrixObj/ZeroVector.tst +++ b/tst/testinstall/MatrixObj/ZeroVector.tst @@ -82,9 +82,9 @@ Error, ZeroVector: length must be non-negative # gap> ZeroVector(Integers mod 4, 2); - + gap> ZeroVector(Integers mod 4, 0); - + gap> ZeroVector(Integers mod 4, -1); Error, ZeroVector: length must be non-negative diff --git a/tst/testinstall/vecmat.tst b/tst/testinstall/vecmat.tst index c5037977b3..cc7d5616c0 100644 --- a/tst/testinstall/vecmat.tst +++ b/tst/testinstall/vecmat.tst @@ -226,18 +226,12 @@ gap> F := Integers mod 6;; m := IdentityMat( 3, F ); [ [ ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ) ], [ ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ) ], [ ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ) ] ] -gap> w := ImmutableMatrix( F, m ); -[ [ ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ) ], - [ ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ) ], - [ ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ) ] ] +gap> w := ImmutableMatrix( F, m );; gap> m = w; true gap> IsMutable(w); false -gap> w := ImmutableMatrix( F, m, true ); -[ [ ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ) ], - [ ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ) ], - [ ZmodnZObj( 0, 6 ), ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ) ] ] +gap> w := ImmutableMatrix( F, m, true );; gap> m = w; true gap> IsMutable(w); diff --git a/tst/testinstall/zmodnz.tst b/tst/testinstall/zmodnz.tst index 2ea1b9461f..16e8879b91 100644 --- a/tst/testinstall/zmodnz.tst +++ b/tst/testinstall/zmodnz.tst @@ -419,9 +419,7 @@ gap> one:= One( A ); [ [ ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ) ], [ ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ) ] ] gap> G:= GroupWithGenerators( [ one ] );; -gap> One( G ); -[ [ ZmodnZObj( 1, 6 ), ZmodnZObj( 0, 6 ) ], - [ ZmodnZObj( 0, 6 ), ZmodnZObj( 1, 6 ) ] ] +gap> One( G );; gap> m:=[[4,1],[1,5]] * ZmodnZObj(1,6);; gap> m in A; m in G; true diff --git a/tst/teststandard/opers/Matobjnz.tst b/tst/teststandard/opers/Matobjnz.tst new file mode 100644 index 0000000000..8274552c51 --- /dev/null +++ b/tst/teststandard/opers/Matobjnz.tst @@ -0,0 +1,17 @@ +gap> START_TEST("Matobjnz.tst"); + +# +gap> p:=NextPrimeInt(MAXSIZE_GF_INTERNAL);; +gap> g:=AlternatingGroup(5);; +gap> mo:=IrreducibleModules(g,GF(p));; +gap> Set(List(mo[2],x->x.dimension)); +[ 1, 4, 5, 6 ] +gap> h:=Group(mo[2][2].generators); + +gap> Size(h); +60 +gap> Length(ConjugacyClassesSubgroups(h)); +9 + +# +gap> STOP_TEST("Matobjnz.tst",1);