GAP provides generic functionality to compute orbits. These functions are, generally spoken, applicable to the groups implemented in **FinInG**, combined with the appropriate action functions. However, the generic functions applied in such situations are rather time consuming. **FinInG** therefore provides alternative functions to compute orbits.

`‣ FiningOrbit` ( g, obj, act ) | ( operation ) |

Returns: The orbit of the object `obj` under the action `act` of the group `g`.

The argument `obj` is either a subspace of a projective space, then combined with the action function `OnProjSubspaces`

, or a set of elements of a projective space, then combined with the action function `OnSetsProjSubspaces`

. The group `g` is a subgroup of a collineation group of a projective space. In both cases the action function computes the action of `el` under the group element `g`.

gap> ps := ParabolicQuadric(6,3); Q(6, 3) gap> g := CollineationGroup(ps); PGammaO(7,3) gap> pg := PG(6,3); ProjectiveSpace(6, 3) gap> s := First(Solids(pg),t -> TypeOfSubspace(ps,t) = "elliptic" ); <a solid in ProjectiveSpace(6, 3)> gap> orbit := FiningOrbit(g,s,OnProjSubspaces); <closed orbit, 265356 points> gap> time; 33555

The second example shows the possible use of `FiningOrbit`

in combination with the action function `OnSetsProjSubspaces`

. Please note that this variant is probably not the most efficient way to compute all elliptic quadrics contained in the parabolic quadric ps. Experiments show that for q=5 the second variant takes an unreasonable amount of time. Also note that the second argument `el` must be a set (and therefore it might be necessary to apply `Set`

on a collection of elements).

gap> ps := ParabolicQuadric(4,3); Q(4, 3) gap> g := CollineationGroup(ps); PGammaO(5,3) gap> pg := PG(4,3); ProjectiveSpace(4, 3) gap> s := First(Solids(pg),t -> TypeOfSubspace(ps,t) = "elliptic" ); <a solid in ProjectiveSpace(4, 3)> gap> orbit1 := FiningOrbit(g,s,OnProjSubspaces); <closed orbit, 36 points> gap> time; 9 gap> spts := Filtered(Points(s),s->s in ps); [ <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)>, <a point in ProjectiveSpace(4, 3)> ] gap> orbit2 := FiningOrbit(g,Set(spts),OnSetsProjSubspaces); <closed orbit, 36 points> gap> time; 18

`‣ FiningOrbits` ( g, set, act ) | ( operation ) |

`‣ FiningOrbits` ( g, coll ) | ( operation ) |

Returns: The orbits of the group `g` on `set` under the action of `act`.

The set is a set of elements of a projective space, the group `g` is a subgroup of the collineation group of a projective space, and `act` is the function `OnProjSubspaces`

. If `coll` is a collection of elements of a projective space (i.e. not a list or set, but and object representing the collection of elements of a given type, such as `Lines(PG(3,4))`

), then the second versions returns the orbits of `g` on the elements of `coll` under the action `OnProjSubspaces`

.

gap> ps := HermitianPolarSpace(3,9); H(3, 3^2) gap> g := CollineationGroup(ps); PGammaU(4,3^2) gap> FiningOrbits(g,Lines(PG(3,9))); 75%..98%..100%..[ <closed orbit, 5670 points>, <closed orbit, 1680 points>, <closed orbit, 112 points> ] gap> FiningOrbits(g,Planes(PG(3,9))); 65%..100%..[ <closed orbit, 540 points>, <closed orbit, 280 points> ] gap> ps := ParabolicQuadric(2,5); Q(2, 5) gap> g := CollineationGroup(ps); PGammaO(3,5) gap> pts := Filtered(Points(PG(2,5)),x->not x in ps);; gap> Length(pts); 25 gap> FiningOrbits(g,Points(PG(2,5))); 48%..67%..100%..[ <closed orbit, 15 points>, <closed orbit, 6 points>, <closed orbit, 10 points> ] gap> FiningOrbits(g,pts,OnProjSubspaces); 60%..100%..[ <closed orbit, 15 points>, <closed orbit, 10 points> ]

