|
#############################################################################
##
#A max.gi Cryst library Bettina Eick
#A Franz G"ahler
#A Werner Nickel
##
#Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel
##
## Routines for the determination of maximal subgroups of CrystGroups
##
#############################################################################
##
#F CoefficientsMod( base, v ) . . . . . . . coefficients of v in factorspace
##
CoefficientsMod := function( base, v )
local head, i, zero, coeff, w, j, h;
if not IsBound( base.fullbase ) then
base.fullbase := Concatenation( base.subspace, base.factorspace );
fi;
if not IsBound( base.depth ) then
head := [];
for i in [1..Length( base.fullbase )] do
head[i] := PositionNonZero( base.fullbase[i] );
od;
base.depth := head;
fi;
zero := base.fullbase[1] * Zero( base.field );
coeff := ShallowCopy( zero );
w := v;
while w <> zero do
j := PositionNonZero( w );
h := Position( base.depth, j );
coeff[h] := coeff[h] + w[j];
w := w - w[j] * base.fullbase[h];
od;
return coeff{[Length(base.subspace)+1..Length(base.fullbase)]};
end;
#############################################################################
##
#F InducedMatrix( base, mat ) . . . . . . . . induced action of mat on base
##
InducedMatrix := function( base, mat )
local ind, n, l, b, v, s;
ind := [];
n := Length(base.fullbase);
l := Length(base.subspace);
for b in base.factorspace do
v := b * mat;
s := SolutionMat( base.fullbase, v );
Add( ind, s{[l+1..n]} );
od;
return ind;
end;
#############################################################################
##
#F TriangularizeMatVector . . . . . . . . . . compute triangularized matrix
##
## This function computes the upper triangular form of the integer
## matrix M via elementary row operations and performs the same
## operations on the (column) vector b.
##
## The function works in place.
##
TriangularizeMatVector := function( M, b )
local zero, c, r, i, t;
zero := M[1][1] * 0;
c := 1; r := 1;
while c <= Length(M[1]) and r <= Length(M) do
i := r; while i <= Length(M) and M[i][c] = zero do i := i+1; od;
if i <= Length(M) then
t := b[r]; b[r] := b[i]; b[i] := t;
t := M[r]; M[r] := M[i]; M[i] := t;
b[r] := b[r] / M[r][c];
M[r] := M[r] / M[r][c];
for i in [1..r-1] do
b[i] := b[i] - b[r] * M[i][c];
M[i] := ShallowCopy( M[i] );
AddCoeffs( M[i], M[r], -M[i][c] );
od;
for i in [r+1..Length(M)] do
b[i] := b[i] - b[r] * M[i][c];
M[i] := ShallowCopy( M[i] );
AddCoeffs( M[i], M[r], -M[i][c] );
od;
r := r+1;
fi;
c := c+1;
od;
for i in Reversed( [r..Length(M)] ) do
Unbind( M[i] );
od;
end;
#############################################################################
##
#F SolutionInhomEquations . . . solve an inhomogeneous system of equations
##
## This function computes the set of solutions of the equation
##
## X * M = b.
##
SolutionInhomEquations := function( M, b )
local zero, one, i, c, d, r, heads, S, v;
zero := M[1][1] * 0;
one := M[1][1] ^ 0;
M := MutableTransposedMat( M );
d := Length(M[1]);
b := ShallowCopy( b );
TriangularizeMatVector( M, b );
for i in [Length(M)+1..Length(b)] do
if b[i] <> zero then return false; fi;
od;
# determine the null space
c := 1; r := 1; heads := []; S := [];
while r <= Length(M) and c <= d do
while c <= d and M[r][c] = zero do
v := ShallowCopy( zero * [1..d] );
v{heads} := M{[1..r-1]}[c]; v[c] := -one;
Add( S, v );
c := c+1;
od;
if c <= d then
Add( heads, c ); c := c+1; r := r+1;
fi;
od;
while c <= d do
v := ShallowCopy( zero * [1..d] );
v{heads} := M{[1..r-1]}[c]; v[c] := -one;
Add( S, v );
c := c+1;
od;
# one particular solution
v := ShallowCopy( zero * [1..d] );
v{heads} := b{[1..Length(M)]};
if Length(S) > 0 then TriangulizeMat( S ); fi;
return rec( basis := S, translation := v );
end;
#############################################################################
##
#F SolutionHomEquations . . . . . . solve a homogeneous system of equations
##
## This function computes the set of solutions of the equation
##
## X * M = 0.
##
SolutionHomEquations := function( M )
return SolutionInhomEquations( M, Zero(Field(M[1][1]))*[1..Length(M[1])]);
end;
#############################################################################
##
#F MatJacobianMatrix( G, mats )
##
MatJacobianMatrix := function( G, mats )
local gens, rels,
J, D, # the result, the one `column' of J
imats, # list of inverted matrices
d, # dimension of matrices
j, k, l, # loop variables
r, # run through the relators
h, p; # generator in r, its position in G.generators
gens := GeneratorsOfGroup( FreeGroupOfFpGroup( G ) );
rels := RelatorsOfFpGroup( G );
if Length(gens) = 0 then return []; fi;
d := Length( mats[1] );
imats := List( mats, m->m^-1 );
J := List( [1..d*Length(gens)], k->[] );
for j in [1..Length(rels)] do
r := rels[j];
D := NullMat( d*Length(gens), d );
for k in [1..Length(r)] do
h := Subword( r,k,k );
p := Position( gens, h );
if not IsBool( p ) then
D := D * mats[p];
for l in [1..d] do
D[(p-1)*d+l][l] := D[(p-1)*d+l][l] + 1;
od;
else
p := Position( gens, h^-1 );
for l in [1..d] do
D[(p-1)*d+l][l] := D[(p-1)*d+l][l] - 1;
od;
D := D * imats[p];
fi;
J{[1..Length(gens)*d]}{[(j-1)*d+1..j*d]} := D;
od;
od;
return J;
end;
#############################################################################
##
#F OneCoboundariesSG( <G>, <mats> ) . . . . . . . . . . . . . . B^1( G, M )
##
OneCoboundariesSG := function( G, mats )
local d, I, S, i;
d := Length( mats[1] );
I := IdentityMat( d );
if Length(mats) <> Length( GeneratorsOfGroup(G) ) then
return Error( "As many matrices as generators expected" );
fi;
S := List( [1..d], i->[] );
for i in [1..Length(mats)] do
S{[1..d]}{[(i-1)*d+1..i*d]} := mats[i] - I;
od;
TriangulizeMat( S );
return S;
end;
#############################################################################
##
#F OneCocyclesVector( <G>, <mats>, <b> ) . . . . . . . . . . . . . . . . . .
##
OneCocyclesVector := function( G, mats, b )
local J, L;
J := MatJacobianMatrix( G, mats );
##
## b needs to be inverted for the following reason (I don't know how to
## say this better without setting up a lot of notation.
##
## b was computed by CocycleInfo() by evaluating the relators of the
## group. In solving the system X * J = b we need to find all tuples of
## elements with the following property: If we modify the generating
## sequence with such a tuple by multiplying from the rigth, then the
## relators on the modified generators have to evaluate to the identity.
## For example, if we have the relation [g2,g1] = m, then [g2*y,g1*x]
## should be 1. Therefore, x and y should be chosen such that after
## collection we have [g2,g1] m^-1 = m m^-1 = 1. Hence we need to
## invert b.
b := -Concatenation( b );
L := SolutionInhomEquations( J, b );
return L;
end;
#############################################################################
##
#F OneCocyclesSG( <G>, <mats> ) . . . . . . . . . . . . . . . . Z^1( G, M )
##
OneCocyclesSG := function( G, mats )
local J, L;
J := MatJacobianMatrix( G, mats );
L := SolutionHomEquations( J ).basis;
return L;
end;
#############################################################################
##
#F OneCohomology( <G>, <mats> ) . . . . . . . . . . . . . . . . H^1( G, M )
##
OneCohomologySG := function( G, mats )
return rec( cocycles := OneCocyclesSG( G, mats ),
coboundaries := OneCoboundariesSG( G, mats ) );
end;
#############################################################################
##
#F ListOneCohomology( <H> ) . . . . . . . . . . . . . . . . . . . . list H^1
##
## Run through the triangularized basis of Z and find those head
## entries which do not occur in the basis of B. For each such
## vector in the basis of Z we need to run through the coefficients
## 0..p-1.
##
ListOneCohomology := function( H )
local Z, B, C, zero, coeffs, h, j, i;
Z := H.cocycles;
B := H.coboundaries;
if Length(Z) = 0 then return B; fi;
C := AsSSortedList( Field( Z[1][1] ) );
zero := Z[1][1]*0;
coeffs := [];
h := 1; j := 1;
for i in [1..Length(Z)] do
while Z[i][h] = zero do h := h+1; od;
if j > Length(B) or B[j][h] = zero then
coeffs[i] := C;
else
coeffs[i] := [ zero ]; j := j+1;
fi;
od;
return List( Cartesian( coeffs ), t->t*Z );
end;
#############################################################################
##
#F ComplementsSG . . . . . . . . . . . . compute complements up to conjugacy
##
ComplementsSG := function( G, mats, b )
local Z, B, C, d, n;
if Length(GeneratorsOfGroup(G)) = 0 then return [ [] ]; fi;
Z := OneCocyclesVector( G, mats, b );
if Z = false then return []; fi;
B := OneCoboundariesSG( G, mats );
C := ListOneCohomology(
rec( cocycles := Z.basis,
coboundaries := B ) );
C := List( C, c->c + Z.translation );
d := Length( mats[1] );
n := Length(GeneratorsOfGroup(G));
return List( C, c->List( [0..n-1], x->c{ [1..d] + x*d } ) );
end;
#############################################################################
##
#F MaximalSubgroupRepsTG( < S > ) . .translationengleiche maximal subgroups
##
## This function computes conjugacy class representatives of the maximal
## subgroups of $S$ which contain $T$. Note that this function may be
## slow, if $S$ is not solvable.
##
MaximalSubgroupRepsTG := function( S )
local d, P, N, T, Sgens, A, max, ind, l, i, gens, g, exp, h, j,
trans, sub;
d := DimensionOfMatrixGroup( S ) - 1;
P := PointGroup( S );
N := NiceObject( P );
# catch a trivial case
if Size( N ) = 1 then
return [];
fi;
# compute the translation generators
T := TranslationBasis( S );
trans := List( T, x -> IdentityMat( d+1 ) );
for i in [1..Length(T)] do
trans[i][d+1]{[1..d]} := T[i];
od;
# first the solvable case
if IsSolvableGroup( N ) then
A := GroupByPcgs( Pcgs( N ) );
Sgens := List( AsList( Pcgs( N ) ),
x -> ImagesRepresentative( NiceToCryst( P ), x ) );
# compute maximal subgroups in ag group
max := ShallowCopy( MaximalSubgroupClassReps( A ) );
# compute preimages in space group and construct subgroups
for i in [1..Length(max)] do
gens := [];
for g in GeneratorsOfGroup( max[i] ) do
exp := ExponentsOfPcElement( Pcgs( A ), g );
h := IdentityMat( d+1 );
for j in [1..Length(exp)] do
h := h * Sgens[j]^exp[j];
od;
Add( gens, h );
od;
Append( gens, trans );
sub := SubgroupNC( S, gens );
AddTranslationBasis( sub, T );
SetIndexInParent( sub, IndexInParent( max[i] ) );
max[i] := sub;
od;
return max;
fi;
# now the non-solvable case
max := List( ConjugacyClassesMaximalSubgroups( N ), Representative );
ind := List( max, x -> Index( N, x ) );
# go back to S, and construct the subgroups
for i in [1..Length(max)] do
gens := List( GeneratorsOfGroup( max[i] ),
x -> ImagesRepresentative( NiceToCryst( P ), x ) );
Append( gens, trans );
sub := SubgroupNC( S, gens );
AddTranslationBasis( sub, T );
SetIndexInParent( sub, ind[i] );
max[i] := sub;
od;
return max;
end;
#############################################################################
##
#F CocycleInfo( <S> ) . . . . . . . . . . .information about extension type
##
CocycleInfo := function( S )
local P, iso, F, d, gens, mats, coc, rel, new;
P := PointGroup( S );
iso := IsomorphismFpGroup( P );
F := Image( iso );
d := DimensionOfMatrixGroup( S ) - 1;
gens := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) );
mats := iso!.preimagesInAffineCrystGroup;
coc := [];
for rel in RelatorsOfFpGroup( F ) do
new := MappedWord( rel, gens, mats );
Add( coc, new[d+1]{[1..d]} );
od;
return coc;
end;
#############################################################################
##
#M CocVecs( <S> ) . . Cocycles of extension of point group with translations
##
InstallMethod( CocVecs, true, [ IsAffineCrystGroupOnRight ], 0,
function( S )
return ReducedLatticeBasis( CocycleInfo( S ) );
end );
InstallMethod( CocVecs, true, [ IsAffineCrystGroupOnLeft ], 0,
function( S )
return CocVecs( TransposedMatrixGroup( S ) );
end );
#############################################################################
##
#F SimpleGenerators( d, gens ) . . . . . . . . . . . simplify the generators
##
SimpleGenerators := function( d, gens )
local I, new, g, trans, t, m;
I := IdentityMat( d );
new := [];
trans := [];
for g in gens do
if g{[1..d]}{[1..d]} = I then
Add( trans, g[d+1]{[1..d]} );
else
Add( new, g );
fi;
od;
trans := ReducedLatticeBasis( trans );
# add the new translation generators
for t in trans do
m := IdentityMat( d+1 );
m[d+1]{[1..d]} := t;
Add( new, m );
od;
return [ new, trans ];
end;
#############################################################################
##
#F MaximalSubgroupRepsKG( < G >, <ps> ) . .klassengleiche maximal subgroups
##
## This function computes represenatives of the conjugacy classes of maximal
## subgroups of $G$ which have $p$-power index for some $p$ in the list $ps$
## and do not contain $T$.
## In the case that $G$ is solvable it is more efficient to use the function
## 'MaximalSubgroupSG' and filter the corresponding maximal subgroups.
##
MaximalSubgroupRepsKG := function( G, primes )
local P, iso, pres, coc, rep, d, n, maximals, p, field,
repp, cocp, mods, sub, F, hom, cocin, repin, comp, c, modu,
modgens, powers, vec, elm, basis, cocpre, gens, i, j, h,
base, primeslist, Ggens, T, trans;
# check argument
if IsInt( primes ) then
primeslist := [primes];
else
primeslist := primes;
fi;
T := TranslationBasis( G );
n := Length( T );
# extract the point group
P := PointGroup( G );
iso := IsomorphismFpGroup( P );
Ggens := iso!.preimagesInAffineCrystGroup;
if not IsStandardAffineCrystGroup( G ) then
Ggens := List ( Ggens, x -> G!.lconj * x * G!.rconj );
fi;
pres := Image( iso );
rep := List( Ggens, x -> x{[1..n]}{[1..n]} );
coc := CocycleInfo( G );
if not IsEmpty( coc ) then coc := coc * T^-1; fi;
d := DimensionOfMatrixGroup( G ) - 1;
trans := List( T, x -> IdentityMat( d+1 ) );
for i in [1..n] do
trans[i][d+1][i] := 1;
od;
# view them as matrices over GF(p)
maximals := [];
for p in primeslist do
field := GF(p);
repp := List( rep, x -> x * One( field ) );
cocp := List( coc, x -> x * One( field ) );
modu := GModuleByMats( repp, d, field );
mods := MTX.BasesMaximalSubmodules( modu );
powers:= List( trans, x -> x^p );
# compute induced operation on T/maxmod and induced cocycle
for sub in mods do
# compute group of translations of maximal subgroup
modgens := [];
for vec in sub do
elm := One( G );
for j in [1..Length( vec )] do
elm := elm * trans[j]^IntFFE(vec[j]);
od;
Add( modgens, elm );
od;
Append( modgens, powers );
# compute quotient space
base := BaseSteinitzVectors( IdentityMat( n, field ), sub );
TriangulizeMat(base.factorspace);
base.field := field;
cocin := List( cocp, x -> CoefficientsMod( base, x ) );
repin := List( repp, x -> InducedMatrix( base, x ) );
# use complement routine
comp := ComplementsSG( pres, repin, cocin );
# compute generators of G corresponding to complements
for i in [1..Length( comp )] do
cocpre := List( comp[i], x -> x * base.factorspace );
gens := [];
for j in [1..Length( cocpre )] do
elm := Ggens[j];
for h in [1..Length( cocpre[j] )] do
elm := elm*trans[h]^IntFFE(cocpre[j][h]);
od;
Add( gens, elm );
od;
# append generators of group of translations
Append( gens, modgens );
# conjugate generators if necessary
if not IsStandardAffineCrystGroup( G ) then
for j in [1..Length(gens)] do
gens[j] := G!.rconj * gens[j] * G!.lconj;
od;
fi;
# construct subgroup and append index
gens := SimpleGenerators( d, gens );
comp[i] := SubgroupNC( G, gens[1] );
AddTranslationBasis( comp[i], gens[2] );
SetIndexInParent( comp[i], p^(n - Length( sub ) ) );
od;
Append( maximals, comp );
od;
od;
return maximals;
end;
#############################################################################
##
#F MaximalSubgroupRepsSG( <G>, <p> ) . . .maximal subgroups of solvable <G>
##
## This function computes representatives of the conjugacy classes of the
## maximal subgroups of $p$-power index in $G$ in the case that $G$ is
## solvable.
##
MaximalSubgroupRepsSG := function( G, p )
local iso, F, Fgens, Frels, Ffree, Ggens, T, n, d, t, gens, A, kernel,
i, imgs, max, M, g, exp, h, j, Agens, pcgs, spcgs, first, weights;
if not IsSolvableGroup( G ) then
Error("G must be solvable \n");
fi;
iso := IsomorphismFpGroup( PointGroup( G ) );
Ggens := iso!.preimagesInAffineCrystGroup;
if not IsStandardAffineCrystGroup( G ) then
Ggens := List ( Ggens, x -> G!.lconj * x * G!.rconj );
fi;
F := Image( IsomorphismFpGroup( G ) );
Frels := RelatorsOfFpGroup( F );
Ffree := FreeGroupOfFpGroup( F );
Fgens := GeneratorsOfGroup( Ffree );
T := TranslationBasis( G );
n := Length( Ggens );
d := DimensionOfMatrixGroup( G ) - 1;
t := Length( T );
gens := List( [n+1..n+t], x -> Fgens[x]^p );
F := Ffree / Concatenation( Frels, gens );
A := PcGroupFpGroup( F );
# compute maximal subgroups of S
Agens := GeneratorsOfGroup( A );
if IsEmpty( Agens ) then
pcgs := Pcgs(A);
else
pcgs := PcgsByPcSequence( FamilyObj(Agens[1]), Agens );
fi;
spcgs := SpecialPcgs(A);
first := LGFirst( spcgs );
weights := LGWeights( spcgs );
max := [];
for i in [1..Length(first)-1] do
if weights[first[i]][2] = 1 and weights[first[i]][3] = p then
Append(max,ShallowCopy(MaximalSubgroupClassesRepsLayer(spcgs,i)));
fi;
od;
# compute generators of kernel G -> A and preimages
kernel := List( [1..t], x -> IdentityMat( d+1 ) );
for i in [1..t] do
kernel[i][d+1][i] := 1;
od;
imgs := Concatenation( Ggens, List( kernel, m -> MutableMatrix( m ) ) );
for i in [1..t] do
kernel[i][d+1][i] := p;
od;
# compute corresponding subgroups in G
for i in [1..Length(max)] do
M := max[i];
gens := [];
for g in GeneratorsOfGroup( M ) do
exp := ExponentsOfPcElement( pcgs, g );
h := Product( List( [1..Length(exp)], x -> imgs[x]^exp[x] ) );
Add( gens, h );
od;
Append( gens, kernel );
if not IsStandardAffineCrystGroup( G ) then
for j in [1..Length(gens)] do
gens[j] := G!.rconj * gens[j] * G!.lconj;
od;
fi;
gens := SimpleGenerators( d, gens );
M := SubgroupNC( G, gens[1] );
AddTranslationBasis( M, gens[2] );
SetIndexInParent( M, Index( A, max[i] ) );
max[i] := M;
od;
return max;
end;
#############################################################################
##
#M MaximalSubgroupClassReps( S, flags )
##
InstallOtherMethod( MaximalSubgroupClassReps,
"for AffineCrystGroupOnRight",
true, [ IsAffineCrystGroupOnRight, IsRecord ], 0,
function( S, flags )
local reps, new, M, i;
if IsBound( flags.primes ) then
if not IsList( flags.primes ) or
not ForAll( flags.primes, IsPrimeInt ) then
Error("flags.primes must be a list of primes");
fi;
fi;
# the lattice-equal case
if IsBound( flags.latticeequal ) and flags.latticeequal=true then
if IsBound( flags.classequal ) and flags.classequal=true then
Error("both classequal and latticeequal is impossible!");
fi;
reps := MaximalSubgroupRepsTG( S );
if IsBound( flags.primes ) then
new := [];
for M in reps do
i := Index( S, M );
if IsPrimePowerInt( i ) and
FactorsInt(i)[1] in flags.primes then
Add( new, M );
fi;
od;
return new;
fi;
return reps;
fi;
# the class-equal case
if IsBound( flags.classequal ) and flags.classequal=true then
if not IsBound( flags.primes ) then
Error("flags.primes must be bound");
fi;
return MaximalSubgroupRepsKG( S, flags.primes );
fi;
# the p-index case
if IsBound( flags.primes ) then
if IsSolvableGroup( S ) then
return Concatenation( List( flags.primes,
x -> MaximalSubgroupRepsSG( S, x ) ) );
else
reps := MaximalSubgroupRepsTG( S );
new := [];
for M in reps do
i := Index( S, M );
if IsPrimePowerInt( i ) and
FactorsInt(i)[1] in flags.primes then
Add( new, M );
fi;
od;
Append( new, MaximalSubgroupRepsKG( S, flags.primes ) );
return new;
fi;
fi;
Error("inconsistent input - check manual");
end );
InstallOtherMethod( MaximalSubgroupClassReps,
"for AffineCrystGroupOnLeft",
true, [ IsAffineCrystGroupOnLeft, IsRecord ], 0,
function( S, flags )
local G, reps, lst, max, gen, new;
G := TransposedMatrixGroup( S );
reps := MaximalSubgroupClassReps( G, flags );
lst := [];
for max in reps do
gen := List( GeneratorsOfGroup( max ), TransposedMat );
new := SubgroupNC( S, gen );
if HasTranslationBasis( max ) then
AddTranslationBasis( new, TranslationBasis( max ) );
fi;
if HasIndexInParent( max ) then
SetIndexInParent( new, IndexInParent( max ) );
fi;
Add( lst, new );
od;
return lst;
end );
#############################################################################
##
#M ConjugacyClassesMaximalSubgroups( S, flags )
##
InstallOtherMethod( ConjugacyClassesMaximalSubgroups, "forAffineCrystGroup",
true, [ IsAffineCrystGroupOnLeftOrRight, IsRecord ], 0,
function( S, flags )
local reps, cls, M, c;
reps := MaximalSubgroupClassReps( S, flags );
cls := [];
for M in reps do
c := ConjugacyClassSubgroups( S, M );
if not IsNormal( S, M ) then
SetSize( c, IndexInParent( M ) );
else
SetSize( c, 1 );
fi;
Add( cls, c );
od;
return cls;
end );
[ Verzeichnis aufwärts0.43unsichere Verbindung
Übersetzung europäischer Sprachen durch Browser
]
|