<!--

   methods.xml            recog package documentation
                                                               Max Neunhoeffer
                                                                   Ákos Seress
                                                                        et al.

         Copyright (C) 2005-2008, by the authors.

This is the chapter of the documentation describing the methods.

-->

<Chapter Label="methods">
<Heading>Methods for recognition</Heading>
<Index><Package>recog</Package></Index>

<Section Label="permmethods">
<Heading>Methods for permutation groups</Heading>

The following table gives an overview over the installed methods and their
rank (higher rank means higher priority, the method is tried earlier, see
Chapter <Ref Chap="methsel"/>).

<#Include SYSTEM "methods_perm_table.xml">

<Subsection Label="TrivialPermGroup">
<Heading><C>TrivialPermGroup</C></Heading>

This method is successful if and only if all generators of the permutation
group <A>G</A> are equal to the identity. Otherwise it returns
<K>false</K> indicating that it will never succeed. This method
is only installed to handle the trivial case such that we do not have to
take this case into account in the other methods.

</Subsection>

<Subsection Label="ThrowAwayFixedPoints">
<Heading><C>ThrowAwayFixedPoints</C></Heading>

This method defines a homomorphism of a permutation group
<A>G</A> to the action on the moved points of <A>G</A> if
<A>G</A> does not have too many moved points. In the current setup, the
homomorphism is defined if the number <M>k</M> of moved
points is at most <M>1/3</M> of the largest moved point of <A>G</A>,
or  <M>k</M> is at most half of the number of points on which
<A>G</A> is stored internally by &GAP;. The method returns
<K>false</K> if it does not define a homomorphism indicating that it will
never succeed.

</Subsection>

<Subsection Label="Pcgs">
<Heading><C>Pcgs</C></Heading>

This is the &GAP; library function to compute a stabiliser chain
for a solvable permutation group.
If the method is successful then
the calling node becomes a leaf node in the recursive scheme.
If the input group is not solvable then the method returns <K>false</K>.

</Subsection>

<Subsection Label="VeryFewPoints">
<Heading><C>VeryFewPoints</C></Heading>

If a permutation group acts only on a few points (the current limit is
at most 10 points) then a stabiliser chain is computed by the
randomized &GAP; library function for that purpose.
If the method is successful then
the calling node becomes a leaf node in the recursive scheme.
If the input group acts on more than 10 points then the
method returns <K>false</K>.

</Subsection>

<Subsection Label="NonTransitive">
<Heading><C>Nontransitive</C></Heading>

If a permutation group <A>G</A> acts nontransitively then this method
computes a homomorphism to the action of <A>G</A> on the orbit of the
largest moved point. If <A>G</A> is transitive then the
method returns <K>false</K>.

</Subsection>

<Subsection Label="Giant">
<Heading><C>Giant</C></Heading>

The method tries to determine whether the input group <A>G</A> is
a giant (that is, <M>A_n</M> or <M>S_n</M> in its natural action on
<M>n</M> points). The output is either a data structure <M>D</M> containing
nice generators for <A>G</A> and a procedure to write an SLP for arbitrary
elements of <A>G</A> from the nice generators; or <K>false</K> if
<A>G</A> is not transitive; or <K>fail</K>, in the case that no
evidence was found that <A>G</A> is a giant, or evidence was found, but
the construction of <M>D</M> was unsuccessful.
If the method constructs <M>D</M> then the calling node becomes a leaf.

</Subsection>

<Subsection Label="Imprimitive">
<Heading><C>Imprimitive</C></Heading>

If the input group is not known to be transitive then this method
returns <K>NotEnoughInformation</K>. If the input group is known to be transitive
and primitive then the method returns <K>false</K>; otherwise, the method
tries to compute a nontrivial block system. If successful then a
homomorphism to the action on the blocks is defined; otherwise,
the method returns <K>false</K>.

If the method is successful then it also gives a hint for the children of
the node by determining whether the kernel of the action on the
block system is solvable. If the answer is yes then the default value 20
for the number of random generators in the kernel construction is increased
by the number of blocks.

</Subsection>

<Subsection Label="SnkSetswrSr">
<Heading><C>SnkSetswrSr</C></Heading>

This method tries to determine whether the input group <A>G</A> is acting
primitively on <M>N</M> points, and
is isomorphic to a large subgroup of <M>H \wr S_r</M> where <M>H</M> is
<M>S_n</M> acting on <M>k</M>-sets and <M>N = {{n \choose k}}^r</M>
and <M>kr > 1</M>. <Q>Large</Q> means that <A>G</A> contains a subgroup
isomorphic to <M>A_n^r</M>. If <A>G</A> is imprimitive then the output is
<K>false</K>. If <A>G</A> is primitive then
the output is either a homomorphism into the
natural imprimitive action of <A>G</A> on <M>nr</M> points with
<M>r</M> blocks of size <M>n</M>, or <K>fail</K>.