`‣ FiningOrbitsDomain` ( g, coll, act ) | ( operation ) |

Returns: The orbits of the group `g` on a collection `coll` under the action of `act`.

The argument `coll` must be an object in the category `IsElementsOfIncidenceGeometry`

, the argument `g` can be any group, acting on the elements of `coll` through a suitable action function `act`. This operation is inspired by the GAP operation `OrbitsDomain`

. It computes the orbits of the group `g` on the set of elements in `coll` *assuming* that the set of elements of `coll` is closed under that action of `g`. There is no check whether the assumption is correct, so this operation should typically be used when it is known that the assumption is correct. The operation is generic in the sense that it can be used for different types of incidence geometries as long as the triple arguments consist of a suitable action of `g` on the elements of `coll`. In general, if the assumption is correct, this operation will be faster than `FiningOrbits`

.

gap> pg := PG(7,2); ProjectiveSpace(7, 2) gap> group:=CollineationGroup(pg); The FinInG collineation group PGL(8,2) gap> syl127:=SylowSubgroup(group,127); <projective collineation group of size 127> gap> orbits := FiningOrbits(syl127,AsList(Solids(pg)));; 1%..2%..3%..4%..5%..6%..7%..8%..9%..10%..11%..12%..13%..14%..15%..16%..17%..18%..19%..20%..21%.. 22%..23%..24%..25%..26%..27%..28%..29%..30%..31%..32%..33%..34%..35%..36%..37%..38%..39%..40%..41% ..42%..43%..44%..45%..46%..47%..48%..49%..50%..51%..52%..53%..54%..55%..56%..57%..58%..59%..60%.. 61%..62%..63%..64%..65%..66%..67%..68%..69%..70%..71%..72%..73%..74%..75%..76%..77%..78%..79%.. 80%..81%..82%..83%..84%..85%..86%..87%..88%..89%..90%..91%..92%..93%..94%..95%..96% ..97%..98%..99%..100%.. gap> time; 212661 gap> Collected(List(orbits,x->Length(x))); [ [ 127, 1581 ] ] gap> orbits := FiningOrbitsDomain(syl127,Solids(pg),OnProjSubspaces);; gap> time; 26529 gap> Collected(List(orbits,x->Length(x))); [ [ 127, 1581 ] ] gap> orbits := OrbitsDomain(syl127,Solids(pg),OnProjSubspaces);; gap> time; 35506 gap> Collected(List(orbits,x->Length(x))); [ [ 127, 1581 ] ] gap> ag := AG(4,5); AG(4, 5) gap> h := Random(CollineationGroup(ag)); < a collineation: <cmat 5x5 over GF(5,1)>, F^0> gap> group := Group(h); <projective collineation group with 1 generators> gap> orbits := FiningOrbitsDomain(group,Points(ag),OnAffineSubspaces); [ <closed orbit, 624 points>, <closed orbit, 1 points> ]

The GAP function `Stabilizer`

is a generic function to compute stabilisers of one object (or sets or tuples etc. of objects) under a group, using a specified action function. This generic function can be used together with the in **FinInG** implemented groups and elements of geometries. However, computing time can be very long, already in small geometries.

gap> ps := PG(3,8); ProjectiveSpace(3, 8) gap> g := CollineationGroup(ps); The FinInG collineation group PGammaL(4,8) gap> p := Random(Points(ps)); <a point in ProjectiveSpace(3, 8)> gap> Stabilizer(g,p,OnProjSubspaces); <projective collineation group of size 177223237632 with 2 generators> gap> time; 10026 gap> line := Random(Lines(ps)); <a line in ProjectiveSpace(3, 8)> gap> Stabilizer(g,line,OnProjSubspaces); <projective collineation group of size 21849440256 with 2 generators> gap> time; 78126

The packages **GenSS** and **orb** required by **FinInG** provide efficient operations to compute stabilisers, and **FinInG** provides functionality to use these operations for the particular groups and (elements) of geometries.

`‣ FiningStabiliser` ( g, el ) | ( operation ) |

