############################################################################ ## #F SelectionIrreducibleSolubleMatrixGroups(n, q, d, indices, orders, blockdims, max) ## ## selects the subset of <indices> corresponding to those irreducible ## matrix groups whose orders are in <orders>, whose minimal block dims are in ## <blockdims>. if max is true and d = 1, only the maximal soluble groups are returned, ## if max is false, the non-maximal ones are returned. ## To ignore one of the parameters orders, blockdims, max, set it to fail ## If <indices> is fail, all groups are considered. ##
InstallGlobalFunction(SelectionIrreducibleSolubleMatrixGroups, function(n0, q0, d, indices, orders, blockdims, max)
local n, q, p, descs, gddescs, i;
n := n0/d;
q := q0^d;
# info comes from GL(n, q)
LoadAbsolutelyIrreducibleSolubleGroupData(n, q);
if indices = fail then
indices := IndicesIrreducibleSolubleMatrixGroups(n0, q0, d); else
indices := Intersection(indices, IndicesIrreducibleSolubleMatrixGroups(n0, q0, d)); fi;
if n = 1then# from groups of degree 1 - defer to orders
descs := IRREDSOL_DATA.GROUPS_DIM1 [q];
# evaluate max
if max <> fail then if d > 1then
Error("maximality information not available for groups which are not absolutely irreducible"); fi;
if max then if Length(descs) in indices then
indices := [Length(descs)]; else
RemoveSet(indices, Length(descs)); fi; fi; fi;
# now look at orders if orders <> fail then
indices := Filtered(indices, i -> descs[i][1] in orders); fi;
# block dims
if blockdims <> fail then if d = 1then if not 1 in blockdims then
indices := []; fi; else
p := SmallestRootInt(q0);
i := PositionSet(DivisorsInt(LogInt(q, p)), LogInt(q0, p));
indices := Filtered(indices, k -> descs[k][2][i] in blockdims); fi; fi;
else# n > 1
# evluate max
if max <> fail then if max then
indices := Intersection(indices, IRREDSOL_DATA.MAX[n][q]); else
indices := Difference(indices, IRREDSOL_DATA.MAX[n][q]); fi; fi;
if orders <> fail then
indices := Filtered(indices, i -> descs[i][4] in orders); fi;
if blockdims <> fail then if d = 1then
indices := Filtered(indices, i -> gddescs[descs[i][1]][4] in blockdims); else
p := SmallestRootInt(q0);
i := PositionSet(DivisorsInt(LogInt(q, p)), LogInt(q0, p));
indices := Filtered(indices, k -> descs[k][3][i] in blockdims); fi; fi; fi;
MakeImmutable(indices);
return indices; end);
############################################################################ ## #F OrdersAbsolutelyIrreducibleSolubleMatrixGroups(n, q, blockdims, max) ## ## returns a set. Each entry is a pair [order, count] describing how many ## groups of that order are in the data base whose minimal block dims are in <blockdims> ## if max is true, only the maximal soluble groups are counted, if max is ## false, the non-maximal ones are returned. ## To ignore one of the parameters blockdims, max, set it to fail ##
InstallGlobalFunction(OrdersAbsolutelyIrreducibleSolubleMatrixGroups, function(n, q, blockdims, max)
local orders, descs, guardianDescs, desc, guardianDesc, grpinds, i, j, grp, o;
LoadAbsolutelyIrreducibleSolubleGroupData(n,q);
if n = 1then if blockdims <> fail and not 1 in blockdims then
return []; fi; if max = true then
return [[IRREDSOL_DATA.GROUPS_DIM1 [q][Length(IRREDSOL_DATA.GROUPS_DIM1 [q])][1],1]]; else
orders := List(IRREDSOL_DATA.GROUPS_DIM1 [q], d -> [d[1],1]); if max = false then
Unbind(orders[Length(orders)]); fi;
return orders; fi; fi;
descs := IRREDSOL_DATA.GROUPS[n][q];
guardianDescs := IRREDSOL_DATA.GUARDIANS[n][q]; if max = true then
grpinds := IRREDSOL_DATA.MAX[n][q]; elif max = false then
grpinds := Difference([1..Length(descs)], IRREDSOL_DATA.MAX[n][q]); else
grpinds := [1..Length(descs)]; fi;
orders := [];
for i in grpinds do
desc := descs[i]; # description of group
guardianDesc := guardianDescs[desc[1]]; # and corresponding guardian
grp := Source (guardianDesc[3]); # pc group isomorphic with guardian if (blockdims = fail or guardianDesc[4] in blockdims) then
o := OrderGroupByCanonicalPcgsByNumber(FamilyPcgs(grp), desc[2]);
j := PositionSorted(orders, [o,1], function(a, b) return a[1] < b[1]; end); if IsBound(orders[j]) and orders[j][1] = o then
orders[j][2] := orders[j][2] + 1; else
Add(orders, [o,1], j); fi; fi;
od;
return orders; end);
############################################################################ ## #F CheckAndExtractArguments(specialfuncs, checks, argl, caller) ## ## This function tests whether argl is a list of even length in which the ## entries at odd positions are functions. ## For special functions in this list (each entry in specialfuncs is a list of synonyms ## of such functions) it tests whether the following entry in argl satisfies the ## function in checks corresponding to specailfunc, and that each specialfunc ## only occurs once (including synonyms). ## ## The function returns a record with entries specialvalues, functions, and values. ## if specialvalues[i] is bound, it was the entry following a function in ## specialfuncs[i]. The functions at odd positions in argl but not in specialfuncs ## are returned in the record entry functions, ## the following entries in argl are in the record entry values. ##
InstallGlobalFunction(CheckAndExtractArguments, function(specialfuncs, argl, caller)
local funcs, vals, specialvals, i, f, j;
if Length(argl) mod 2 <> 0then
Error("number of arguments of `", caller, "' must be even"); fi;
funcs := [];
vals := [];
specialvals := []; for i in [1,3..Length(argl)-1] do
f := argl[i]; if not IsFunction(f) then
Error(i, "-th argument in function `", caller, "' must be a function"); fi; if IsHomogeneousList(argl[i+1]) then
argl[i+1] := Set(argl[i+1]); elif IsList(argl[i+1]) then
argl[i+1] := ShallowCopy (argl[i+1]); else
argl[i+1] := [argl[i+1]]; fi;
j := PositionProperty (specialfuncs, funclist -> f in funclist[1]); if j = fail then
Add(funcs, f);
Add(vals, argl[i+1]); elif IsBound(specialvals[j]) then
Error("there may be only one occurrence of ", f, " in `", caller, "'"); else if not ForAll (argl[i+1], x -> specialfuncs[j][2](x)) then
Error("inadmissible value for argument ", i+1, " in `", caller, "'"); fi;
specialvals[j] := argl[i+1]; fi;
od;
return rec(specialvalues := specialvals, functions := funcs, values := vals); end);
############################################################################ ## #F IteratorIrreducibleSolubleMatrixGroups(<func_1>, <val_1>, ...) ## ## see the IRREDSOL manual ##
InstallGlobalFunction(IteratorIrreducibleSolubleMatrixGroups, function(arg)
local r, p, q, k, iter, primes;
r := CheckAndExtractArguments ([
[[Degree, DegreeOfMatrixGroup, Dimension, DimensionOfMatrixGroup], IsPosInt],
[[Characteristic, CharacteristicOfField], p -> IsPosInt(p) and IsPrimeInt(p)],
[[Field, FieldOfMatrixGroup, TraceField], F -> IsField (F) and IsFinite (F)],
[[Order, Size], IsPosInt],
[[MinimalBlockDimension, MinimalBlockDimensionOfMatrixGroup], IsPosInt],
[[IsPrimitive, IsPrimitiveMatrixGroup, IsLinearlyPrimitive], x -> x in [true, false]],
[[IsMaximalAbsolutelyIrreducibleSolubleMatrixGroup], x -> x in [true, false]],
[[IsAbsolutelyIrreducibleMatrixGroup, IsAbsolutelyIrreducible], x -> x in [true, false]],
[[SplittingField], F -> IsField (F) and IsFinite (F)]
],
arg, "IteratorIrreducibleSolubleMatrixGroups");
if ForAny (r.specialvalues, v -> IsEmpty(v)) then
return Iterator ([]); fi;
if not IsBound(r.specialvalues[1]) then
Error("IteratorIrreducibleSolubleMatrixGroups: You must specify the degree(s) of the desired matrix groups"); fi;
if not IsBound(r.specialvalues[3]) then
Error("IteratorIrreducibleSolubleMatrixGroups: You must specify the field(s) of the desired matrix groups"); fi;
# set up data for the iterator record
iter := rec(); if Length(r.functions) > 0then
iter.testfuncs := r.functions;
iter.testvals := r.values; else
iter.testfuncs := fail; fi;
iter.dims := r.specialvalues[1];
if IsBound(r.specialvalues[2]) then# if field characteristic is given
iter.qs := Filtered(r.specialvalues[3], field -> SmallestRootInt(Size(field)) in r.specialvalues[2]); else
iter.qs := List(r.specialvalues[3], Size); fi;
if IsBound(r.specialvalues[4]) then
iter.orders := r.specialvalues[4]; else
iter.orders := fail; fi;
if IsBound(r.specialvalues[5]) then
iter.blockdims := r.specialvalues[5]; else
iter.blockdims := fail; fi;
if IsBound(r.specialvalues[6]) then if Length(r.specialvalues[6]) = 1then
iter.primitive := r.specialvalues[6][1]; else
Info(InfoWarning, 2, "IteratorIrreducibleSolubleMatrixGroups: `IsPrimitiveMatrixGroup' is redundant - will be ignored");
iter.primitive := fail; fi; else
iter.primitive := fail; fi;
if IsBound(r.specialvalues[7]) then if Length(r.specialvalues[7]) > 1then
Info(InfoWarning, 2, "IteratorIrreducibleSolubleMatrixGroups: `IsMaximalAbsolutelyIrreducibleSolubleMatrixGroup' is redundant");
iter.max := fail; else
iter.max := r.specialvalues[7][1]; fi; else
iter.max := fail; fi;
if IsBound(r.specialvalues[8]) then if Length(r.specialvalues[8]) > 1then
Info(InfoWarning, 2, "IteratorIrreducibleSolubleMatrixGroups: `IsAbsolutelyIrreducibleSolubleMatrixGroup' is redundant");
iter.absirred := fail; else
iter.absirred := r.specialvalues[8][1]; if iter.max = true and iter.absirred = false then
Info(InfoWarning, 2, "IteratorIrreducibleSolubleMatrixGroups: values of `IsMaximalAbsolutelyIrreducibleSolubleMatrixGroup' ", "and `IsAbsolutelyIrreducibleSolubleMatrixGroup' contradict each other");
return Iterator([]); fi; fi; else
iter.absirred := fail; fi;
if IsBound(r.specialvalues[9]) then
iter.split := List(r.specialvalues[9], Size); else
iter.split := fail; fi;
if iter.max = true then
iter.absirred := true; fi;
# set up start position in iterator, always points to data of next group to read # if pos is outside indices, then the next value for d, dim and/or q has to be loaded # we mark both iter.d and iter.indices as empty, so that they will be reloaded # during the first call to IsDoneIterator
iter.qi := 1;
iter.dimi := 0; # this gets incremented during the first call of IsDoneIterator # which will also load the data for iter.d and iter.indices
iter.d := [];
iter.di := 1; # mark iter.d as empty
iter.pos := 1;
iter.indices := []; # mark iter.indices as empty
# add iterator methods
iter.IsDoneIterator := function(iterator)
# In order for IsDoneIterator to work in this case, we actually have to look # for a new group. If we find a group, it is stored for NextIterator
local blockdims, dim, divs, d, q, min, max, G, H, gensH, repH, gensG, repG;
# as a safety measure, make sure that IsDoneIterator can be called # after it has returned `true'
if iterator!.qi > Length(iterator!.qs) then
return true; fi;
# find next group
while not IsBound(iterator!.nextGroup) do while iterator!.pos > Length(iterator!.indices) do
iterator!.di := iterator!.di + 1; while iterator!.di > Length(iterator!.d) do
# next dimension
iterator!.dimi := iterator!.dimi + 1;
if iterator!.dimi > Length(iterator!.dims) then
iterator!.dimi := 1;
iterator!.qi := iterator!.qi + 1; if iterator!.qi > Length(iterator!.qs) then
return true; fi; fi;
# we have a new dimension, store its divisors
iterator!.divsdim := DivisorsInt(iterator!.dims[iterator!.dimi]);
# set up degrees of splitting field for the construction of groups which are not absolutely irreducible
iterator!.di := 1; if iterator!.absirred = true then if iterator!.split = fail or iterator!.qs[iterator!.qi] in iterator!.split then
iterator!.d := [1]; else
iterator!.d := []; fi; else if iterator!.split = fail then
iterator!.d := ShallowCopy (iterator!.divsdim); else
q := iterator!.qs[iterator!.qi];
iterator!.d := Filtered(iterator!.divsdim, t -> q^t in iterator!.split); fi; if iterator!.absirred = false then
RemoveSet(iterator!.d, 1); fi; fi;
od;
dim := iterator!.dims[iterator!.dimi];
q := iterator!.qs[iterator!.qi];
# get relevant indices for new values of n, q, and d
d := iterator!.d[iterator!.di];
# merge information about block dims and primitivity
if iterator!.primitive = true then if iterator!.blockdims = fail or dim in iterator!.blockdims then
blockdims := [dim]; else
continue; fi; else if iterator!.blockdims = fail then
blockdims := ShallowCopy (iterator!.divsdim); else
blockdims := Intersection(iterator!.divsdim, iterator!.blockdims); fi; if iterator!.primitive = false then
RemoveSet(blockdims, dim); fi; fi;
if d = 1then#absolutely irreducible case
max := iterator!.max; elif iterator!.max = true then
Error("internal error: iterator!.max is true but trying to construct groups which are not abs. irred"); else
max := fail; fi;
Info(InfoIrredsol, 2, "searching subgroups of GL(", dim, ", ", q, ")", " with splitting field GF(",q, "^",d,"), orders: ", iterator!.orders, " and block dims ", blockdims, " max = ", max);
if IsAvailableAbsolutelyIrreducibleSolubleGroupData(dim/d, q^d) then
iterator!.indices := SelectionIrreducibleSolubleMatrixGroups(
dim, q, d, fail, iterator!.orders, blockdims, max); else
Error("group data for GL(", dim/d, ", ",q^d,") is not available. Type \'return;\' to skip these subgroups.");
iterator!.indices := []; fi;
iterator!.pos := 1;
od;
G := IrreducibleSolubleMatrixGroup(
iterator!.dims[iterator!.dimi],
iterator!.qs[iterator!.qi],
iterator!.d[iterator!.di],
iterator!.indices[iterator!.pos]);
iterator!.pos := iterator!.pos + 1;
if iterator!.testfuncs = fail or ForAll ([1..Length(iterator!.testfuncs)], i -> iterator!.testfuncs[i](G) in iterator!.testvals[i]) then
iterator!.nextGroup := G; fi;
od;
return false; end;
iter.NextIterator := function(iterator)
local G;
if IsDoneIterator (iterator) then
Error("iterator already at its end"); else
G := iterator!.nextGroup;
Unbind(iterator!.nextGroup);
return G; fi; end;
iter.ShallowCopy := function(iterator)
local r;
# we need not copy lists in iterator, since these are never changed in place # and are not documented
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.