############################################################################# ## #W subgroups.gi POLENTA package Bjoern Assmann ## ## Methods for the calculation of ## certain subgroups of matrix groups ## #Y 2004 ##
############################################################################# ##
POL_Group := function( subGens, G ) if Length( subGens ) = 0then
return TrivialSubgroup( G ); else
return Group( subGens ); fi; end;
############################################################################# ## #F POL_TriangNSGFI_NonAbelianPRMGroup( arg ) ## ## ## ## IN: arg[1] ..... G is an non-abelian polycyclic rational matrix group ## arg[2] ..... optional prime p ## ## OUT: Normal subgroup of finite index, ## actually the p-congruence subgroup ##
InstallGlobalFunction( POL_TriangNSGFI_NonAbelianPRMGroup , function( arg )
local p, d, gens_p,G, bound_derivedLength, pcgs_I_p, gens_K_p,
comSeries, gens_K_p_m, gens, gens_K_p_mutableCopy, pcgs,
gensOfBlockAction, pcgs_nue_K_p, pcgs_GU, gens_U_p, pcgs_U_p,
recordSeries, radSeries, isTriang, H; # setup
G := arg[1];
gens := GeneratorsOfGroup( G );
d := Length(gens[1][1]);
# determine an admissible prime or take the wished one if Length( arg ) = 2then
p := arg[2]; else
p := DetermineAdmissiblePrime(gens); fi;
Info( InfoPolenta, 1, "Chosen admissible prime: " , p );
Info( InfoPolenta, 1, " " );
# calculate the gens of the group phi_p(<gens>) where phi_p is # natural homomorphism to GL(d,p)
gens_p := InducedByField( gens, GF(p) );
# determine an upper bound for the derived length of G
bound_derivedLength := d+2;
# finite part
Info( InfoPolenta, 1,"Determine a constructive polycyclic sequence\n", " for the image under the p-congruence homomorphism ..." );
pcgs_I_p := CPCS_finite_word( gens_p, bound_derivedLength ); if pcgs_I_p = fail then return fail; fi;
Info(InfoPolenta,1,"finished.");
Info( InfoPolenta, 1, "Finite image has relative orders ",
RelativeOrdersPcgs_finite( pcgs_I_p ), "." );
Info( InfoPolenta, 1, " " );
# compute the normal the subgroup gens. for the kernel of phi_p
Info( InfoPolenta, 1,"Compute normal subgroup generators for the kernel\n", " of the p-congruence homomorphism ...");
gens_K_p := POL_NormalSubgroupGeneratorsOfK_p( pcgs_I_p, gens );
gens_K_p := Filtered( gens_K_p, x -> not x = IdentityMat(d) );
Info( InfoPolenta, 1,"finished.");
# radical series
Info( InfoPolenta, 1, "Compute the radical series ...");
gens_K_p_mutableCopy := CopyMatrixList( gens_K_p );
recordSeries := POL_RadicalSeriesNormalGensFullData( gens,
gens_K_p_mutableCopy,
d );
if recordSeries=fail then return fail; fi;
radSeries := recordSeries.sers;
Info( InfoPolenta, 1,"finished.");
Info( InfoPolenta, 1, "The radical series has length ",
Length( radSeries ), "." );
Info( InfoPolenta, 2, "The radical series is" );
Info( InfoPolenta, 2, radSeries );
Info( InfoPolenta, 1, " " );
# test if G is unipotent by abelian
isTriang := POL_TestIsUnipotenByAbelianGroupByRadSeries( gens, radSeries ); if isTriang then
return G; fi;
# compositions series
Info( InfoPolenta, 1, "Compute the composition series ...");
comSeries := POL_CompositionSeriesByRadicalSeries( gens_K_p_mutableCopy,
d,
recordSeries.sersFullData, 1 ); if comSeries=fail then return fail; fi;
Info( InfoPolenta, 1,"finished.");
Info( InfoPolenta, 1, "The composition series has length ",
Length( comSeries ), "." );
Info( InfoPolenta, 2, "The composition series is" );
Info( InfoPolenta, 2, comSeries );
Info( InfoPolenta, 1, " " );
# induce K_p to the factors of the composition series
gensOfBlockAction := POL_InducedActionToSeries(gens_K_p, comSeries);
# let nue be the homomorphism which induces the action of K_p to # the factors of the series
Info( InfoPolenta, 1, "Compute a constructive polycyclic sequence\n", " for the induced action of the kernel to the composition series ...");
pcgs_nue_K_p := CPCS_AbelianSSBlocks_ClosedUnderConj( gens_K_p,
gens, comSeries ); if pcgs_nue_K_p = fail then return fail; fi;
Info(InfoPolenta,1,"finished.");
############################################################################# ## #F POL_TriangNSGFI_PRMGroup( arg ) ## ## arg[1] = G is a rational polycyclic rational matrix group ##
InstallGlobalFunction( POL_TriangNSGFI_PRMGroup , function( arg )
local G;
G := arg[1]; if IsAbelian( G ) then
return G; else if IsBound( arg[2] ) then
return POL_TriangNSGFI_NonAbelianPRMGroup( arg[1], arg[2] ); else
return POL_TriangNSGFI_NonAbelianPRMGroup( G ); fi; fi; end );
# this code has to be reviewed. In the current form we can only assure, # that it returns normal subgroup generators for K_p. ############################################################################# ## #M TriangNormalSubgroupFiniteInd( G ) ## ## G is a matrix group over the Rationals. ## Returned is triangularizable normal subgroup of finite index ## ## #InstallMethod( TriangNormalSubgroupFiniteInd, "for polycyclic matrix groups", # true, [ IsMatrixGroup ], 0, #function( G ) # local test; # test := POL_IsMatGroupOverFiniteField( G ); # if IsBool( test ) then # TryNextMethod(); # elif test = 0 then # return POL_TriangNSGFI_PRMGroup(G ); # else # TryNextMethod(); # fi; #end) ; # #InstallOtherMethod( TriangNormalSubgroupFiniteInd, # "for polycyclic matrix groups", true, # [ IsMatrixGroup, IsInt], 0, #function( G, p ) # local test; # test := POL_IsMatGroupOverFiniteField( G ); # if IsBool( test ) then # TryNextMethod(); # elif test = 0 then # if not IsPrime(p) then # Print( "Second argument must be a prime number.\n" ); # return fail; # fi; # return POL_TriangNSGFI_PRMGroup(G ); # else # TryNextMethod(); # fi; # #end );
############################################################################# ## #M SubgroupsUnipotentByAbelianByFinite( G ) ## ## G is a matrix group over the Rationals. ## Returned is triangularizable normal subgroup K of finite index ## and an unipotent normal subgroup U of K such that K/U is abelian. ##
InstallMethod( SubgroupsUnipotentByAbelianByFinite, "for polycyclic matrix groups (Polenta)",
true, [ IsMatrixGroup ], 0, function( G )
local cpcs, U_p, K_p; if not IsRationalMatrixGroup( G ) then
TryNextMethod( ); fi;
cpcs := CPCS_PRMGroup( G ); if cpcs = fail then return fail; fi; if IsAbelian( G ) then
U_p := cpcs.pcgs_U_p.pcs;
return rec( T := G , U := POL_Group( U_p, G )); else
U_p := cpcs.pcgs_U_p.pcs; # check if G is triangularizable if Length( cpcs.pcgs_GU.pcgs_I_p.gens ) = 0then #G triangularizable
return rec( T := G, U := POL_Group( U_p, G )); else #G not triangularizable
K_p := cpcs.pcgs_GU.preImgsNue;
K_p := Concatenation( K_p, U_p );
return rec( T := POL_Group( K_p, G ), U := POL_Group( U_p, G )); fi; fi; end );
InstallOtherMethod( SubgroupsUnipotentByAbelianByFinite , "for polycyclic matrix groups (Polenta)", true,
[ IsMatrixGroup, IsInt], 0, function( G,p )
local cpcs, U_p, K_p; if not IsRationalMatrixGroup( G ) then
TryNextMethod( ); fi;
cpcs := CPCS_PRMGroup( G,p ); if cpcs = fail then return fail; fi; if IsAbelian( G ) then
U_p := cpcs.pcgs_U_p.pcs;
return rec( T := G , U := POL_Group( U_p, G )); else
U_p := cpcs.pcgs_U_p.pcs; # check if G is triangularizable if Length( cpcs.pcgs_GU.pcgs_I_p.gens ) = 0then #G triangularizable
return rec( T := G, U := POL_Group( U_p, G )); else #G not triangularizable
K_p := cpcs.pcgs_GU.preImgsNue;
K_p := Concatenation( K_p, U_p );
return rec( T := POL_Group( K_p, G ), U := POL_Group( U_p, G )); fi; fi; end );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.