Returns: The subgroup of `g` stabilising the element `el`

The argument `g` is a group of collineations acting on the element `el`, being a subspace of a projective space (and hence, all elements of a Lie geometry are allowed as second argument). This operation relies on the **GenSS** operation `Stab`

.

gap> ps := PG(5,4); ProjectiveSpace(5, 4) gap> g := SpecialHomographyGroup(ps); The FinInG PSL group PSL(6,4) gap> p := Random(Points(ps)); <a point in ProjectiveSpace(5, 4)> gap> FiningStabiliser(g,p); <projective collineation group of size 264696069567283200 with 2 generators> gap> line := Random(Lines(ps)); <a line in ProjectiveSpace(5, 4)> gap> FiningStabiliser(g,line); <projective collineation group of size 3881174040576000 with 3 generators> gap> plane := Random(Planes(ps)); <a plane in ProjectiveSpace(5, 4)> gap> FiningStabiliser(g,plane); #I Have 106048 points. #I Have 158748 points. <projective collineation group of size 958878292377600 with 2 generators> gap> ps := HyperbolicQuadric(5,5); Q+(5, 5) gap> g := IsometryGroup(ps); PGO(1,6,5) gap> p := Random(Points(ps)); <a point in Q+(5, 5)> gap> FiningStabiliser(g,p); <projective collineation group of size 36000000 with 3 generators> gap> line := Random(Lines(ps)); <a line in Q+(5, 5)> gap> FiningStabiliser(g,line); <projective collineation group of size 6000000 with 3 generators> gap> plane := Random(Planes(ps)); <a plane in Q+(5, 5)> gap> FiningStabiliser(g,plane); <projective collineation group of size 93000000 with 2 generators> gap> h := SplitCayleyHexagon(3); H(3) gap> g := CollineationGroup(h); #I for Split Cayley Hexagon #I Computing nice monomorphism... #I Found permutation domain... G_2(3) gap> p := Random(Points(h)); <a point in H(3)> gap> FiningStabiliser(g,p); <projective collineation group of size 11664 with 2 generators> gap> line := Random(Lines(h)); <a line in H(3)> gap> FiningStabiliser(g,line); <projective collineation group of size 11664 with 2 generators>

`‣ FiningStabiliserOrb` ( g, el ) | ( operation ) |

Returns: The subgroup of `g` stabilising the element `el`

The argument `g` is a group of collineations acting on the element `el`, being a subspace of a projective space (and hence, all elements of a Lie geometry are allowed as second argument). This operation relies on some particular **orb** functionality.

gap> ps := PG(5,4); ProjectiveSpace(5, 4) gap> g := SpecialHomographyGroup(ps); The FinInG PSL group PSL(6,4) gap> p := Random(Points(ps)); <a point in ProjectiveSpace(5, 4)> gap> FiningStabiliserOrb(g,p); <projective collineation group with 15 generators> gap> line := Random(Lines(ps)); <a line in ProjectiveSpace(5, 4)> gap> FiningStabiliserOrb(g,line); <projective collineation group with 15 generators> gap> plane := Random(Planes(ps)); <a plane in ProjectiveSpace(5, 4)> gap> FiningStabiliserOrb(g,plane); <projective collineation group with 15 generators> gap> ps := HyperbolicQuadric(5,5); Q+(5, 5) gap> g := IsometryGroup(ps); PGO(1,6,5) gap> p := Random(Points(ps)); <a point in Q+(5, 5)> gap> FiningStabiliserOrb(g,p); <projective collineation group with 15 generators> gap> line := Random(Lines(ps)); <a line in Q+(5, 5)> gap> FiningStabiliserOrb(g,line); <projective collineation group with 15 generators> gap> plane := Random(Planes(ps)); <a plane in Q+(5, 5)> gap> FiningStabiliserOrb(g,plane); <projective collineation group with 15 generators> gap> h := SplitCayleyHexagon(3); H(3) gap> g := CollineationGroup(h); #I for Split Cayley Hexagon #I Computing nice monomorphism... #I Found permutation domain... G_2(3) gap> p := Random(Points(h)); <a point in H(3)> gap> FiningStabiliserOrb(g,p); <projective collineation group with 15 generators> gap> line := Random(Lines(h)); <a line in H(3)> gap> FiningStabiliserOrb(g,line); <projective collineation group with 15 generators>

