Because blackbox groups exist primarily to allow the user to write efficient
code for evaluating words under a homomorphism, there are some extra
features in the homomorphism constructor which rely on the user
providing correct input.
hom< G -> H | L: parameters> : GrpBB, Grp -> Map
CheckCodomain: BoolElt Default: true
Return the group homomorphism phi : G -> H defined by the list L. The list may contain:
- Elements of the codomain. This form can only be used when all the preceding entries have given the image of the corresponding generator of G;
- Generator-image pairs of the form G.i -> x or <G.i, x>;
- A homomorphism psi from a blackbox group B to H where G has been defined as a result of adding redundant generators to B. If this item appears, it must appear first. After the remaining generators have been processed, any images which are not yet assigned are computed from psi . If the parameter CheckCodomain has the value false, then it is assumed that the generator images lie in the codomain.
> G := BlackboxGroup(2); > M := GeneralLinearGroup(19, 7); > phi := hom<G -> M | M.1, M.2>; > P := RandomProcess(G); > x := Random(P); > #x; 74 > Q := [x^G.1, x^G.2, x^(G.1*G.2)]; > time R1 := phi(Q); Time: 0.129
We note that x has become important since it is now a common sub-expression of several straight-line programs. We can build a homomorphism which will store the image of x by adding x as a redundant generator and defining the same homomorphism from the resulting group.
> H := AddRedundantGenerators(G, [x]); > QQ := [H | x: x in Q]; > // we will define psi as the unique map on H which matches phi. > psi := hom<H -> M | phi>; > time R2 := psi(QQ); Time: 0.000 > R1 eq R2; true
In fact, if we had looked at the expression lengths of the straight-line programs involved, we would have found the following, which explains the significant speed up:
> [#x: x in Q]; [ 75, 75, 75 ] > [#x: x in QQ]; [ 1, 1, 2 ]