</Subsection>

<Subsection Label="StabChain">
<Heading><C>StabChain</C></Heading>

This is the randomized &GAP; library function for computing a stabiliser
chain. The method selection process ensures that this function is called
only with small-base inputs, where the method works efficiently.

</Subsection>

</Section>

<Section Label="matrixmethods">
<Heading>Methods for matrix groups</Heading>

The following table gives an overview over the installed methods and their
rank (higher rank means higher priority, the method is tried earlier, see
Chapter <Ref Chap="methsel"/>). Note
that there are not that many methods for matrix groups since the
system can switch to projective groups by dividing out the subgroup
of scalar matrices. The bulk of the recognition methods are then
installed es methods for projective groups.

<#Include SYSTEM "methods_matrix_table.xml">

<Subsection Label="TrivialMatrixGroup">
<Heading><C>TrivialMatrixGroup</C></Heading>

This method is successful if and only if all generators of a matrix group
<A>G</A> are equal to the identity. Otherwise, it returns <K>false</K>.

</Subsection>

<Subsection Label="KnownStabilizerChain">
<Heading><C>KnownStabilizerChain</C></Heading>

TODO. use an already known stabilizer chain for this group

</Subsection>

<Subsection Label="DiagonalMatrices">
<Heading><C>DiagonalMatrices</C></Heading>

This method is successful if and only if all generators of a matrix group
<A>G</A> are diagonal matrices. Otherwise, it returns <K>false</K>.

</Subsection>

<Subsection Label="FewGensAbelian">
<Heading><C>FewGensAbelian</C></Heading>

TODO. if very few generators, check IsAbelian and if yes, do KnownNilpotent

</Subsection>

<Subsection Label="ReducibleIso">
<Heading><C>ReducibleIso</C></Heading>

This method determines whether a matrix group <A>G</A> acts irreducibly.
If yes, then it returns <K>false</K>. If <A>G</A> acts reducibly then
a composition series of the underlying module is computed and a base
change is performed to write <A>G</A> in a block lower triangular form.
Also, the method passes a hint to the image group that it is in
block lower triangular form, so the image immediately can make
recursive calls for the actions on the diagonal blocks, and then to the
lower <M>p</M>-part. For the image the method <C>BlockLowerTriangular</C>
(see <Ref Subsect="BlockLowerTriangular"/>) is used.

<P/>
Note that this method is implemented in a way such that it can also be
used as a method for a projective group <A>G</A>. In that case the
recognition info record has the <C>!.projective</C> component bound
to <K>true</K> and this information is passed down to image and kernel.
</Subsection>

<Subsection Label="BlockLowerTriangular">
<Heading><C>BlockLowerTriangular</C></Heading>

This method is only called when a hint was passed down from the method
<C>ReducibleIso</C> (see
<Ref Subsect="ReducibleIso"/>). In that case, it knows that a base change
to block lower triangular form has been performed. The method can then
immediately find a homomorphism by mapping to the diagonal blocks. It sets
up this homomorphism and gives hints to image and kernel. For the image,
the method <C>BlockDiagonal</C> (see <Ref Subsect="BlockDiagonal"/>)
is used and for the kernel,
the method <C>LowerLeftPGroup</C> (see <Ref Subsect="LowerLeftPGroup"/>)
is used.

<P/>
Note that this method is implemented in a way such that it can also be
used as a method for a projective group <A>G</A>. In that case the
recognition info record has the <C>!.projective</C> component bound
to <K>true</K> and this information is passed down to image and kernel.
</Subsection>

<Subsection Label="BlockDiagonal">
<Heading><C>BlockDiagonal</C></Heading>

This method is only called when a hint was passed down from the method
<C>BlockLowerTriangular</C> (see <Ref Subsect="BlockLowerTriangular"/>).
In that case, it knows that the group is in block diagonal form.
The method is used both in the matrix- and the projective case.

<P/>
The method immediately delegates to projective methods handling
all the diagonal blocks projectively. This is done by giving a hint
to the factor to use the method
<C>BlocksModScalars</C> (see <Ref Subsect="BlocksModScalars"/>) is
given. The method for the kernel then has to deal with only scalar blocks,
either projectively or with scalars, which is again done by giving a hint to
either use <C>BlockScalar</C> (see <Ref Subsect="BlockScalar"/>)
or <C>BlockScalarProj</C> (see <Ref Subsect="BlockScalarProj"/>) respectively.