A small example shows the difference in computing time. Clearly the `FiningStabiliserOrb`

is the fastest way to compute stabilizers of one element.

gap> ps := PG(3,8); ProjectiveSpace(3, 8) gap> g := CollineationGroup(ps); The FinInG collineation group PGammaL(4,8) gap> p := Random(Points(ps)); <a point in ProjectiveSpace(3, 8)> gap> g1 := Stabilizer(g,p); <projective collineation group of size 177223237632 with 2 generators> gap> time; 9576 gap> g2 := FiningStabiliser(g,p); <projective collineation group of size 177223237632 with 2 generators> gap> time; 244 gap> g3 := FiningStabiliserOrb(g,p); <projective collineation group with 15 generators> gap> time; 46 gap> g1=g2; true gap> g2=g3; true

`‣ FiningSetwiseStabiliser` ( g, els ) | ( operation ) |

Returns: The subgroup of `g` stabilising the set `els`

The argument `g` is a group of collineations acting on the element `el`, being a subspace of a projective space (and hence, all elements of a Lie geometry are allowed as second argument). The argument `els` is a set of elements of the same type of the same Lie geometry, the elements are all in the category `IsSubspaceOfProjectiveSpace`

. The underlying action function is assumed to be `OnProjSubspaces`

gap> ps := HyperbolicQuadric(5,5); Q+(5, 5) gap> g := IsometryGroup(ps); PGO(1,6,5) gap> plane1 := Random(Planes(ps)); <a plane in Q+(5, 5)> gap> plane2 := Random(Planes(ps)); <a plane in Q+(5, 5)> gap> FiningSetwiseStabiliser(g,Set([plane1,plane2])); #I Computing adjusted stabilizer chain... <projective collineation group with 4 generators>

Computing the setwise stabiliser under a group is also possible using `Stabilizer`

. But, not surprisingly, the computing time can be very long.

gap> ps := PG(3,4); ProjectiveSpace(3, 4) gap> p := Random(Points(ps)); <a point in ProjectiveSpace(3, 4)> gap> q := Random(Points(ps)); <a point in ProjectiveSpace(3, 4)> gap> g := CollineationGroup(ps); The FinInG collineation group PGammaL(4,4) gap> Stabilizer(g,Set([p,q]),OnSets); <projective collineation group of size 552960 with 5 generators> gap> time; 10440

The package **GenSS** provides an efficient operations to compute setwise stabilisers. This is why **FinInG** provides functionality, such as `FiningSetwiseStabiliser`

, to use these **GenSS** operations for the particular groups and (elements) of geometries. A small example shows the difference in computing time.

gap> ps := ParabolicQuadric(4,4); Q(4, 4) gap> g := CollineationGroup(ps); PGammaO(5,4) gap> l1 := Random(Lines(ps)); <a line in Q(4, 4)> gap> l2 := Random(Lines(ps)); <a line in Q(4, 4)> gap> g1 := Stabilizer(g,Set([l1,l2]),OnSets); <projective collineation group of size 2304 with 6 generators> gap> time; 2633 gap> g2 := FiningSetwiseStabiliser(g,Set([l1,l2])); #I Computing adjusted stabilizer chain... <projective collineation group with 5 generators> gap> time; 70 gap> g1=g2; true

For subspaces of projective spaces we can be even more efficient by writing down generators of the stabiliser and then return the generated subgroup.

`‣ StabiliserGroupOfSubspace` ( sub ) | ( operation ) |

Returns: The subgroup of the collineation group of `AmbientSpace(sub)` stabilising the subspace `sub`

The argument `sub` is a subspace of a projective space.

`‣ ProjectiveStabiliserGroupOfSubspace` ( sub ) | ( operation ) |

Returns: The subgroup of the projectivity group of `AmbientSpace(sub)` stabilising the subspace `sub`

