Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W basicmat.gi GAP Library Frank Celler ## ## #Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany ## ## This file contains the methods for the construction of the basic matrix ## group types. ## ############################################################################# ## #M CyclicGroupCons( <IsMatrixGroup>, <field>, <n> ) ## InstallOtherMethod( CyclicGroupCons, "matrix group for given field", true, [ IsMatrixGroup and IsFinite, IsField, IsInt and IsPosRat ], 0, function( filter, fld, n ) local o, m, i, g; o := One(fld); m := NullMat( n, n, fld ); for i in [ 1 .. n-1 ] do m[i][i+1] := o; od; m[n][1] := o; m := [ ImmutableMatrix(fld,m,true) ]; g := GroupByGenerators( m ); SetIsCyclic (g, true); SetMinimalGeneratingSet (g, m); SetSize( g, n ); return g; end ); ############################################################################# ## #M CyclicGroupCons( <IsMatrixGroup>, <n> ) ## InstallMethod( CyclicGroupCons, "matrix group for default field", true, [ IsMatrixGroup and IsFinite, IsInt and IsPosRat ], 0, function( filter, n ) local m, i; m := NullMat( n, n, Rationals ); for i in [ 1 .. n-1 ] do m[i][i+1] := 1; od; m[n][1] := 1; m := GroupByGenerators( [ ImmutableMatrix(Rationals,m,true) ] ); SetSize( m, n ); return m; end ); ############################################################################# ## #M QuaternionGroupCons( <IsMatrixGroup>, <n> ) ## InstallMethod( QuaternionGroupCons, "matrix group for default field", true, [ IsMatrixGroup and IsFinite, IsInt and IsPosRat ], 0, function( filter, n ) return QuaternionGroup( filter, Rationals, n ); end ); ############################################################################# ## #M QuaternionGroupCons( <IsMatrixGroup>, <field>, <n> ) ## InstallOtherMethod( QuaternionGroupCons, "matrix group for given field", true, [ IsMatrixGroup and IsFinite, IsField, IsInt and IsPosRat ], 0, function( filter, fld, n ) local bas, grp, cyc, one; if 0 <> n mod 4 then TryNextMethod(); fi; if n = 4 then return CyclicGroup( filter, fld, n ); fi; if Characteristic( fld ) = 0 and IsAbelianNumberField( fld ) then cyc := E( n / 2 ); bas := CanonicalBasis( Field( fld, [ cyc ] ) ); one := 1; elif 0 = n mod Characteristic( fld ) then # XXX: regular rep is not minimal grp := QuaternionGroup( IsPermGroup, n ); grp := Group( List( GeneratorsOfGroup( grp ), prm -> PermutationMat( prm, NrMovedPoints( grp ), fld ) ) ); SetSize( grp, n ); return grp; elif IsFFECollection( fld ) then # XXX: If OrderMod( Size( fld ), n/2 ) is large, then this asks GAP # XXX: to compute a large conway polynomial, rather than just using # XXX: a companion polynomial directly. bas := CanonicalBasis( GF( Size( fld ), OrderMod( Size( fld ), n/2 ) ) ); cyc := Z( Size( Field( bas ) ) )^( ( Size( Field( bas ) ) - 1 ) / (n/2) ); one := One( fld ); elif Characteristic( fld ) = 0 then bas := CanonicalBasis( CF( n / 2 ) ); cyc := E( n / 2 ); one := 1; else bas := CanonicalBasis( GF( Characteristic( fld ), OrderMod( Characteristic( fld ), n/2 ) ) ); cyc := Z( Size( Field( bas ) ) )^( ( Size( Field( bas ) ) - 1 ) / (n/2) ); one := One( Field( bas ) ); fi; grp := Group( List( [[[0,1],[-1,0]],[[cyc,0],[0,1/cyc]]]*one, mat -> ImmutableMatrix( fld, BlownUpMat( bas, mat )*One(fld), true ) ) ); SetSize( grp, n ); return grp; end); ############################################################################# ## #M GeneralLinearGroupCons( <IsMatrixGroup>, <d>, <F> ) ## InstallMethod( GeneralLinearGroupCons, "matrix group for dimension and finite field", [ IsMatrixGroup and IsFinite, IsInt and IsPosRat, IsField and IsFinite ], function( filter, n, f ) local q, z, o, mat1, mat2, i, g; q:= Size( f ); # small cases if q = 2 and 1 < n then #T why 1 < n? return SL( n, 2 ); fi; # construct the generators z := PrimitiveRoot( f ); o := One( f ); mat1 := IdentityMat( n, f ); mat1[1][1] := z; mat2 := List( Zero(o) * mat1, ShallowCopy ); mat2[1][1] := -o; mat2[1][n] := o; for i in [ 2 .. n ] do mat2[i][i-1]:= -o; od; mat1 := ImmutableMatrix( f, mat1,true ); mat2 := ImmutableMatrix( f, mat2,true ); g := GroupByGenerators( [ mat1, mat2 ] ); SetName( g, Concatenation("GL(",String(n),",",String(q),")") ); SetDimensionOfMatrixGroup( g, n ); SetFieldOfMatrixGroup( g, f ); SetIsNaturalGL( g, true ); SetIsFinite(g,true); if n<50 or n+q<500 then Size(g); fi; # Return the group. return g; end ); ############################################################################# ## #M SpecialLinearGroupCons( <IsMatrixGroup>, <d>, <q> ) ## InstallMethod( SpecialLinearGroupCons, "matrix group for dimension and finite field", [ IsMatrixGroup and IsFinite, IsInt and IsPosRat, IsField and IsFinite ], function( filter, n, f ) local q, g, o, z, mat1, mat2, i, size, qi; q:= Size( f ); # handle the trivial case first if n = 1 then g := GroupByGenerators( [ ImmutableMatrix( f, [[One(f)]],true ) ] ); # now the general case else # construct the generators o := One(f); z := PrimitiveRoot(f); mat1 := IdentityMat( n, f ); mat2 := List( Zero(o) * mat1, ShallowCopy ); mat2[1][n] := o; for i in [ 2 .. n ] do mat2[i][i-1]:= -o; od; if q = 2 or q = 3 then mat1[1][2] := o; else mat1[1][1] := z; mat1[2][2] := z^-1; mat2[1][1] := -o; fi; mat1 := ImmutableMatrix(f,mat1,true); mat2 := ImmutableMatrix(f,mat2,true); g := GroupByGenerators( [ mat1, mat2 ] ); fi; # set name, dimension and field SetName( g, Concatenation("SL(",String(n),",",String(q),")") ); SetDimensionOfMatrixGroup( g, n ); SetFieldOfMatrixGroup( g, f ); SetIsFinite( g, true ); if q = 2 then SetIsNaturalGL( g, true ); fi; SetIsNaturalSL( g, true ); SetIsFinite(g,true); # add the size if n<50 or n+q<500 then Size(g); fi; # return the group return g; end ); ############################################################################# ## #M GeneralSemilinearGroupCons( IsMatrixGroup, <d>, <q> ) ## InstallMethod( GeneralSemilinearGroupCons, "matrix group for dimension and finite field size", [ IsMatrixGroup and IsFinite, IsInt and IsPosRat, IsInt and IsPosRat ], function( filter, d, q ) local p, f, field, B, gl, gens, frobact, frobmat, i, g; p:= Factors( Integers, q ); f:= Length( p ); if f = 1 then return GL( d, q ); fi; p:= p[1]; field:= GF(q); B:= Basis( field ); gl:= GL( d, q ); gens:= List( GeneratorsOfGroup( gl ), x -> BlownUpMat( B, x ) ); frobact:= List( BasisVectors( B ), x -> Coefficients( B, x^p ) ); frobmat:= NullMat( d*f, d*f, GF(p) ); for i in [ 1 .. d ] do frobmat{ [ (i-1)*f+1 .. i*f ] }{ [ (i-1)*f+1 .. i*f ] }:= frobact; od; Add( gens, frobmat ); g:= GroupWithGenerators( gens ); SetName( g, Concatenation( "GammaL(",String(d),",",String(q),")" ) ); SetDimensionOfMatrixGroup( g, d*f ); SetFieldOfMatrixGroup( g, GF(p) ); SetIsFinite( g, true ); SetSize( g, f * Size( gl ) ); return g; end ); ############################################################################# ## #M SpecialSemilinearGroupCons( IsMatrixGroup, <d>, <q> ) ## InstallMethod( SpecialSemilinearGroupCons, "matrix group for dimension and finite field size", [ IsMatrixGroup and IsFinite, IsInt and IsPosRat, IsInt and IsPosRat ], function( filter, d, q ) local p, f, field, B, sl, gens, frobact, frobmat, i, g; p:= Factors( Integers, q ); f:= Length( p ); if f = 1 then return SL( d, q ); fi; p:= p[1]; field:= GF(q); B:= Basis( field ); sl:= SL( d, q ); gens:= List( GeneratorsOfGroup( sl ), x -> BlownUpMat( B, x ) ); frobact:= List( BasisVectors( B ), x -> Coefficients( B, x^p ) ); frobmat:= NullMat( d*f, d*f, GF(p) ); for i in [ 1 .. d ] do frobmat{ [ (i-1)*f+1 .. i*f ] }{ [ (i-1)*f+1 .. i*f ] }:= frobact; od; Add( gens, frobmat ); g:= GroupWithGenerators( gens ); SetName( g, Concatenation( "SigmaL(",String(d),",",String(q),")" ) ); SetDimensionOfMatrixGroup( g, d*f ); SetFieldOfMatrixGroup( g, GF(p) ); SetIsFinite( g, true ); SetSize( g, f * Size( sl ) ); return g; end ); ############################################################################# ## #M GeneralSemilinearGroupCons( IsPermGroup, <d>, <q> ) #M SpecialSemilinearGroupCons( IsPermGroup, <d>, <q> ) ## PermConstructor( GeneralSemilinearGroupCons, [ IsPermGroup, IsPosInt, IsPosInt ], IsMatrixGroup and IsFinite ); PermConstructor( SpecialSemilinearGroupCons, [ IsPermGroup, IsPosInt, IsPosInt ], IsMatrixGroup and IsFinite ); ############################################################################## ## #M SylowSubgroupOp( NaturalGL, p ) ## ## Use Weir and Carter-Fong's explicit generators for Sylow p-subgroups of ## natural general linear groups. ## CallFuncList( function() # Avoid polluting the namespace with these functions of somewhat limited interest. local SylowSubgroupOfWreathProduct, MaximalUnipotentSubgroupOfNaturalGL, TorusOfNaturalGL, SylowSubgroupOfTorusOfNaturalGL, SylowSubgroupOfNaturalGL; # Return a Sylow p-subgroup of Sym(k) wreath Sym(m) SylowSubgroupOfWreathProduct := function( k, m, p ) local wr, ss, sy; wr := WreathProduct( SymmetricGroup( k ), SymmetricGroup( m ) ); ss := List( [1..m+1], i -> Image( Embedding( wr, i ), SylowSubgroup( Source( Embedding( wr, i ) ), p ) ) ); sy := Subgroup( wr, Concatenation( List( ss, GeneratorsOfGroup ) ) ); SetSize( sy, Size(ss[1])^m*Size(ss[m+1]) ); Assert( 2, Size( sy ) = Size( Subgroup( wr, GeneratorsOfGroup( sy ) ) ) ); Assert( 0, 0 <> ( Size(wr) / Size(sy) ) mod p and IsSubgroup( wr, sy ) ); return sy; end; # The following function creates the subgroup generated by the positive simple # roots (upper triangular matrices with 1s on the diagonal, and a single # non-zero entry on the first super diagonal, the non-zero entries varying over # a basis of GF(q) over GF(p)). MaximalUnipotentSubgroupOfNaturalGL := function( gl ) local n, q, o, z, u; n := DimensionOfMatrixGroup( gl ); q := Size( DefaultFieldOfMatrixGroup( gl ) ); if SizeGL( n, q ) <> Size( gl ) then q := Size( FieldOfMatrixGroup( gl ) ); fi; if IsPosInt(q) then q := GF(q); fi; o := One(q); z := Zero(q); u := Subgroup( gl, Concatenation( List( [1..n-1], r -> List( Basis( q ), b -> ImmutableMatrix( q, List( [1..n], i -> List( [1..n], function(j) if i = r and j = r+1 then return b; elif i = j then return o; else return z; fi; end ) ), true ) ) ) ) ); SetSize( u, Size(q)^Binomial(n,2) ); IsPGroup( u ); return u; end; # The conjugacy classes of maximal tori of GL are indexed by conjugacy classes # of Weyl group elements. For a given permutation, return a corresponding # torus. TorusOfNaturalGL := function( gl, pi ) local n, q, gfq, one, orbs, gens, sub; n := DimensionOfMatrixGroup( gl ); q := Size( DefaultFieldOfMatrixGroup( gl ) ); if SizeGL( n, q ) <> Size( gl ) then q := Size( FieldOfMatrixGroup( gl ) ); fi; gfq := GF(q); one := IdentityMat( n, gfq ); orbs := Cycles( pi, [1..n] ); gens := List( orbs, function( orb ) local mat; mat := MutableCopyMat( one ); # XXX: Asks GAP to compute ConwayPolynomial, but could make do with much less mat{orb}{orb} := CompanionMat( MinimalPolynomial( gfq, Z(q^Size(orb)) ) ); return ImmutableMatrix( gfq, mat, true ); end ); sub := Subgroup( gl, gens ); SetIsAbelian( sub, true ); SetAbelianInvariants( sub, AbelianInvariantsOfList( List( orbs, orb -> q^Size(orb)-1 ) ) ); SetSize( sub, Product( AbelianInvariants( sub ) ) ); return sub; end; # The Sylow p-subgroup of a direct product of cyclic groups is quite easy to # compute. SylowSubgroupOfTorusOfNaturalGL := function( gl, pi, p ) local n, q, gfq, one, orbs, gens, sub; n := DimensionOfMatrixGroup( gl ); q := Size( DefaultFieldOfMatrixGroup( gl ) ); if SizeGL( n, q ) <> Size( gl ) then q := Size( FieldOfMatrixGroup( gl ) ); fi; gfq := GF(q); one := IdentityMat( n, gfq ); orbs := Cycles( pi, [1..n] ); gens := List( orbs, function( orb ) local k, mat; k := Size(orb); mat := MutableCopyMat( one ); mat{orb}{orb} := CompanionMat( MinimalPolynomial( gfq, Z(q^k) ) )^( (q^k-1)/p^PadicValuation(q^k-1,p)); return ImmutableMatrix( gfq, mat, true ); end ); sub := Subgroup( gl, gens ); SetIsAbelian( sub, true ); SetAbelianInvariants( sub, AbelianInvariantsOfList( List( orbs, orb -> p^PadicValuation(q^Size(orb)-1,p) ) ) ); SetSize( sub, Product( AbelianInvariants( sub ) ) ); return sub; end; # The main worker. In defining characteristic, return the maximal unipotent # subgroup. In cross-characteristic, take a Sylow p-subgroup of a # as-split-possible maximal torus, and if the dimension is large enough, the # Sylow p-subgroup of the part of the Weyl group normalizing it. SylowSubgroupOfNaturalGL := function( gl, p ) local n, q, syl, s, syl2, k, sylp, pi, prm, syl1; n := DimensionOfMatrixGroup( gl ); q := Size( DefaultFieldOfMatrixGroup( gl ) ); if SizeGL( n, q ) <> Size( gl ) then q := Size( FieldOfMatrixGroup( gl ) ); fi; if p = SmallestRootInt( q ) then # unipotent sylow syl := MaximalUnipotentSubgroupOfNaturalGL( gl ); elif p = 2 then # use Carter-Fong description s := PadicValuation( q-1, 2 ); syl1 := Subgroup( GL( 1, q ), [ [ [ Z(q)^((q-1)/2^s) ] ] ] ); if 1 = q mod 4 then s := PadicValuation( q-1, 2 ); syl2 := Subgroup( GL( 2, q ), [ [[ 0, 1 ], [ 1, 0 ]], [[ Z(q)^((q-1)/2^s), 0 ], [ 0, 1 ]], [[ 1, 0 ], [ 0, Z(q)^((q-1)/2^s) ]], ]*One(GF(q)) ); else s := PadicValuation( q+1, 2 ); syl2 := Subgroup( GL( 2, q ), [ [[ 0, 1 ], [ -1, 0 ]], [[ 0, 1 ], [ 1, Z(q^2)^((q^2-1)/2^(s+1)) + Z(q^2)^(q*(q^2-1)/2^(s+1)) ]], ]*One(GF(q)) ); fi; s := 0; pi := []; repeat k := PadicValuation( n - s, 2 ); Add( pi, [s+1..s+2^k] ); s := s+2^k; until n = s; syl := Subgroup( gl, Concatenation( List( pi, function( part ) local one, prm; one := One(gl); if Size( part ) = 1 then return List( GeneratorsOfGroup( syl1 ), function( x ) local mat; mat := MutableCopyMat( one ); mat{part}{part} := x ; return mat; end ); fi; prm := SylowSubgroup( SymmetricGroup( Size( part ) / 2 ), 2 ); return Concatenation( List( GeneratorsOfGroup( prm ), function( x ) local mat; mat := MutableCopyMat( one ); mat{part}{part} := KroneckerProduct( PermutationMat( x, Size( part )/2, GF( q ) ), One( syl2 ) ); return mat; end ), List( GeneratorsOfGroup( syl2 ), function( x ) local mat; mat := MutableCopyMat( one ); mat{part{[1..2]}}{part{[1..2]}} := x; return mat; end ) ); end ) ) ); else k := OrderMod( q, p^(2/GcdInt(p-1,2)) ); pi := PermList( List( [1..n], function(i) if i > Int(n/k)*k then return i; else return (i mod k) + 1 + k*Int((i-1)/k); fi; end ) ); syl := SylowSubgroupOfTorusOfNaturalGL( gl, pi, p ); if n >= p*k or ( p = 2 and k <= n ) then # non-abelian sylow prm := SylowSubgroupOfWreathProduct( k, Int(n/k), p ); syl2 := Subgroup( gl, Concatenation( List( GeneratorsOfGroup( prm ), pi -> PermutationMat( pi, n, GF(q) ) ), GeneratorsOfGroup( syl ) ) ); SetSize( syl2, Size(prm)*Size(syl) ); syl := syl2; fi; fi; SetSize( syl, p^PadicValuation( Size(gl), p ) ); SetIsPGroup( syl, true ); SetPrimePGroup( syl, p ); Assert( 2, Size( Group( GeneratorsOfGroup( syl ) ) ) = Size( syl ) ); return syl; end; # Just install the method. InstallMethod( SylowSubgroupOp, "Direct construction for natural GL", [ IsNaturalGL and IsFinite and IsFFEMatrixGroup, IsPosInt ], SylowSubgroupOfNaturalGL ); end, [] ); ############################################################################# ## #E