<P/>
Note that this method is implemented in a way such that it can also be
used as a method for a projective group <A>G</A>. In that case the
recognition info record has the <C>!.projective</C> component bound
to <K>true</K> and this information is passed down to image and kernel.
</Subsection>

<Subsection Label="GoProjective">
<Heading><C>GoProjective</C></Heading>

This method defines a homomorphism from a matrix group <A>G</A>
into the projective group <A>G</A> modulo scalar matrices. In fact, since
projective groups in &GAP; are represented as matrix groups, the
homomorphism is the identity mapping and the only difference is that in
the image the projective group methods can be applied.
The bulk of the work in matrix recognition is done in the projective group
setting.

</Subsection>

<Subsection Label="BlockScalar">
<Heading><C>BlockScalar</C></Heading>

This method is only called by a hint. Alongside with the hint it gets
a block decomposition respected by the matrix group <A>G</A> to be recognised
and the promise that all diagonal blocks of all group elements
will only be scalar matrices. This method recursively builds a balanced tree
and does scalar recognition in each leaf.
</Subsection>

<Subsection Label="LowerLeftPGroup">
<Heading><C>LowerLeftPGroup</C></Heading>

This method is only called by a hint from <C>BlockLowerTriangular</C>
as the kernel of the homomorphism mapping to the diagonal blocks.
The method uses the fact the this kernel is a <M>p</M>-group where
<M>p</M> is the characteristic of the underlying field. It exploits
this fact and uses this special structure to find nice generators
and a method to express group elements in terms of these.
</Subsection>

</Section>

<Section Label="projmethods">
<Heading>Methods for projective groups</Heading>

The following table gives an overview over the installed methods and their
rank (higher rank means higher priority, the method is tried earlier, see
Chapter <Ref Chap="methsel"/>). Note
that the recognition for matrix group switches to projective recognition
rather soon in the recognition process such that most recognition methods
in fact are installed as methods for projective groups.

<#Include SYSTEM "methods_proj_table.xml">

<Subsection Label="TrivialProjectiveGroup">
<Heading><C>TrivialProjectiveGroup</C></Heading>

This method is successful if and only if all generators of a projective group
<A>G</A> are equal to the identity (that is, in the matrix representation
of <A>G</A>, all matrices are scalars). Otherwise, it returns <K>false</K>.

</Subsection>

<Subsection Label="ProjDeterminant">
<Heading><C>ProjDeterminant</C></Heading>

The method defines a homomorphism from a projective group <A>G</A><M> \le
PGL(d,q)</M> to the cyclic group <M>GF(q)^*/D</M>, where <M>D</M> is the set
of <M>d</M>th powers in <M>GF(q)^*</M>. The image of a group
element <M>g \in <A>G</A></M> is the determinant of a matrix representative of
<M>g</M>, modulo <M>D</M>.

</Subsection>

<Subsection Label="ReducibleIsoProj">
<Heading><C>ReducibleIso</C></Heading>

This method is the same as the matrix group method with the same name
(see <Ref Subsect="ReducibleIso"/>), which is able to take into account
the projective mode.

</Subsection>

<Subsection Label="BlocksModScalars">
<Heading><C>BlocksModScalars</C></Heading>

This method is only called when hinted from above. In this method it is
understood that G should <E>neither</E>
be recognised as a matrix group <E>nor</E> as a projective group.
Rather, it treats all diagonal blocks modulo scalars which means that
two matrices are considered to be equal, if they differ only by a scalar
factor in <E>corresponding</E> diagonal blocks, and this scalar can
be different for each diagonal block. This means that the kernel of
the homomorphism mapping to a node which is recognised using this
method will have only scalar matrices in all diagonal blocks.

<P/>
This method does the balanced tree approach mapping to subsets of the
diagonal blocks and finally using projective recognition to recognise
single diagonal block groups.
</Subsection>

<Subsection Label="NotAbsolutelyIrred">
<Heading><C>NotAbsolutelyIrred</C></Heading>

If an irreducible projective group <A>G</A> acts absolutely irreducibly
then this method returns <K>false</K>. If <A>G</A> is not absolutely
irreducible then a homomorphism into a smaller dimensional representation
over an extension field is defined. A hint is handed down to the image that
no test for absolute irreducibility has to be done any more. Another hint
is handed down to the kernel indicating that the only possible kernel
elements can be elements in the centraliser of <A>G</A> in <M>PGL(d,q)</M>
that come from scalar matrices in the extension field.

</Subsection>

<Subsection Label="Subfield">
<Heading><C>Subfield</C></Heading>