The argument `sub` is a subspace of a projective space.

`‣ SpecialProjectiveStabiliserGroupOfSubspace` ( sub ) | ( operation ) |

Returns: The subgroup of the special projectivity group of `AmbientSpace(sub)` stabilising the subspace `sub`

The argument `sub` is a subspace of a projective space.

gap> pg:=ProjectiveSpace(5,9); ProjectiveSpace(5, 9) gap> sub:=RandomSubspace(pg,2); <a plane in ProjectiveSpace(5, 9)> gap> coll:=StabiliserGroupOfSubspace(sub); time; <projective collineation group of size 11173786189009966655078400 with 6 generators> 10 gap> computed:=FiningStabiliserOrb(CollineationGroup(pg),sub); <projective collineation group with 15 generators> gap> time; 34923 gap> coll = computed; true gap> proj:=ProjectiveStabiliserGroupOfSubspace(sub); <projective collineation group of size 5586893094504983327539200 with 5 generators> gap> time; 2 gap> FiningStabiliserOrb(ProjectivityGroup(pg),sub)=proj; true gap> time; 116113 gap> specproj:=SpecialProjectiveStabiliserGroupOfSubspace(sub); <projective collineation group of size 2793446547252491663769600 with 5 generators> gap> time; 2 gap> specproj = FiningStabiliserOrb(SpecialProjectivityGroup(pg),sub); true gap> time; 65564

GAP provides generic functions to compute action homomorphisms and their images for arbitrary groups. These functions are applicable on the projective groups implemented in **FinInG**.

`‣ OnProjSubspaces` ( el, g ) | ( function ) |

`‣ OnProjSubspacesExtended` ( el, g ) | ( function ) |

`‣ OnSetsProjSubspaces` ( set, g ) | ( function ) |

Returns: a element of a Lie geometry

Let `el` be an element of any Lie geometry, and `g` an element of a projective group acting on the elements of the ambient Lie geometry of `el`. Then then `OnProjSubspaces`

will return simply the image of `el` under `g`. When `g` is an element of the correlation/collineation group of a projective space, `OnProjSubspacesExtended`

returns the image of `el` under `g`. Finally, when `set` is a set of elements of a Lie geometry, `OnSetsProjSubspaces`

returns the set of images under `g`. `OnProjSubspaces`

is also explained in 5.8-1, `OnProjSubspacesExtended`

is also explained in 5.8-3.

`‣ ActionHomomorphism` ( g, S, act ) | ( operation ) |

`‣ Action` ( g, S, act ) | ( operation ) |

`g` is a projective group, `S` is a set or a collection of elements, `act` is an action function. `Action`

simply returns `Image(hom)`

, if `hom` is the result of `ActionHomomorphism`

. The examples are self-explanatory.

gap> pg := PG(2,3); ProjectiveSpace(2, 3) gap> conic := Set(Points(ParabolicQuadric(2,3)));; gap> coll := CollineationGroup(pg); The FinInG collineation group PGL(3,3) gap> orb := Orbit(coll,conic,OnSetsProjSubspaces);; gap> Length(orb); 234 gap> hom := ActionHomomorphism(coll,orb,OnSetsProjSubspaces); <action homomorphism> gap> perm := Image(hom); <permutation group with 2 generators> gap> Order(perm); 5616 gap> NrMovedPoints(perm); 234 gap> ps := SymplecticSpace(5,2); W(5, 2) gap> coll := CollineationGroup(ps); PGammaSp(6,2) gap> perm := Action(coll,Lines(ps),OnProjSubspaces); <permutation group with 4 generators> gap> NrMovedPoints(perm); 315

A nice monomorphism of a group G is roughly just a permutation representation of G on a suitable action domain. An easy example is the permutation action of the full collineation group of a projective space on its points.

`‣ NiceMonomorphism` ( group ) | ( attribute ) |

Returns: A group homomorphism

This is a generic GAP function, and returns a homomorphism to a "better" representation.

`‣ NiceObject` ( group ) | ( attribute ) |

