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 cat1data.gi GAP4 package `XMod' Chris Wensley ## #Y Copyright (C) 2001-2017, Chris Wensley et al, #Y School of Computer Science, Bangor University, U.K. ## These functions are used in the construction of the data file cat1data.g ## and are not intended for the general user. ## In order to use the operations which write intermediate data to file, ## start the GAP session as follows: ## gap> SetInfoLevel( InfoXMod, 2 ); ## or some higher value ## gap> gp := SmallGroup( nn, kk ); ## choose an appropriate group ## gap> gens := GeneratorsOfGroup( gp ); ## gap> ngens := Length( gens ); ## gap> f1 := gens[1]; ## gap> . . . ## repeat for each generator ## gap> id := One( gp ); ## gap> Cat1RepresentativesToFile( gp ); ## then edit nn.kk.rep ## ## changing the entry 1 in ireps ## ## to TrivialSubgroup(gp).\n" ); ## gap> Read( "lib/nn.kk.rep" ); ## read in the list ireps ## gap> Cat1IdempotentsToFile( gp, ireps, 1, jj ); ## gap> Cat1IdempotentsToFile( gp, ireps, jj+1, jjj ); ## etc. etc. ## ## then look at nn.kk.ids ## gap> Read( "lib/nn.kk.ids" ); ## read in the list of idempotents ## gap> AllCat1DataGroupsInParts( gp, ireps, idems, [1,jj], [ ] ); ## gap> Cjj := ??? ## gap> AllCat1DataGroupsInParts( gp, ireps, idems, [jj+1,jjj], Cjj ); ## etc. ## ## Finally, edit nn.kk.out, deleting the final entry, ## and changing the last line of the file to finish with: ] ] ] ] ], ############################################################################## ## #M AllCat1DataGroups . . . . . . . . . . . . . . . . . . . . . . . . for a group ## InstallGlobalFunction( AllCat1DataGroups, function( arg ) local nargs; nargs := Length( arg ); if ( nargs = 1 ) then return AllCat1DataGroupsBasic( arg[1] ); elif ( nargs = 3 ) then return AllCat1DataGroupsInParts( arg[1], arg[2], arg[3] ); else Error( "length of arg neither 1 nor 3" ); fi; end ); ############################################################################## ## #M AllCat1DataGroupsBasic . . . . . . . . . . . . . . . . . . for a cyclic Pgroup ## InstallMethod( AllCat1DataGroupsBasic, "construct all cat1-groups on a given group", true, [ IsCyclic and IsPGroup ], 0, function( gp ) local C, zero, one; C := [ 0, 0 ]; zero := MappingToOne( gp, gp ); C[1] := PreCat1GroupByEndomorphisms( zero, zero ); IsCat1Group( C[1] ); one := IdentityMapping( gp ); C[2] := PreCat1GroupByEndomorphisms( one, one ); IsCat1Group( C[2] ); return C; end ); InstallMethod( AllCat1DataGroupsBasic, "construct all cat1-groups on a given group", true, [ IsGroup ], 0, function( gp ) local gpid, size, num, gens, ngens, path, name, out, gensgp, egensgp, idem, ranges, idems, inum, i, im, R, j, numrng, aut, reps, nreps, ireps, nireps, quot, autR, a, q, b, mgi, keep, iranges, iidems, genR, igenR, aR, pos, C, Cnum, numirng, idemi, inumi, h, kerh, k, t, kert, kerth, CC, g, AICG, isocg, bdy, kerbdy, z, gens1, list1, len1, gens2, list2, len2, struc, fst, genr, egenr, imt, eimt, imh, eimh; gpid := IdGroup( gp ); size := gpid[1]; num := gpid[2]; gens := GeneratorsOfGroup( gp ); ngens := Length( gens ); gensgp := SmallGeneratingSet( gp ); egensgp := List( gensgp, g -> ExtRepOfObj(g) ); path := DirectoriesPackageLibrary( "xmod", "lib" )[1]; name := Concatenation( String(size), ".", String(num), ".out" ); out := Filename( path, name ); ## find isomorphism classes of subgroups if not IsPcGroup( gp ) then return fail; fi; aut := AutomorphismGroup( gp ); reps := List( ConjugacyClassesSubgroups(gp), c -> Representative(c) ); nreps := Length( reps ); Info( InfoXMod, 2, "nreps = ", nreps ); keep := ListWithIdenticalEntries( nreps, 1 ); ireps := [ ]; for i in [1..nreps] do if ( keep[i] = 1 ) then Info( InfoXMod, 2, " rep number: ", i ); R := reps[i]; Add( ireps, R ); genR := GeneratorsOfGroup( R ); for a in aut do igenR := List( genR, g -> Image( a, g ) ); aR := Subgroup( gp, igenR ); pos := Position( reps, aR ); if ( not( pos = fail ) and ( pos > i ) ) then keep[pos] := 0; fi; od; fi; od; nireps := Length( ireps ); if ( InfoLevel( InfoXMod ) > 1 ) then Print( nreps, " reps reduced to ", nireps, "\n" ); for i in [1..nireps] do Print( ireps[i], " <--> ", StructureDescription( ireps[i] ), "\n" ); od; elif ( InfoLevel( InfoXMod ) > 0 ) then PrintListOneItemPerLine( ireps ); fi; idems := ListWithIdenticalEntries( nireps, 0 ); for i in [1..nireps] do Info( InfoXMod, 2, "subgroup number: ", i ); idems[i] := [ ]; R := ireps[i]; quot := GQuotients( gp, R ); autR := AutomorphismGroup( R ); for q in quot do for a in autR do b := q*a; if ( b*b = b ) then pos := Position( idems[i], b ); if ( pos = fail ) then Add( idems[i], b ); fi; fi; od; od; od; ## now convert entries in idems back to endomorphisms of gp ## GQuotients may have picked an alternative generating set for gp for i in [1..nireps] do idem := idems[i]; for j in [1..Length(idem)] do mgi := List( gens, g -> Image( idem[j], g ) ); idem[j] := GroupHomomorphismByImages( gp, gp, gens, mgi ); od; od; if ( InfoLevel( InfoXMod ) > 0 ) then Print( "# idempotents = ", Sum( List( idems, i -> Length(i) ) ), "\n" ); Print( List( idems, i -> Length(i) ), "\n" ); fi; if ( InfoLevel( InfoXMod ) > 1 ) then Print( "\nidems = \n" ); PrintListOneItemPerLine( idems ); fi; C := [ ]; Cnum := 0; for i in [1..nireps] do R := ireps[i]; idemi := idems[i]; inumi := Length( idemi ); for j in [1..inumi] do h := idemi[j]; kerh := Kernel( h ); # (e;t,h:G->R) isomorphic to (e;h,t:G->R), so take k>=j for k in [j..inumi] do t := idemi[k]; kert := Kernel( t ); kerth := CommutatorSubgroup( kert, kerh ); if ( Size( kerth ) = 1 ) then if ( InfoLevel( InfoXMod ) > 1 ) then Print( "t: ", MappingGeneratorsImages(t)[2], "\n" ); Print( "h: ", MappingGeneratorsImages(h)[2], "\n" ); fi; CC := PreCat1GroupByEndomorphisms( t, h ); if not IsCat1Group( CC ) then Error( "not a cat1-group" ); fi; g := Cnum; AICG := false; while ( not AICG and ( g > 0 ) ) do #? is this expensive? isocg := IsomorphismPreCat1Groups( C[g], CC ); AICG := not ( isocg = fail ); g := g-1; od; if ( AICG = false ) then Add( C, CC ); Cnum := Cnum + 1; Info( InfoXMod, 2, "\nC[", Cnum, "] = ", CC ); else ## maybe CC is a simpler construction than C[g] ? gens1 := GeneratorsOfGroup( Range( CC ) ); list1 := Flat( List( gens1, g -> ExtRepOfObj(g) ) ); for z in [1..Length(list1)] do if IsOddInt(z) then list1[z] := 0; fi; od; len1 := Sum( list1 ); g := g+1; Info( InfoXMod, 2, "isomorphic to C[g], g = ", g ); gens2 := GeneratorsOfGroup( Range( C[g] ) ); list2 := Flat( List( gens2, g -> ExtRepOfObj(g) ) ); for z in [1..Length(list2)] do if IsOddInt(z) then list2[z] := 0; fi; od; len2 := Sum( list2 ); Info( InfoXMod, 2, "len1 = ", len1, ", len2 = ", len2, " at [i,j,k] = ", [i,j,k] ); if ( len1 < len2 ) then C[g] := CC; Info( InfoXMod, 2, "swapping due to lengths:" ); Info( InfoXMod, 2, "gens1 = ", gens1 ); Info( InfoXMod, 2, "gens2 = ", gens2 ); elif ( len1 = len2 ) then # check no. generators fixed by tail map len1 := 0; for z in gens1 do if ( Image(TailMap(CC),z) = z ) then len1 := len1 + 1; fi; od; len2 := 0; for z in gens2 do if ( Image(TailMap(CC),z) = z ) then len2 := len2 + 1; fi; od; if ( len1 < len2 ) then C[g] := CC; Info( InfoXMod, 2, "swapping due to fixed points" ); Info( InfoXMod, 2, "gens1 = ", gens1 ); Info( InfoXMod, 2, "gens2 = ", gens2 ); fi; fi; fi; fi; od; od; od; if ( InfoLevel( InfoXMod ) > 0 ) then for i in [1..Cnum] do CC := C[i]; Print( "Isomorphism class ", i, "\n" ); if ( Size( Kernel( CC ) ) < 101 ) then Print( ": kernel of tail = ", IdGroup( Kernel( CC) ), "\n" ); else Print( ": kernel has size = ", Size( Kernel( CC ) ), "\n" ); fi; if ( Size( Range( CC ) ) < 101 ) then Print( ": range group = ", IdGroup( Range( CC ) ), "\n" ); else Print( ": range has size = ", Size( Range( CC ) ), "\n" ); fi; bdy := Boundary( CC ); kerbdy := Kernel( bdy ); if ( kerbdy <> Kernel( CC ) ) then if ( Size( kerbdy ) < 101 ) then Print( ": kernel of bdy = ", IdGroup( kerbdy ), "\n" ); else Print( ": kernel of bdy has size ", Size(kerbdy), "\n" ); fi; fi; Print( "\n" ); od; fi; ## now output in the form required for the cat1data.g file struc := StructureDescription( gp ); PrintTo( out, "[",size,",",num,",\"",struc,"\",",egensgp,",[\n" ); if IsAbelian( gp ) then fst := 2; else fst := 1; fi; for j in [fst..Cnum-1] do a := C[j]; genr := SmallGeneratingSet( Range(a) ); egenr := List( genr, g -> ExtRepOfObj(g) ); t := TailMap( a ); imt := List( gensgp, g -> Image( t, g ) ); eimt := List( imt, g -> ExtRepOfObj(g) ); h := HeadMap( a ); imh := List( gensgp, g -> Image( h, g ) ); eimh := List( imh, g -> ExtRepOfObj(g) ); AppendTo( out,"[ ",egenr,",\n ",eimt,",\n ",eimh," ],\n" ); od; Print( "#I Edit last line of .../xmod/lib/nn.kk.out to end with ] ] ] ] ]\n" ); return C; end ); ############################################################################## ## #M Cat1RepresentativesToFile . . . . . . . . . . . . . . . . . . for a group ## InstallMethod( Cat1RepresentativesToFile, "construct potential idempotents", true, [ IsGroup ], 0, function( gp ) local gpid, size, num, name, path, rname, rout, iname, iout, gens, ngens, aut, reps, nreps, keep, ireps, i, R, genR, a, igenR, aR, pos, nireps, idems, quot, autR, q, b, idem, j, k, id, mgi, nidems, GHBI; gpid := IdGroup( gp ); size := gpid[1]; num := gpid[2]; gens := GeneratorsOfGroup( gp ); ngens := Length( gens ); path := DirectoriesPackageLibrary( "xmod", "lib" )[1]; gp := SmallGroup( size, num ); rname := Concatenation( String(size), ".", String(num), ".rep" ); rout := Filename( path, rname ); ## find isomorphism classes of subgroups if not IsPcGroup( gp ) then return fail; fi; aut := AutomorphismGroup( gp ); reps := List( ConjugacyClassesSubgroups(gp), c -> Representative(c) ); nreps := Length( reps ); Print( "nreps = ", nreps, "\n" ); keep := ListWithIdenticalEntries( nreps, 1 ); ireps := [ ]; for i in [1..nreps] do if ( keep[i] = 1 ) then Info( InfoXMod, 2, " rep number: ", i ); R := reps[i]; Add( ireps, R ); genR := GeneratorsOfGroup( R ); for a in aut do igenR := List( genR, g -> Image( a, g ) ); aR := Subgroup( gp, igenR ); pos := Position( reps, aR ); if ( not( pos = fail ) and ( pos > i ) ) then keep[pos] := 0; fi; od; fi; od; nireps := Length( ireps ); if ( InfoLevel( InfoXMod ) > 1 ) then Print( nreps, " reps reduced to ", nireps, "\n" ); for i in [1..nireps] do Print( ireps[i], " <--> ", StructureDescription(ireps[i]), "\n" ); od; else PrintListOneItemPerLine( ireps ); fi; PrintTo( rout, "ireps := ", ireps, ";\n" ); iname := Concatenation( String(size), ".", String(num), ".ids" ); iout := Filename( path, iname ); PrintTo( iout, "GHBI := GroupHomomorphismByImages;\n" ); AppendTo( iout, "idems := [ \n" ); Print( "Remember to edit the file ", rname, ",\n" ); Print( "changing the first entry in ireps to TrivialSubgroup(gp).\n" ); return nireps; end ); ############################################################################## ## #M Cat1IdempotentsToFile . . . . . . . . . . . . . . . . . . . . for a group ## InstallMethod( Cat1IdempotentsToFile, "construct potential idempotents", true, [ IsGroup, IsList, IsPosInt, IsPosInt ], 0, function( gp, ireps, fst, lst ) local gpid, size, num, path, iname, iout, gens, ngens, aut, reps, ist, nreps, keep, i, R, genR, a, igenR, aR, pos, nireps, quot, autR, q, b, idem, j, k, id, mgi, nidems, GHBI; gpid := IdGroup( gp ); size := gpid[1]; num := gpid[2]; gens := GeneratorsOfGroup( gp ); ngens := Length( gens ); path := DirectoriesPackageLibrary( "xmod", "lib" )[1]; iname := Concatenation( String(size), ".", String(num), ".ids" ); iout := Filename( path, iname ); id := One( gp ); GHBI := GroupHomomorphismByImages; nireps := Length( ireps ); if ( lst >= nireps ) then ist := nireps - 1; else ist := lst; fi; nidems := 0; Info( InfoXMod, 2, "determining idempotents in range ", [fst,ist] ); for i in [fst..ist] do idem := [ ]; R := ireps[i]; Info( InfoXMod, 2, "subgroup number: ", i, ", ", StructureDescription( R ) ); quot := GQuotients( gp, R ); autR := AutomorphismGroup( R ); Info( InfoXMod, 2, "[quot,autR] has sizes ", [ Length(quot), Size(autR) ] ); for q in quot do for a in autR do b := q*a; if ( b*b = b ) then pos := Position( idem, b ); if ( pos = fail ) then Add( idem, b ); fi; fi; od; od; ## now convert entries in idem back to endomorphisms of gp ## GQuotients may have picked an alternative generating set for gp for j in [1..Length(idem)] do mgi := List( gens, g -> Image( idem[j], g ) ); idem[j] := GroupHomomorphismByImages( gp, gp, gens, mgi ); od; Print( "# idempotents = ", Length( idem ), "\n" ); if ( InfoLevel( InfoXMod ) >= 2 ) then PrintListOneItemPerLine( idem ); fi; if ( idem = [ ] ) then AppendTo( iout, "[ ]" ); else AppendTo( iout, "[ " ); for j in [1..Length( idem )] do mgi := MappingGeneratorsImages( idem[j] )[2]; AppendTo( iout, "GHBI( gp, gp, gens, [" ); for k in [1..ngens] do if ( mgi[k] = id ) then AppendTo( iout, "id" ); else AppendTo( iout, mgi[k] ); fi; if ( k < ngens ) then AppendTo( iout, "," ); else AppendTo( iout, "] )" ); fi; od; if ( j = Length(idem) ) then AppendTo( iout, " ]" ); else AppendTo( iout, ",\n" ); fi; od; fi; AppendTo( iout, ",\n" ); if ( i = nireps ) then AppendTo( iout, "GHBI( gp, gp, gens, gens ) ] ];\n" ); fi; nidems := nidems + Length( idem ); od; return nidems; end ); ############################################################################## ## #M CollectPartsAlreadyDone . . . . . . . . . . . . . . . . . . . for a group ## InstallMethod( CollectPartsAlreadyDone, "preparation for AllCat1DataGroupsInParts", true, [ IsGroup, IsPosInt, IsPosInt, IsList ], 0, function( gp, nn, kk, range ) local C0, j, C1, Clen, Cj, gpj, iso, Rj, res, ok, mor; C0 := List( range, j -> Cat1Select(nn,kk,j) ); for j in C0 do Display(j); od; C1 := ShallowCopy( C0 ); Clen := Length( C0 ); for j in [1..Clen] do Cj := C0[j]; gpj := Source( Cj ); iso := IsomorphismGroups( gpj, gp ); Rj := Range( Cj ); res := GeneralRestrictedMapping( iso, Rj, gp ); res := GeneralRestrictedMapping( iso, Rj, Image(res) ); ok := IsBijective( iso ) and IsBijective( res ); if not ok then Error( "iso/res not bijective in CooectPartsAlreadyDone" ); fi; mor := IsomorphismByIsomorphisms( Cj, [ iso, res ] ); C1[j] := Range( mor ); od; return C1; end ); ############################################################################## ## #M AllCat1DataGroupsInParts . . . . . . . . . . . . . . . . . . . . . . . for a group ## InstallMethod( AllCat1DataGroupsInParts, "construct all cat1-groups on a given group", true, [ IsGroup, IsList, IsList, IsList, IsList ], 0, function( gp, ireps, idems, range, C ) local gpid, size, num, gens, ngens, path, name, out, id, Cnum, Cnum0, i, R, j, nireps, fst, lst, ist, single, sj, sk, numirng, idemi, inumi, h, kerh, k, t, kert, kerth, CC, g, AICG, isocg, bdy, kerbdy, z, gens1, list1, len1, gens2, list2, len2, struc, gensgp, egensgp, a, genr, egenr, imt, eimt, imh, eimh; gpid := IdGroup( gp ); size := gpid[1]; num := gpid[2]; gens := GeneratorsOfGroup( gp ); ngens := Length( gens ); path := DirectoriesPackageLibrary( "xmod", "lib" )[1]; name := Concatenation( String(size), ".", String(num), ".out" ); out := Filename( path, name ); id := One( gp ); gens := GeneratorsOfGroup( gp ); gensgp := SmallGeneratingSet( gp ); egensgp := List( gensgp, g -> ExtRepOfObj(g) ); nireps := Length( ireps ); fst := range[1]; lst := range[2]; if ( lst > nireps ) then ist := nireps; else ist := lst; fi; single := ( ( fst = ist ) and ( Length( range ) = 4 ) ); if single then sj := range[3]; sk := range[4]; else sj := 1; sk := 0; fi; Cnum := Length( C ); Cnum0 := Cnum; for i in [fst..ist] do R := ireps[i]; idemi := idems[i]; inumi := Length( idemi ); if not single then sk := inumi; fi; for j in [sj..sk] do h := idemi[j]; kerh := Kernel( h ); # (e;t,h:G->R) isomorphic to (e;h,t:G->R), so take k>=j for k in [j..inumi] do Print( "\n[i,j,k] = ", [i,j,k], "\n" ); t := idemi[k]; kert := Kernel( t ); kerth := CommutatorSubgroup( kert, kerh ); if ( Size( kerth ) = 1 ) then if ( InfoLevel( InfoXMod ) > 1 ) then Print( "t : ", MappingGeneratorsImages(t)[2], "\n", "h : ", MappingGeneratorsImages(h)[2], "\n" ); fi; CC := PreCat1GroupByEndomorphisms( t, h ); if not IsCat1Group( CC ) then Error( "not a cat1-group" ); fi; g := Cnum; AICG := false; while ( not AICG and ( g > 0 ) ) do #? is this expensive? isocg := IsomorphismPreCat1Groups( C[g], CC ); AICG := not ( isocg = fail ); g := g-1; od; if ( AICG = false ) then Add( C, CC ); Cnum := Cnum + 1; Info( InfoXMod, 2, "C[", Cnum, "] = ", CC ); else ## maybe CC is a simpler construction than C[g] ? gens1 := GeneratorsOfGroup( Range( CC ) ); list1 := Flat( List( gens1, g -> ExtRepOfObj(g) ) ); for z in [1..Length(list1)] do if IsOddInt(z) then list1[z] := 0; fi; od; len1 := Sum( list1 ); g := g+1; Info( InfoXMod, 2, "isomorphic to C[g], g = ", g ); gens2 := GeneratorsOfGroup( Range( C[g] ) ); list2 := Flat( List( gens2, g -> ExtRepOfObj(g) ) ); for z in [1..Length(list2)] do if IsOddInt(z) then list2[z] := 0; fi; od; len2 := Sum( list2 ); Info( InfoXMod, 2, "len1 = ", len1, ", len2 = ", len2, " at [i,j,k] = ", [i,j,k] ); if ( len1 < len2 ) then C[g] := CC; Info( InfoXMod, 2, "swapping due to lengths:"); Info( InfoXMod, 2, "gens1 = ", gens1 ); Info( InfoXMod, 2, "gens2 = ", gens2 ); elif ( len1 = len2 ) then # check no. generators fixed by tail map len1 := 0; for z in gens1 do if ( Image(TailMap(CC),z) = z ) then len1 := len1 + 1; fi; od; len2 := 0; for z in gens2 do if ( Image(TailMap(CC),z) = z ) then len2 := len2 + 1; fi; od; if ( len1 < len2 ) then C[g] := CC; Info( InfoXMod, 2, "swapping due to fixed points" ); Info( InfoXMod, 2, "gens1 = ", gens1 ); Info( InfoXMod, 2, "gens2 = ", gens2 ); fi; fi; fi; fi; od; od; if ( InfoLevel( InfoXMod ) > 2 ) then Print( "\nvvvvv when i = ", i, " Cnum = ", Cnum, "\n" ); for j in [1..Cnum] do CC := C[j]; Print( "Isomorphism class ", j, "\n" ); if ( Size( Kernel( CC ) ) < 101 ) then Print( ": kernel(tail) = ", IdGroup( Kernel( CC) ), "\n" ); else Print( ": size(kernel) = ", Size( Kernel( CC ) ), "\n" ); fi; if ( Size( Range( CC ) ) < 101 ) then Print( ": range group = ", IdGroup( Range( CC ) ), "\n" ); else Print( ": range has size = ", Size( Range( CC ) ), "\n" ); fi; bdy := Boundary( CC ); kerbdy := Kernel( bdy ); if ( kerbdy <> Kernel( CC ) ) then if ( Size( kerbdy ) < 101 ) then Print( ": ker(bdy) = ", IdGroup( kerbdy ), "\n" ); else Print( ": ker(bdy) has size = ", Size( kerbdy ), "\n" ); fi; fi; Print( "\n" ); od; Print( "^^^^^ when i = ", i, " Cnum = ", Cnum, "\n" ); fi; od; ## now convert to the form required in the cat1data.g file if ( fst = 1 ) then struc := StructureDescription( gp ); PrintTo( out, "[",size,",",num,",\"",struc,"\",",egensgp,",[\n" ); fi; for j in [(Cnum0+1)..Cnum] do a := C[j]; genr := SmallGeneratingSet( Range(a) ); egenr := List( genr, g -> ExtRepOfObj(g) ); t := TailMap( a ); imt := List( gensgp, g -> Image( t, g ) ); eimt := List( imt, g -> ExtRepOfObj(g) ); h := HeadMap( a ); imh := List( gensgp, g -> Image( h, g ) ); eimh := List( imh, g -> ExtRepOfObj(g) ); AppendTo( out,"[ ",egenr,",\n ",eimt,",\n ",eimh," ],\n" ); od; if ( ist = nireps ) then Print( "Delete the final cat1-group in the size.num.out file\n" ); Print( "Edit the last line of the file to end with ] ] ] ] ]\n" ); fi; return C; end ); ############################################################################## ## #M MakeAllCat1DataGroups . . . . . . . . . . . . . . . . . for three positive integers ## InstallMethod( MakeAllCat1DataGroups, "all cat1-groups of a chosen order", true, [ IsPosInt, IsPosInt, IsPosInt ], 0, function( n, fst, lst ) local sgp, gensgp, egensgp, all, len, i, a, t, h, gens, fam, genr, egenr, num, j, k, imt, eimt, imh, eimh, path, name, out, struc; path := DirectoriesPackageLibrary("xmod","lib")[1]; name := Concatenation( String(n), ".out" ); out := Filename( path, name ); num := NumberSmallGroups( n ); if ( lst > num ) then lst := num; fi; for j in [fst..lst] do sgp := SmallGroup( n, j ); struc := StructureDescription( sgp ); Print( struc, "\n" ); if IsPermGroup( sgp ) then Print( "#I only works for PcGroups at present" ); gensgp := GeneratorsOfGroup( sgp ); AppendTo( out, "[",n,",",j,",\"",struc,"\",",gensgp,",[\n" ); else gensgp := SmallGeneratingSet( sgp ); fam := FamilyObj( gensgp[1] ); egensgp := List( gensgp, g -> ExtRepOfObj(g) ); Print( "small group with n = ", n, ", j = ", j, "\n" ); Print( "representatives of isomorphism classes of subgroups:\n" ); if ( j = fst ) then PrintTo( out, "[",n,",",j,",\"",struc,"\",",egensgp,",[\n" ); else AppendTo(out, "[",n,",",j,",\"",struc,"\",",egensgp,",[\n" ); fi; all := AllCat1DataGroupsBasic( sgp ); len := Length( all ); if ( (len = 1) or ( (len = 2) and IsCommutative( sgp ) ) ) then AppendTo( out, " ] ],\n" ); fi; if IsCommutative( sgp ) then k := 2; else k := 1; fi; for i in [k..(len-1)] do a := all[i]; genr := SmallGeneratingSet( Range(a) ); egenr := List( genr, g -> ExtRepOfObj(g) ); t := TailMap( a ); imt := List( gensgp, g -> Image( t, g ) ); eimt := List( imt, g -> ExtRepOfObj(g) ); h := HeadMap( a ); imh := List( gensgp, g -> Image( h, g ) ); eimh := List( imh, g -> ExtRepOfObj(g) ); AppendTo( out,"[ ",egenr,",\n ",eimt,",\n ",eimh," ]" ); if ( i < len-1 ) then AppendTo( out, ",\n" ); else AppendTo( out, " ] ],\n" ); fi; od; fi; od; return all; end ); ############################################################################## ## the following was placed in removed.gi, then brought back here 27/09/12 ## ############################################################################## ############################################################################## ## #M EndomorphismClassObj( <nat>, <iso>, <aut>, <conj> ) . . . . . make a class ## InstallMethod( EndomorphismClassObj, "generic method for an endomorphism class", true, [ IsGroupHomomorphism, IsGroupHomomorphism, IsGroupOfAutomorphisms, IsList ], 0, function( nat, iso, aut, conj ) local filter, fam, class; fam := FamilyObj( [ nat, iso, aut, conj ] ); filter := IsEndomorphismClassObj; class := rec(); ObjectifyWithAttributes( class, NewType( fam, filter ), IsEndomorphismClass, true, EndoClassNaturalHom, nat, EndoClassIsomorphism, iso, EndoClassAutoGroup, aut, EndoClassConjugators, conj ); return class; end ); ############################################################################# ## #M Display . . . . . . . . . . . . . . . . . . . . . for endomorphism classes ## InstallMethod( Display, "generic method for endomorphism classes", true, [ IsEndomorphismClassObj ], 0, function( class ) Print( "class of group endomorphisms with\n" ); Print( "natural hom: " ); ViewObj( EndoClassNaturalHom( class ) ); Print( "\n" ); Print( "isomorphism: " ); ViewObj( EndoClassIsomorphism( class ) ); Print( "\n" ); Print( "autogp gens: ", GeneratorsOfGroup( EndoClassAutoGroup( class ) ), "\n" ); Print( "conjugators: ", EndoClassConjugators( class ), "\n" ); end ); ############################################################################# ## #M ZeroEndomorphismClass( <G> ) ## InstallMethod( ZeroEndomorphismClass, "generic method for a group", true, [ IsGroup ], 0, function( G ) local Q, nat, iso, aut, conj, idgp; Q := Group( One( G ) ); nat := MappingToOne( G, Q ); iso := IdentityMapping( Q ); aut := Group( iso ); SetIsAutomorphismGroup( aut, true ); conj := [ One( G ) ]; return EndomorphismClassObj( nat, iso, aut, conj ); end ); ############################################################################# ## #M AutomorphismClass( <G> ) ## InstallMethod( AutomorphismClass, "generic method for a group", true, [ IsGroup ], 0, function( G ) local iso, aut, conj; aut := AutomorphismGroup( G ); iso := InclusionMappingGroups( G, G ); conj := [ One( G ) ]; return EndomorphismClassObj( iso, iso, aut, conj ); end ); ############################################################################# ## #M NontrivialEndomorphismClasses( <G> ) ## InstallMethod( NontrivialEndomorphismClasses, "generic method for a group", true, [ IsGroup ], 0, function( G ) local nargs, valid, case, switch, oldcase, normG, rcosG, N, nnum, natG, quotG, genG, oneG, Qnum, ccs, reps, cnum, Q, R, iso, L, im, phi, nat, proj, comp, normal, cosets, conj, Cnum, g, gim, zero, i, j, k, l, Lnum, aut, idgp, Ecl, Enum, classes, class, name, ok; genG := GeneratorsOfGroup( G ); oneG := One( G ); idgp := Subgroup( G, [ One(G) ] ); # determine non-monomorphic endomorphisms by kernel normG := NormalSubgroups( G ); nnum := Length( normG ); ccs := ConjugacyClassesSubgroups( G ); cnum :=Length( ccs ); reps := List( ccs, c -> Representative( c ) ); rcosG := List( normG, N -> RightCosets( G, N ) ); natG := List( normG, N -> NaturalHomomorphismByNormalSubgroup( G, N ) ); quotG := List( natG, n -> Image( n ) ); normal := List( reps, R -> ( Normalizer( G, R ) = G ) ); classes := [ ]; for i in [2..(nnum-1)] do N := normG[i]; Q := quotG[i]; proj := natG[i]; aut := AutomorphismGroup( Q ); for j in [2..(cnum-1)] do R := reps[j]; ok := ( Intersection( N, R ) = idgp ); iso := IsomorphismGroups( Q, R ); if not ( iso = fail ) then # (unnecessary?) check that this gives a homomorphism comp := CompositionMapping( iso, proj ); im := List( genG, x -> Image( comp, x ) ); phi := GroupHomomorphismByImages( G, R, genG, im ); if not IsGroupHomomorphism( phi ) then Error( "phi not a homomorphism" ); fi; if not normal[j] then cosets := RightCosets( G, Normalizer( G, R ) ); conj := List( cosets, c -> Representative( c ) ); else conj := [ oneG ]; fi; class := EndomorphismClassObj( proj, iso, aut, conj ); Add( classes, class ); fi; od; od; return classes; end ); ############################################################################# ## #M NonIntersectingEndomorphismClasses( <G> ) ## InstallMethod( NonIntersectingEndomorphismClasses, "generic method for a group", true, [ IsGroup ], 0, function( G ) local nargs, valid, case, switch, oldcase, normG, rcosG, N, nnum, natG, quotG, genG, oneG, Qnum, ccs, reps, cnum, Q, R, iso, L, im, phi, nat, proj, comp, normal, cosets, conj, Cnum, g, gim, zero, i, j, k, l, Lnum, aut, idgp, Ecl, Enum, classes, class, name, ok; genG := GeneratorsOfGroup( G ); oneG := One( G ); idgp := Subgroup( G, [ One(G) ] ); # determine non-monomorphic endomorphisms by kernel normG := NormalSubgroups( G ); nnum := Length( normG ); ccs := ConjugacyClassesSubgroups( G ); cnum :=Length( ccs ); reps := List( ccs, c -> Representative( c ) ); rcosG := List( normG, N -> RightCosets( G, N ) ); natG := List( normG, N -> NaturalHomomorphismByNormalSubgroup( G, N ) ); quotG := List( natG, n -> Image( n ) ); normal := List( reps, R -> ( Normalizer( G, R ) = G ) ); classes := [ ]; for i in [2..(nnum-1)] do N := normG[i]; Q := quotG[i]; proj := natG[i]; aut := AutomorphismGroup( Q ); for j in [2..(cnum-1)] do R := reps[j]; ok := ( Intersection( N, R ) = idgp ); if ok then iso := IsomorphismGroups( Q, R ); fi; if ( ok and not ( iso = fail ) ) then # (unnecessary?) check that this gives a homomorphism comp := CompositionMapping( iso, proj ); im := List( genG, x -> Image( comp, x ) ); phi := GroupHomomorphismByImages( G, R, genG, im ); if not IsGroupHomomorphism( phi ) then Error( "phi not a homomorphism" ); fi; if not normal[j] then cosets := RightCosets( G, Normalizer( G, R ) ); conj := List( cosets, c -> Representative( c ) ); else conj := [ oneG ]; fi; class := EndomorphismClassObj( proj, iso, aut, conj ); Add( classes, class ); fi; od; od; return classes; end ); ############################################################################## ## #F EndomorphismClasses finds all homomorphisms G -> G ## InstallGlobalFunction( EndomorphismClasses, function( arg ) local nargs, valid, G, case, classes, auts, ends, zero, disj; nargs := Length( arg ); G := arg[1]; valid := ( IsGroup( G ) and ( nargs = 2 ) and ( arg[2] in [0..3] ) ); if not valid then Print( "\nUsage: EndomorphismClasses( G [, case] );\n" ); Print( " choose case = 1 to include automorphisms & zero,\n" ); Print( "default case = 2 to exclude automorphisms & zero,\n" ); Print( " case = 3 when N meet H trivial,\n" ); return fail; fi; if ( Length( arg ) = 1 ) then case := 2; else case := arg[2]; fi; ends := NontrivialEndomorphismClasses( G ); if ( case = 1 ) then zero := ZeroEndomorphismClass( G ); auts := AutomorphismClass( G ); fi; if ( case = 2 ) then classes := ends; elif ( case = 1 ) then classes := Concatenation( [auts], ends, [zero] ); else classes := NonIntersectingEndomorphismClasses( G ); fi; return classes; end ); ############################################################################# ## #M EndomorphismImages finds all homomorphisms G -> G by converting ## EndomorphismClasses into a list of genimages ## InstallMethod( EndomorphismImages, "generic method for a list of endomorphism classes", true, [ IsList ], 0, function( classes ) local clnum, G, genG, Q, autos, rho, psi, phi, L, Lnum, LR, k, l, im, g, gim, i, c, nat, iso, aut, conj, cjnum, comp, R; if ( ( classes = [] ) or not IsEndomorphismClass( classes[1] ) ) then Error( "usage: EndomorphismImages( <list of endo classes> );" ); fi; c := classes[1]; nat := EndoClassNaturalHom( c ); G := Source( nat ); genG := GeneratorsOfGroup( G ); clnum := Length( classes ); L := [ ]; for i in [1..clnum] do c := classes[i]; nat := EndoClassNaturalHom( c ); iso := EndoClassIsomorphism( c ); aut := EndoClassAutoGroup( c ); conj := EndoClassConjugators( c ); comp := CompositionMapping( iso, nat ); R := Image( comp ); cjnum := Length( conj ); Q := Image( nat ); autos := Elements( aut ); LR := [ ]; for k in [ 1..Length( autos ) ] do rho := autos[k]; psi := nat * rho * iso; im := List( genG, x -> Image( psi, x ) ); Add( LR, im ); od; Lnum := Length( LR ); for k in [2..cjnum] do g := conj[k]; for l in [1..Lnum] do im := LR[l]; gim := List( im, x -> x^g ); Add( LR, gim ); od; od; L := Concatenation( L, LR ); od; return L; end ); ############################################################################### ## #M IdempotentImages finds all homomorphisms h : G -> G with h^2 = h ## by converting a list of endomorphism classes ## into a list of genimages, using the notation ## of Alp/Wensley IJAC 2000, section 4.4. ## InstallMethod( IdempotentImages, "generic method for a list of endomorphism classes", true, [ IsList ], 0, function( classes ) local R, genR, Q0, Q, alpha0, psi, phi, L, L1, L2, k, im, im2, psi2, c, cim, i, cl, nu, theta, autQ, conj, cjnum; if ( classes = [] ) then return [ ]; fi; if not IsEndomorphismClass( classes[1] ) then Error( "usage: EndomorphismImages( <list of endo classes> );" ); fi; cl := classes[1]; nu := EndoClassNaturalHom( cl ); R := Source( nu ); genR := GeneratorsOfGroup( R ); L := [ ]; for cl in classes do nu := EndoClassNaturalHom( cl ); theta := EndoClassIsomorphism( cl ); autQ := EndoClassAutoGroup( cl ); conj := EndoClassConjugators( cl ); psi := CompositionMapping( theta, nu ); Q := Image( psi ); Q0 := Image( nu ); L1 := [ ]; for alpha0 in autQ do psi := nu * alpha0 * theta; im := List( genR, x -> Image( psi, x ) ); Add( L1, im ); od; L2 := [ ]; for c in conj do for im in L1 do cim := List( im, x -> x^c ); psi2 := GroupHomomorphismByImages( R, R, genR, cim ); im2 := List( cim, x -> Image( psi2, x ) ); if ( cim = im2 ) then Add( L2, cim ); fi; od; od; L := Concatenation( L, L2 ); od; return L; end ); ############################################################################# ## #E cat1data.gi . . . . . . . . . . . . . . . . . . . . . . . . . . ends here