When this method runs it knows that the projective group <A>G</A> acts
absolutely irreducibly. It then tries to realise this group over a smaller
field. The algorithm used is the one using the <Q>standard basis approach</Q>
known from isomorphism testing of absolutely irreducible modules. It
finds a base change to write the projective group over the smallest
field possible. Since the group is projective, it may choose to
multiply generators with arbitrary scalars to write them over a smaller field.

<P/>
However, sometimes the correct scalar can not be guessed. Therefore, if the
first approach does not work, the method computes the derived subgroup.
If the group can be written over a smaller field, then taking commutators
loses the scalars preventing a direct base change to work. Therefore,
if the derived subgroup still acts irreducibly, the standard basis approach
can find the right base change that could also do the job for the whole
group. If it acts reducibly, the method <C>Derived</C> (see
<Ref Subsect="Derived"/>) which is run next already has the computed
derived subgroup and can try different things to find a reduction.

</Subsection>

<Subsection Label="Derived">
<Heading><C>Derived</C></Heading>

This method computes the derived subgroup, if this has not yet been done
by other methods. It then uses the MeatAxe to decide whether
the derived subgroup acts irreducibly or not. If it acts reducibly,
then we can apply Clifford theory to the natural module. The natural
module restricted to the derived subgroup is a direct sum of simple
modules. If all the summands are isomorphic, we immediately get either
an action of <A>G</A> on blocks or a tensor decomposition. Otherwise,
we get an action of <A>G</A> on the isotypic components. Either way,
we find a reduction.

<P/>
If the derived group acts irreducibly, we return <K>false</K> in the current
implementation.

</Subsection>

<Subsection Label="LowIndex">
<Heading><C>LowIndex</C></Heading>

This method is designed for the handling of the Aschbacher class C2
(stabiliser of a decomposition of the underlying vector space), but may
succeed on other types of input as well. Given <A>G</A> <M> \le PGL(d,q)</M>,
the output is either the permutation action of <A>G</A> on a short
orbit of subspaces or <K>fail</K>. In the current setup, <Q>short orbit</Q>
is defined to have length at most <M>4d</M>.

</Subsection>

<Subsection Label="C6">
<Heading><C>C6</C></Heading>

This method is designed for the handling of the Aschbacher class C6
(normaliser of an extraspecial group). If the input <A>G</A><M>\le PGL(d,q)</M>
does not satisfy <M>d=r^n</M> and <M>r|q-1</M> for some prime <M>r</M>
and integer <M>n</M> then the method
returns <K>false</K>. Otherwise, it returns either a homomorphism of
<A>G</A> into <M>Sp(2n,r)</M>, or a homomorphism into the C2 permutation
action of <A>G</A> on a decomposition of <M>GF(q)^d</M>, or <K>fail</K>.

</Subsection>

<Subsection Label="Tensor">
<Heading><C>Tensor</C></Heading>

This method currently tries to find one tensor factor by powering up
commutators of random elements to elements of prime order. This seems
to work quite well provided that the two tensor factors are not
<Q>linked</Q> too much such that there exist enough elements that act
with different orders on both tensor factors.

<P/>
This method and its description needs some improvement.

</Subsection>

<Subsection Label="TwoLargeElOrders">
<Heading><C>TwoLargeElOrders</C></Heading>

In the case when the input group <A>G</A><M> \le PGL(d,p^e)</M> is
suspected to be
simple but not alternating, this method takes the two
largest element orders from a sample of pseudorandom elements of
<A>G</A>. From these element orders, it tries to determine whether <A>G</A>
is of Lie type or sporadic, and the characteristic of <A>G</A> if it is of
Lie type. In the case when <A>G</A> is of Lie type of characteristic
different from <M>p</M> or <A>G</A> is sporadic, the method also provides
a short list of the possible isomorphism types of <A>G</A>.

</Subsection>

<Subsection Label="StabilizerChain">
<Heading><C>StabilizerChain</C></Heading>

This method computes a stabiliser chain and a base and strong generating
set using projective actions. This is a last resort method since for
bigger examples no short orbits can be found in the natural action.
The strong generators are the nice generator in this case and expressing
group elements in terms of the nice generators ist just sifting along
the stabiliser chain.

</Subsection>

<Subsection Label="BlockScalarProj">
<Heading><C>BlockScalarProj</C></Heading>

This method is only called by a hint. Alongside with the hint it gets
a block decomposition respected by the matrix group <A>G</A> to be recognised
and the promise that all diagonal blocks of all group elements
will only be scalar matrices. This method simply norms the last diagonal
block in all generators by multiplying with a scalar and then
delegates to <C>BlockScalar</C> (see <Ref Subsect="BlockScalar"/>)
and matrix group mode to do the recognition.

</Subsection>


</Section>

<!-- ############################################################ -->

</Chapter>