Returns: A permutation group

`group` is a projective group. The object this operation returns is actually equivalent with `Image(NiceMonomorphism(group))`

.

For the different Lie geometries implemented in **FinInG**, nicemonomorphisms are (necessarily) treated in a different way. As the aim of a nicemonomorphism of group G is to provide a permutation representation, such that efficient algorithms for permutation groups become available for certain operations applicable on G, clearly the efficiency will be increased if the degree of the permutation representation is as small as possible.

For the collineation group, projectivity group and special projectivity group of a projective space, it is clear that the smallest degree permutation representation is the action of the group on the projective points. In principle, one could also consider the action on the hyperplanes. For the collineation group, similarity group and isometry group of a classical polar space, in most cases, the smallest degree permutation representation is the action on the points. A notorious exception to this is the hermitian polar space in three dimensions, of which the number of lines is smaller than the number of points, and hence of which the smallest degree permutation representation is the action of the group on the lines. When constructing a collineation group (or (special) projectivity group) of a projective space, the nicemonomorphism is not computed. It is only computed when needed. The reason is that from the underlying field and dimension, the underlying projective space can be determined at any time, and hence the smallest degree representation can be computed. For the collineation groups (and similarity and isometry groups) of classical polar spaces, this behaviour is different. Indeed, given a group of collineations, from the underlying field and dimension, the original polar space can not be determined. Of course one could consider the action on the points of the underlying projective space, but typically the number of points of a classical polar space is much smaller than the number points of the underlying projective space. This explains why, currently, a nice monomorphism is computed at the moment a collineation group of a classical polar space is computed. As a consequence, just asking the collineation group of a polar space can be time consuming.

gap> g := CollineationGroup(PG(5,9)); The FinInG collineation group PGammaL(6,9) gap> time; 28 gap> HasNiceMonomorphism(g); false gap> h := CollineationGroup(EllipticQuadric(5,9)); PGammaO-(6,9) gap> time; 1584 gap> HasNiceMonomorphism(h); true

`‣ SetParent` ( group ) | ( operation ) |

Assume that G is a group of collineations. As mentioned already, from the underlying field and dimension, only the underlying projective space can be determined. An operation like `Order`

requires a nice monomorphism, so for an arbitrary group G, the action on the points of the underlying projective space will be computed, which can be time consuming for large projective spaces. However, if it is known that G is a subgroup of another collineation group H, this group H can be set as a parent group for G. If a nice monomorphism is available for H, it will become available for G. In the example we construct the collineation group of the hermitian polar space H(3,81). As explained, a nice monomorphism is computed upon construction. Then construct a group generated by two random elements of this collineation group of H(3,81), and compute its order. Without further information, it will be assumed by the system that this new group is a subgroup of the collineation group of PG(3,81), and a nice monomorphism will be computed through this group. In the second part we set the parent group as the collineation group of H(3,81), and compute the order again. Compare the different timings.

gap> ps := HermitianPolarSpace(3,81); H(3, 9^2) gap> group := CollineationGroup(ps); PGammaU(4,9^2) gap> time; 2219 gap> g := Random(group); < a collineation: <cmat 4x4 over GF(3,4)>, F^27> gap> h := Random(group); < a collineation: <cmat 4x4 over GF(3,4)>, F^3> gap> group2 := Group([g,h]); <projective collineation group with 2 generators> gap> HasNiceMonomorphism(group2); false gap> Order(group2); 407194345728000 gap> time; 371559 gap> HasNiceMonomorphism(group2); true gap> NrMovedPoints(NiceObject(group2)); 538084 gap> Size(Points(PG(3,81))); 538084 gap> group2 := Group([g,h]); <projective collineation group with 2 generators> gap> SetParent(group2,group); gap> HasNiceMonomorphism(group2); true gap> HasNiceObject(group2); false gap> Order(group2); 407194345728000 gap> time; 888 gap> HasNiceObject(group2); true gap> NrMovedPoints(NiceObject(group2)); 7300 gap> Size(Lines(ps)); 7300

generated by GAPDoc2HTML