CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / doc / tut / group.xml
Views: 418346
1
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
2
<!-- %% -->
3
<!-- %W group.tex GAP documentation Thomas Breuer -->
4
<!-- %W & Frank Celler -->
5
<!-- %W & Martin Schönert -->
6
<!-- %W & Heiko Theißen -->
7
<!-- %% -->
8
<!-- %H @(#)<M>Id: group.tex,v 4.42 2006/11/08 11:50:35 gap Exp </M> -->
9
<!-- %% -->
10
<!-- %Y Copyright 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany -->
11
<!-- %% -->
12
<!-- %% This file contains a tutorial introduction to groups. -->
13
<!-- %% -->
14
<P/>
15
16
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
17
<Chapter Label="Groups and Homomorphisms">
18
<Heading>Groups and Homomorphisms</Heading>
19
20
In this chapter we will show some computations with groups. The examples
21
deal mostly with permutation groups, because they are the easiest
22
to input.
23
The functions mentioned here, like <Ref Func="Group" BookName="ref"/>,
24
<Ref Func="Size" BookName="ref"/> or
25
<Ref Func="SylowSubgroup" BookName="ref"/>, however,
26
are the same for all kinds of groups, although
27
the algorithms which compute the information of course will be different
28
in most cases.
29
30
31
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
32
<Section Label="Permutation groups">
33
<Heading>Permutation groups</Heading>
34
35
Permutation groups are so easy to input because their elements, i.e.,
36
permutations, are so easy to type: they are entered and displayed in
37
disjoint cycle notation. So let's construct a permutation group:
38
<P/>
39
<Example><![CDATA[
40
gap> s8 := Group( (1,2), (1,2,3,4,5,6,7,8) );
41
Group([ (1,2), (1,2,3,4,5,6,7,8) ])
42
]]></Example>
43
<P/>
44
We formed the group generated by the permutations <C>(1,2)</C> and
45
<C>(1,2,3,4,5,6,7,8)</C>, which is well known to be the symmetric group
46
<M>S_8</M> on eight points, and assigned it to the identifier <C>s8</C>.
47
Now <M>S_8</M> contains the alternating group on eight points which can be
48
described in several ways, e.g., as the group of all even permutations
49
in <C>s8</C>, or as its derived subgroup. Once we ask &GAP; to verify that
50
the group is an alternating group acting in its natural permutation
51
representation, the system will display the group accordingly.
52
<P/>
53
<Example><![CDATA[
54
gap> a8 := DerivedSubgroup( s8 );
55
Group([ (1,2,3), (2,3,4), (2,4)(3,5), (2,6,4), (2,4)(5,7),
56
(2,8,6,4)(3,5) ])
57
gap> Size( a8 ); IsAbelian( a8 ); IsPerfect( a8 );
58
20160
59
false
60
true
61
gap> IsNaturalAlternatingGroup(a8);
62
true
63
gap> a8;
64
Alt( [ 1 .. 8 ] )
65
]]></Example>
66
<P/>
67
Once information about a group like <C>s8</C> or <C>a8</C> has been computed,
68
it is stored in the group so that it can simply be looked up when it is
69
required again. This holds for all pieces of information in the
70
previous example. Namely, <C>a8</C> stores its order and that it is
71
nonabelian and perfect, and <C>s8</C> stores its derived subgroup <C>a8</C>.
72
Had we computed <C>a8</C> as <C>CommutatorSubgroup( s8, s8 )</C>, however, it
73
would not have been stored, because it would then have been computed
74
as a function of <E>two</E> arguments, and hence one could not attribute it
75
to just one of them.
76
(Of course the function <Ref Func="CommutatorSubgroup" BookName="ref"/> can
77
compute the commutator subgroup of <E>two</E> arbitrary subgroups.) The
78
situation is a bit different for Sylow <M>p</M>-subgroups: The function
79
<Ref Func="SylowSubgroup" BookName="ref"/> also requires two arguments,
80
namely a group and a
81
prime <M>p</M>, but the result is stored in the group &ndash;namely together
82
with the prime <M>p</M> in a list that can be accessed with
83
<C>ComputedSylowSubgroups</C>, but we
84
won't dwell on the details here.
85
<P/>
86
<Example><![CDATA[
87
gap> syl2 := SylowSubgroup( a8, 2 );; Size( syl2 );
88
64
89
gap> Normalizer( a8, syl2 ) = syl2;
90
true
91
gap> cent := Centralizer( a8, Centre( syl2 ) );; Size( cent );
92
192
93
gap> DerivedSeries( cent );; List( last, Size );
94
[ 192, 96, 32, 2, 1 ]
95
]]></Example>
96
<P/>
97
We have typed double semicolons after some commands to avoid the output
98
of the groups (which would be printed by their generator lists).
99
Nevertheless, the beginner is encouraged to type a single semicolon
100
instead and study the full output. This remark also applies for the rest
101
of this tutorial.
102
<P/>
103
With the next examples, we want to calculate a subgroup of <C>a8</C>, then
104
its normalizer and finally determine the structure of the extension. We
105
begin by forming a subgroup generated by three commuting involutions,
106
i.e., a subgroup isomorphic to the additive group of the vector space
107
<M>2^3</M>.
108
<P/>
109
<Example><![CDATA[
110
gap> elab := Group( (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8),
111
> (1,5)(2,6)(3,7)(4,8) );;
112
gap> Size( elab );
113
8
114
gap> IsElementaryAbelian( elab );
115
true
116
]]></Example>
117
<P/>
118
As usual, &GAP; prints the group by giving all its generators. This can
119
be annoying, especially if there are many of them or if they are of huge
120
degree. It also makes it difficult to recognize a particular group when
121
there are already several around. Note that although it is no problem for
122
<E>us</E> to specify a particular group to &GAP;, by using well-chosen
123
identifiers such as <C>a8</C> and <C>elab</C>, it is impossible for &GAP; to use
124
these identifiers when printing a group for us, because the group does
125
not know which identifier(s) point to it, in fact there can be several.
126
In order to give a name to the group itself (rather than to the
127
identifier),
128
you can use the function <Ref Func="SetName" BookName="ref"/>.
129
We do this with the
130
name <C>2^3</C> here which reflects the mathematical properties of the group.
131
From now on, &GAP; will use this name when printing the group for us,
132
but we still cannot use this name to specify the group to &GAP;, because
133
the name does not know to which group it was assigned (after all, you
134
could assign the same name to several groups). When talking to the
135
computer, you must always use identifiers.
136
<P/>
137
<Example><![CDATA[
138
gap> SetName( elab, "<group of type 2^3>" ); elab;
139
<group of type 2^3>
140
gap> norm := Normalizer( a8, elab );; Size( norm );
141
1344
142
]]></Example>
143
<P/>
144
<Index Subkey="natural">homomorphism</Index>
145
Now that we have the subgroup <C>norm</C> of order 1344 and its subgroup
146
<C>elab</C>, we want to look at its factor group. But since we also want to
147
find preimages of factor group elements in <C>norm</C>, we really want to look
148
at the <E>natural homomorphism</E> defined on <C>norm</C> with kernel <C>elab</C> and
149
whose image is the factor group.
150
<P/>
151
<Example><![CDATA[
152
gap> hom := NaturalHomomorphismByNormalSubgroup( norm, elab );
153
<action epimorphism>
154
gap> f := Image( hom );
155
Group([ (), (), (), (4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5),
156
(1,2)(5,6) ])
157
gap> Size( f );
158
168
159
]]></Example>
160
<P/>
161
The factor group is again represented as a permutation group
162
(its first three generators are trivial, meaning that the first three
163
generators of the preimage are in the kernel of <C>hom</C>). However,
164
the action domain of this factor group has nothing to do with the
165
action domain of <C>norm</C>. (It only happens that both are subsets of the
166
natural numbers.) We can now form images and preimages under the natural
167
homomorphism. The set of preimages of an element under <C>hom</C> is a coset
168
modulo <C>elab</C>.
169
We use the function <Ref Func="PreImages" BookName="ref"/> here because
170
<C>hom</C> is not
171
a bijection, so an element of the range can have several preimages or
172
none at all.
173
<P/>
174
<Example><![CDATA[
175
gap> ker:= Kernel( hom );
176
<group of type 2^3>
177
gap> x := (1,8,3,5,7,6,2);; Image( hom, x );
178
(1,7,5,6,2,3,4)
179
gap> coset := PreImages( hom, last );
180
RightCoset(<group of type 2^3>,(2,8,6,7,3,4,5))
181
]]></Example>
182
<P/>
183
Note that &GAP; is free to choose any representative for the coset
184
of preimages.
185
Of course the quotient of two representatives lies in the kernel of
186
the homomorphism.
187
<P/>
188
<Example><![CDATA[
189
gap> rep:= Representative( coset );
190
(2,8,6,7,3,4,5)
191
gap> x * rep^-1 in ker;
192
true
193
]]></Example>
194
<P/>
195
The factor group <C>f</C> is a simple group, i.e., it has no non-trivial
196
normal subgroups. &GAP; can detect this fact, and it can then also find
197
the name by which this simple group is known among group theorists. (Such
198
names are of course not available for non-simple groups.)
199
<P/>
200
<Example><![CDATA[
201
gap> IsSimple( f ); IsomorphismTypeInfoFiniteSimpleGroup( f );
202
true
203
rec(
204
name := "A(1,7) = L(2,7) ~ B(1,7) = O(3,7) ~ C(1,7) = S(2,7) ~ 2A(1,\
205
7) = U(2,7) ~ A(2,2) = L(3,2)", parameter := [ 2, 7 ], series := "L" )
206
gap> SetName( f, "L_3(2)" );
207
]]></Example>
208
<P/>
209
We give <C>f</C> the name <C>L_3(2)</C> because the last part of the name string
210
reveals that it is isomorphic to the simple linear group <M>L_3(2)</M>. This
211
group, however, also has a lot of other names. Names that are connected
212
with a <C>=</C> sign are different names for the same matrix group, e.g.,
213
<C>A(2,2)</C> is the Lie type notation for the classical notation <C>L(3,2)</C>.
214
Other pairs of names are connected via <C>~</C>, these then specify other
215
classical groups that are isomorphic to that linear group (e.g., the
216
symplectic group <C>S(2,7)</C>, whose Lie type notation would be <C>C(1,7)</C>).
217
<P/>
218
The group <C>norm</C> acts on the eight elements of its normal subgroup <C>elab</C>
219
by conjugation, yielding a representation of <M>L_3(2)</M> in <C>s8</C> which
220
leaves one point fixed (namely point&nbsp;<C>1</C>).
221
The image of this representation can be computed with the function
222
<Ref Func="Action" BookName="ref"/>; it is even
223
contained in the group <C>norm</C> and we can show that <C>norm</C> is indeed a
224
split extension of the elementary abelian group <M>2^3</M> with this image of
225
<M>L_3(2)</M>.
226
<P/>
227
<Example><![CDATA[
228
gap> op := Action( norm, elab );
229
Group([ (), (), (), (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6),
230
(2,3)(6,7) ])
231
gap> IsSubgroup( a8, op ); IsSubgroup( norm, op );
232
true
233
true
234
gap> IsTrivial( Intersection( elab, op ) );
235
true
236
gap> SetName( norm, "2^3:L_3(2)" );
237
]]></Example>
238
<P/>
239
By the way, you should not try the operator <C>&lt;</C> instead of the function
240
<Ref Func="IsSubgroup" BookName="ref"/>. Something like
241
<P/>
242
<Example><![CDATA[
243
gap> elab < a8;
244
false
245
]]></Example>
246
<P/>
247
will not cause an error, but the result does not signify anything about the
248
inclusion of one group in another; <C>&lt;</C> tests which of the two groups is
249
less in some total order. On the other hand, the equality operator <C>=</C> in
250
fact does test the equality of its arguments.
251
<P/>
252
<E>Summary.</E> In this section we have used the elementary group
253
functions to determine the structure of a normalizer. We have assigned
254
names to the involved groups which reflect their mathematical structure
255
and &GAP; uses these names when printing the groups.
256
257
</Section>
258
259
260
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
261
<Section Label="Actions of Groups">
262
<Heading>Actions of Groups</Heading>
263
264
In order to get another representation of <C>a8</C>, we consider another
265
action, namely that on the elements of a certain conjugacy class by
266
conjugation.
267
<P/>
268
In the following example we temporarily increase the line length limit
269
from its default value 80 to 82 in order to make the long expression fit
270
into one line.
271
<P/>
272
<Example><![CDATA[
273
gap> ccl := ConjugacyClasses( a8 );; Length( ccl );
274
14
275
gap> List( ccl, c -> Order( Representative( c ) ) );
276
[ 1, 2, 2, 3, 6, 3, 4, 4, 5, 15, 15, 6, 7, 7 ]
277
gap> List( ccl, Size );
278
[ 1, 210, 105, 112, 1680, 1120, 2520, 1260, 1344, 1344, 1344, 3360,
279
2880, 2880 ]
280
]]></Example>
281
<P/>
282
Note the difference between <Ref Func="Order" BookName="ref"/>
283
(which means the element order),
284
<Ref Func="Size" BookName="ref"/>
285
(which means the size of the conjugacy class) and
286
<Ref Func="Length" BookName="ref"/> (which means the length of a list).
287
We choose to let <C>a8</C> operate on the class of length&nbsp;112.
288
<P/>
289
<Example><![CDATA[
290
gap> class := First( ccl, c -> Size(c) = 112 );;
291
gap> op := Action( a8, AsList( class ),OnPoints );;
292
]]></Example>
293
<P/>
294
We use <Ref Func="AsList" BookName="ref"/> here to convert the conjugacy
295
class into a list of its elements whereas we wrote
296
<C>Action( norm, elab )</C> directly in the previous section.
297
The reason is that the elementary abelian group <C>elab</C>
298
can be quickly enumerated by &GAP; whereas the standard enumeration
299
method for conjugacy classes is slower than just explicit calculation of
300
the elements. However, &GAP; is reluctant to construct explicit element
301
lists, because for really large groups this direct method is infeasible.
302
<P/>
303
Note also the function <Ref Func="First" BookName="ref"/>,
304
used to find the first element in a list which passes some test.
305
<P/>
306
In this example,
307
we have specified the action function <Ref Func="OnPoints" BookName="ref"/>
308
in this example,
309
which is defined as
310
<C>OnPoints( </C><M>d</M><C>, </C><M>g</M><C> ) = </C><M>d</M><C> ^ </C><M>g</M>.
311
This <Q>caret</Q> operator denotes conjugation in a group if both
312
arguments <M>d</M> and <M>g</M> are group elements (contained in a common
313
group), but it also denotes the natural action of permutations on
314
positive integers (and exponentiation of integers as well, of course).
315
It is in fact the default action and will be supplied by the system if not
316
given. Another common action is for example
317
always assumes <Ref Func="OnRight" BookName="ref"/>, which means right
318
multiplication, defined as <M>d</M><C> * </C><M>g</M>.
319
(Group actions in &GAP; are always from the right.)
320
<P/>
321
We now have a permutation representation <C>op</C> on 112 points, which we
322
test for primitivity. If it is not primitive, we can obtain a minimal
323
block system (i.e., one where the blocks have minimal length) by the
324
function <Ref Func="Blocks" BookName="ref"/>.
325
<P/>
326
<Example><![CDATA[
327
gap> IsPrimitive( op, [ 1 .. 112 ] );
328
false
329
gap> blocks := Blocks( op, [ 1 .. 112 ] );;
330
]]></Example>
331
<P/>
332
Note that we must specify the domain of the action. You might think
333
that the functions <Ref Func="IsPrimitive" BookName="ref"/> and
334
<Ref Func="Blocks" BookName="ref"/> could use <C>[ 1 .. 112 ]</C> as
335
default domain if no domain was given. But this is not so easy,
336
for example would the default domain of <C>Group( (2,3,4) )</C> be
337
<C>[ 1 .. 4 ]</C> or <C>[ 2 .. 4 ]</C>?
338
To avoid confusion, all action functions require that you
339
specify the domain of action.
340
If we had specified <C>[ 1 .. 113 ]</C> in the
341
primitivity test above, point&nbsp;113 would have been a fixpoint (and the
342
action would not even have been transitive).
343
<P/>
344
Now <C>blocks</C> is a list of blocks (i.e., a list of lists), which we do not
345
print here for the sake of saving paper (try it for yourself). In fact
346
all we want to know is the size of the blocks, or rather how many there
347
are (the product of these two numbers must of course be&nbsp;112). Then we can
348
obtain a new permutation group of the corresponding degree by letting
349
<C>op</C> act on these blocks setwise.
350
<P/>
351
<Example><![CDATA[
352
gap> Length( blocks[1] ); Length( blocks );
353
2
354
56
355
gap> op2 := Action( op, blocks, OnSets );;
356
gap> IsPrimitive( op2, [ 1 .. 56 ] );
357
true
358
]]></Example>
359
<P/>
360
Note that we give a third argument (the action function
361
<Ref Func="OnSets" BookName="ref"/>) to
362
indicate that the action is not the default action on points but an
363
action on sets of elements given as sorted lists.
364
(Section&nbsp;<Ref Sect="Basic Actions" BookName="ref"/> lists all
365
actions that are pre-defined by &GAP;.)
366
<P/>
367
The action of <C>op</C> on the given block system gave us a new representation
368
on 56 points which is primitive, i.e., the point stabilizer is a maximal
369
subgroup. We compute its preimage in the representation on eight points
370
using the associated action homomorphisms (which of course in this
371
case are
372
monomorphisms). We construct the composition of two homomorphisms with
373
the <C>*</C> operator, reading left-to-right.
374
<P/>
375
<Example><![CDATA[
376
gap> ophom := ActionHomomorphism( a8, op );;
377
gap> ophom2 := ActionHomomorphism( op, op2 );;
378
gap> composition := ophom * ophom2;;
379
gap> stab := Stabilizer( op2, 2 );;
380
gap> preim := PreImages( composition, stab );
381
Group([ (1,4,2), (3,6,7), (3,8,5,7,6), (1,4)(7,8) ])
382
]]></Example>
383
<P/>
384
Alternatively, it is possible to create action homomorphisms immediately
385
(without creating the action first) by giving the same set of arguments to
386
<Ref Func="ActionHomomorphism" BookName="ref"/>.
387
<Example><![CDATA[
388
gap> nophom := ActionHomomorphism( a8, AsList(class) );
389
<action homomorphism>
390
gap> IsSurjective(nophom);
391
false
392
gap> Image(nophom,(1,2,3));
393
(2,43,14)(3,44,20)(4,45,26)(5,46,32)(6,47,38)(8,13,48)(9,19,53)(10,25,
394
58)(11,31,63)(12,37,68)(15,49,73)(16,50,74)(17,51,75)(18,52,76)(21,54,
395
77)(22,55,78)(23,56,79)(24,57,80)(27,59,81)(28,60,82)(29,61,83)(30,62,
396
84)(33,64,85)(34,65,86)(35,66,87)(36,67,88)(39,69,89)(40,70,90)(41,71,
397
91)(42,72,92)
398
]]></Example>
399
<P/>
400
In this situation, however (for performance reasons, avoiding computation
401
an image that might never be needed) the homomorphism is defined to be not
402
into the <E>Image</E> of the action, but into the <E>full symmetric
403
group</E>, i.e. it is not automatically surjective. Surjectivity can be
404
enforced by giving the string <C>"surjective"</C> as an extra last argument.
405
The <C>Image</C> of the action homomorphism of course is the same group in
406
either case.
407
<Example><![CDATA[
408
gap> Size(Range(nophom));
409
1974506857221074023536820372759924883412778680349753377966562950949028\
410
5896977181144089422435502777936659795733823785363827233491968638562181\
411
1850780464277094400000000000000000000000000
412
gap> Size(Range(ophom));
413
20160
414
gap> nophom := ActionHomomorphism( a8, AsList(class),"surjective" );
415
<action epimorphism>
416
gap> Size(Range(nophom));
417
20160
418
]]></Example>
419
<P/>
420
Continuing the example,
421
the normalizer of an element in the conjugacy class <C>class</C> is a group of
422
order 360, too. In fact, it is a conjugate of the maximal subgroup we had
423
found before, and a conjugating element in <C>a8</C> is found by the function
424
<Ref Func="RepresentativeAction" BookName="ref"/>.
425
<P/>
426
<Example><![CDATA[
427
gap> sgp := Normalizer( a8, Subgroup(a8,[Representative(class)]) );;
428
gap> Size( sgp );
429
360
430
gap> RepresentativeAction( a8, sgp, preim );
431
(2,4,3)
432
]]></Example>
433
<!-- % The scalar product of permutation characters of two subgroups <A>U</A>, <A>V</A>, -->
434
<!-- % say, equals the number of <M>(<A>U</A>,<A>V</A>)</M>-double cosets. For example, the -->
435
<!-- % norm of the natural permutation character of degree eight is two since -->
436
<!-- % the action of <C>a8</C> on the cosets of a point stabilizer is at least doubly -->
437
<!-- % transitive. We also compute the numbers of <M>(<C>sgp</C>,<C>sgp</C>)</M> and -->
438
<!-- % <M>(<C>sgp</C>,<C>stab</C>)</M> double cosets. -->
439
<!-- % \b eginexample -->
440
<!-- % gap> stab := Stabilizer( a8, 1 );; -->
441
<!-- % gap> Length( DoubleCosets( a8, stab, stab ) ); -->
442
<!-- % 2 -->
443
<!-- % gap> Length( DoubleCosets( a8, sgp, sgp ) ); -->
444
<!-- % 4 -->
445
<!-- % gap> Length( DoubleCosets( a8, sgp, stab ) ); -->
446
<!-- % 2 -->
447
<!-- % \e ndexample -->
448
<P/>
449
<Index Subkey="operation">homomorphism</Index>
450
<Index Subkey="action">homomorphism</Index>
451
<Index>enumerator</Index>
452
<Index>transversal</Index>
453
<Index>canonical position</Index>
454
455
One of the most prominent actions of a group is on the cosets of a subgroup.
456
Naïvely this can be done by constructing the cosets and acting on them
457
by right multiplication.
458
<Example><![CDATA[
459
gap> cosets:=RightCosets(a8,norm);;
460
gap> op:=Action(a8,cosets,OnRight);
461
Group([ (1,2,3)(4,6,5)(7,8,9)(10,12,11)(13,14,15),
462
(1,3,2)(4,9,13)(5,11,7)(6,15,10)(8,12,14),
463
(1,13)(2,7)(3,10)(4,11)(5,15)(6,9),
464
(1,8,13)(2,7,12)(3,9,5)(4,14,11)(6,10,15),
465
(2,3)(4,14)(5,7)(8,13)(9,12)(10,15),
466
(1,8)(2,3,11,6)(4,12,10,15)(5,7,14,9) ])
467
gap> NrMovedPoints(op);
468
15
469
]]></Example>
470
<P/>
471
A problem with this approach is that creating (and storing) all cosets can
472
be very memory intensive if the subgroup index gets large.
473
Because of this, &GAP; provides special
474
objects which act like a list of elements, but do not actually store
475
elements but compute them on the go. Such a simulated list is called an
476
<E>enumerator</E>. The easiest example of this concept is the
477
<Ref Func="Enumerator" BookName="ref"/> of a group.
478
While it behaves like a list of elements, it requires far less storage, and
479
is applicable to potentially huge groups for which it would be completely
480
infeasible to write down all elements:
481
<Example><![CDATA[
482
gap> enum:=Enumerator(SymmetricGroup(20));
483
<enumerator of perm group>
484
gap> Length(enum);
485
2432902008176640000
486
gap> enum[123456789012345];
487
(1,4,15,3,14,11,8,17,6,18,5,7,20,13,10,9,2,12)
488
gap> Position(enum,(1,2,3,4,5,6,7,8,9,10));
489
71948729603
490
]]></Example>
491
<P/>
492
For the action on cosets the object of interest is the
493
<Ref Func="RightTransversal" BookName="ref"/> of a subgroup. Again, it does
494
not write out actual elements and thus can be created even for subgroups of
495
large index.
496
<Example><![CDATA[
497
gap> t:=RightTransversal(a8,norm);
498
RightTransversal(Alt( [ 1 .. 8 ] ),2^3:L_3(2))
499
gap> t[7];
500
(4,6,5)
501
gap> Position(t,(4,6,7,8,5));
502
8
503
gap> Position(t,(1,2,3));
504
fail
505
]]></Example>
506
<P/>
507
For the action on cosets there is the added complication that not
508
every group element is in the transversal (as the last example shows) but
509
the action on cosets of a subgroup
510
usually will not preserve a chosen set of coset representatives.
511
Because of this issue, all action functionality actually uses
512
<Ref Func="PositionCanonical" BookName="ref"/> instead of
513
<Ref Func="Position" BookName="ref"/>. In general, for elements contained in
514
a list,
515
<Ref Func="PositionCanonical" BookName="ref"/> returns the same as
516
<C>Position</C>. If the element is not contained in the list (and for
517
special lists, such as transversals), <C>PositionCanonical</C> returns the
518
list element representing the same objects, e.g. the transversal element
519
representing the same coset.
520
<Example><![CDATA[
521
gap> PositionCanonical(t,(1,2,3));
522
2
523
gap> t[2];
524
(6,7,8)
525
gap> t[2]/(1,2,3);
526
(1,3,2)(6,7,8)
527
gap> last in norm;
528
true
529
]]></Example>
530
Thus, acting on a <C>RightTransversal</C> with the <C>OnRight</C> action
531
will in fact (in a slight abuse of definitions)
532
produce the action of a group on cosets of a subgroup and is in general the
533
most efficient way of creating this action.
534
<Example><![CDATA[
535
gap> Action(a8,RightTransversal(a8,norm),OnRight);
536
Group([ (1,2,3)(4,6,5)(7,8,9)(10,12,11)(13,14,15),
537
(1,3,2)(4,9,13)(5,11,7)(6,15,10)(8,12,14),
538
(1,13)(2,7)(3,10)(4,11)(5,15)(6,9),
539
(1,8,13)(2,7,12)(3,9,5)(4,14,11)(6,10,15),
540
(2,3)(4,14)(5,7)(8,13)(9,12)(10,15),
541
(1,8)(2,3,11,6)(4,12,10,15)(5,7,14,9) ])
542
]]></Example>
543
<P/>
544
545
<E>Summary.</E> In this section we have learned how groups can operate on
546
&GAP; objects such as integers and group elements. We have used
547
<Ref Func="ActionHomomorphism" BookName="ref"/>,
548
among others, to construct the corresponding actions and homomorphisms
549
and have seen how transversals can be used to create the action on cosets of
550
a subgroup.
551
</Section>
552
553
554
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
555
<Section Label="Subgroups!as Stabilizers">
556
<Heading>Subgroups as Stabilizers</Heading>
557
558
Action functions can also be used without constructing external sets.
559
We will try to find several subgroups in <C>a8</C> as stabilizers of such
560
actions. One subgroup is immediately available, namely the stabilizer
561
of one point. The index of the stabilizer must of course be equal to the
562
length of the orbit, i.e.,&nbsp;8.
563
<P/>
564
<Example><![CDATA[
565
gap> u8 := Stabilizer( a8, 1 );
566
Group([ (2,3,4,5,6,7,8), (2,4,5,6,7,8,3) ])
567
gap> Index( a8, u8 );
568
8
569
gap> Orbit( a8, 1 ); Length( last );
570
[ 1, 3, 2, 4, 5, 6, 7, 8 ]
571
8
572
]]></Example>
573
<P/>
574
This gives us a hint how to find further subgroups. Each subgroup is the
575
stabilizer of a point of an appropriate transitive action (namely the
576
action on the cosets of that subgroup or another action that is
577
equivalent to this action). So the question is how to find other
578
actions. The obvious thing is to operate on pairs of points.
579
So using the function <Ref Func="Tuples" BookName="ref"/> we first generate
580
a list of all pairs.
581
<P/>
582
<Example><![CDATA[
583
gap> pairs := Tuples( [1..8], 2 );;
584
]]></Example>
585
<P/>
586
Now we would like to have <C>a8</C> operate on this domain.
587
But we cannot use the default action <Ref Func="OnPoints" BookName="ref"/>
588
because powering a list by a permutation via the caret operator <C>^</C>
589
is not defined. So we must tell the functions from the actions package how
590
the group elements operate on the elements of the domain
591
(here and below, the word <Q>package</Q> refers to the &GAP; functionality
592
for group actions, not to a &GAP; package). In our example
593
we can do this by simply passing <Ref Func="OnPairs" BookName="ref"/>
594
as an optional last argument.
595
All functions from the actions package accept such an optional argument
596
that describes the action.
597
One example is <Ref Func="IsTransitive" BookName="ref"/>.
598
<P/>
599
<Example><![CDATA[
600
gap> IsTransitive( a8, pairs, OnPairs );
601
false
602
]]></Example>
603
<P/>
604
The action is of course not transitive, since the pairs <C>[ 1, 1 ]</C> and
605
<C>[ 1, 2 ]</C> cannot lie in the same orbit.
606
So we want to find out what the orbits are.
607
The function <Ref Func="Orbits" BookName="ref"/> does that for us.
608
It returns a list of all the orbits.
609
We look at the orbit lengths and representatives for the orbits.
610
<P/>
611
<Example><![CDATA[
612
gap> orbs := Orbits( a8, pairs, OnPairs );; Length( orbs );
613
2
614
gap> List( orbs, Length );
615
[ 8, 56 ]
616
gap> List( orbs, o -> o[1] );
617
[ [ 1, 1 ], [ 1, 2 ] ]
618
]]></Example>
619
<P/>
620
The action of <C>a8</C> on the first orbit (this is the one containing
621
<C>[1,1]</C>, try <C>[1,1] in orbs[1]</C>) is of course equivalent to the original
622
action, so we ignore it and work with the second orbit.
623
<P/>
624
<Example><![CDATA[
625
gap> u56 := Stabilizer( a8, orbs[2][1], OnPairs );; Index( a8, u56 );
626
56
627
]]></Example>
628
<P/>
629
So now we have found a second subgroup. To make the following
630
computations a little bit easier and more efficient we would now like to
631
work on the points <C>[ 1 .. 56 ]</C> instead of the list of pairs.
632
The function <Ref Func="ActionHomomorphism" BookName="ref"/> does what we
633
need.
634
It creates a homomorphism defined on <C>a8</C> whose image is a new group
635
that acts on <C>[ 1 .. 56 ]</C> in
636
the same way that <C>a8</C> acts on the second orbit.
637
<P/>
638
<Example><![CDATA[
639
gap> h56 := ActionHomomorphism( a8, orbs[2], OnPairs );;
640
gap> a8_56 := Image( h56 );;
641
]]></Example>
642
<P/>
643
We would now like to know if the subgroup <C>u56</C> of index 56 that we found
644
is maximal or not.
645
As we have used already in Section&nbsp;<Ref Sect="Actions of Groups"/>,
646
a subgroup is maximal if and only if the action on the cosets of this
647
subgroup is primitive.
648
<P/>
649
<Example><![CDATA[
650
gap> IsPrimitive( a8_56, [1..56] );
651
false
652
]]></Example>
653
<P/>
654
Remember that we can leave out the function if we mean
655
<Ref Func="OnPoints" BookName="ref"/>
656
but that we have to specify the action domain for all action functions.
657
<P/>
658
We see that <C>a8_56</C> is not primitive. This means of course that the
659
action of <C>a8</C> on <C>orb[2]</C> is not primitive, because those two
660
actions are equivalent. So the stabilizer <C>u56</C> is not maximal. Let us
661
try to find its supergroups.
662
We use the function <Ref Func="Blocks" BookName="ref"/> to find a block
663
system. The (optional) third argument in the following example tells
664
<Ref Func="Blocks" BookName="ref"/> that we want a block system
665
where 1 and 3 lie in one block.
666
<P/>
667
<Example><![CDATA[
668
gap> blocks := Blocks( a8_56, [1..56], [1,3] );;
669
]]></Example>
670
<P/>
671
The result is a list of sets, such that <C>a8_56</C> acts on those sets.
672
Now we would like the stabilizer of this action on the sets.
673
Because we want to operate on the sets we have to pass
674
<Ref Func="OnSets" BookName="ref"/> as third argument.
675
<P/>
676
<Example><![CDATA[
677
gap> u8_56 := Stabilizer( a8_56, blocks[1], OnSets );;
678
gap> Index( a8_56, u8_56 );
679
8
680
gap> u8b := PreImages( h56, u8_56 );; Index( a8, u8b );
681
8
682
gap> IsConjugate( a8, u8, u8b );
683
true
684
]]></Example>
685
<P/>
686
So we have found a supergroup of <C>u56</C> that is conjugate in <C>a8</C> to <C>u8</C>.
687
This is not surprising, since <C>u8</C> is a point stabilizer, and <C>u56</C> is a
688
two point stabilizer in the natural action of <C>a8</C> on eight points.
689
<P/>
690
Here is a <E>warning</E>:
691
If you specify <Ref Func="OnSets" BookName="ref"/> as third argument to a
692
function like <Ref Func="Stabilizer" BookName="ref"/>,
693
you have to make sure that the point (i.e.
694
the second argument) is indeed a set. Otherwise you will get a puzzling
695
error message or even wrong results!
696
In the above example, the second argument <C>blocks[1]</C> came from the
697
function <Ref Func="Blocks" BookName="ref"/>, which returns a
698
list of sets, so everything was OK.
699
<P/>
700
Actually there is a third block system of <C>a8_56</C> that gives rise to a
701
third subgroup.
702
<P/>
703
<Example><![CDATA[
704
gap> blocks := Blocks( a8_56, [1..56], [1,13] );;
705
gap> u28_56 := Stabilizer( a8_56, [1,13], OnSets );;
706
gap> u28 := PreImages( h56, u28_56 );;
707
gap> Index( a8, u28 );
708
28
709
]]></Example>
710
<P/>
711
We know that the subgroup <C>u28</C> of index 28 is maximal, because we know
712
that <C>a8</C> has no subgroups of index 2, 4, or 7. However we can also
713
quickly verify this by checking that <C>a8_56</C> acts primitively on the
714
28 blocks.
715
<P/>
716
<Example><![CDATA[
717
gap> IsPrimitive( a8_56, blocks, OnSets );
718
true
719
]]></Example>
720
<P/>
721
<Ref Func="Stabilizer" BookName="ref"/> is not only applicable to groups
722
like <C>a8</C> but also to their
723
subgroups like <C>u56</C>. So another method to find a new subgroup is to
724
compute the stabilizer of another point in <C>u56</C>. Note that <C>u56</C> already
725
leaves 1 and 2 fixed.
726
<P/>
727
<Example><![CDATA[
728
gap> u336 := Stabilizer( u56, 3 );;
729
gap> Index( a8, u336 );
730
336
731
]]></Example>
732
<P/>
733
Other functions are also applicable to subgroups. In the following we
734
show that <C>u336</C> acts regularly on the 60&nbsp;triples of
735
<C>[ 4 .. 8 ]</C> which
736
contain no element twice.
737
We construct the list of these 60&nbsp;triples with
738
the function <Ref Func="Orbit" BookName="ref"/>
739
(using <Ref Func="OnTuples" BookName="ref"/> as the natural generalization
740
of <Ref Func="OnPairs" BookName="ref"/>)
741
and then pass it as action domain to the function
742
<Ref Func="IsRegular" BookName="ref"/>.
743
The positive result of the regularity test means that this
744
action is equivalent to the actions of <C>u336</C> on its 60 elements
745
from the right.
746
<P/>
747
<Example><![CDATA[
748
gap> IsRegular( u336, Orbit( u336, [4,5,6], OnTuples ), OnTuples );
749
true
750
]]></Example>
751
<P/>
752
Just as we did in the case of the action on the pairs above, we now
753
construct a new permutation group that acts on <C>[ 1 .. 336 ]</C>
754
in the same way that <C>a8</C> acts on the cosets of <C>u336</C>.
755
But this time we let <C>a8</C> operate on a right transversal,
756
just like <C>norm</C> did in the natural homomorphism above.
757
<P/>
758
<Example><![CDATA[
759
gap> t := RightTransversal( a8, u336 );;
760
gap> a8_336 := Action( a8, t, OnRight );;
761
]]></Example>
762
<P/>
763
To find subgroups above <C>u336</C> we again look for nontrivial block systems.
764
<P/>
765
<Example><![CDATA[
766
gap> blocks := Blocks( a8_336, [1..336] );; blocks[1];
767
[ 1, 43, 85 ]
768
]]></Example>
769
<P/>
770
We see that the union of <C>u336</C> with its 43rd and its 85th coset
771
is a subgroup in <C>a8_336</C>, its index is 112.
772
We can obtain it as the closure of <C>u336</C> with a representative
773
of the 43rd coset, which can be found as the 43rd element
774
of the transversal&nbsp;<C>t</C>.
775
Note that in the representation <C>a8_336</C> on 336 points,
776
this subgroup corresponds to the stabilizer of the block <C>[ 1, 43, 85 ]</C>.
777
<P/>
778
<Example><![CDATA[
779
gap> u112 := ClosureGroup( u336, t[43] );;
780
gap> Index( a8, u112 );
781
112
782
]]></Example>
783
<P/>
784
Above this subgroup of index 112 lies a subgroup of index 56, which is
785
not conjugate to <C>u56</C>. In fact, unlike <C>u56</C> it is maximal. We obtain
786
this subgroup in the same way that we obtained <C>u112</C>, this time forcing
787
two points, namely 7 and 43 into the first block.
788
<P/>
789
<Example><![CDATA[
790
gap> blocks := Blocks( a8_336, [1..336], [1,7,43] );;
791
gap> Length( blocks );
792
56
793
gap> u56b := ClosureGroup( u112, t[7] );; Index( a8, u56b );
794
56
795
gap> IsPrimitive( a8_336, blocks, OnSets );
796
true
797
]]></Example>
798
<P/>
799
We already mentioned in Section&nbsp;<Ref Sect="Actions of Groups"/>
800
that there is another standard
801
action of permutations, namely the conjugation.
802
E.g., since no other action is specified in the following example,
803
<Ref Func="OrbitLength" BookName="ref"/> simply acts via
804
<Ref Func="OnPoints" BookName="ref"/>,
805
and because <A>perm_1</A><C> ^ </C><A>perm_2</A> is defined as the conjugation
806
of <A>perm_2</A> on <A>perm_1</A>, in fact we compute the length of
807
the conjugacy class of <C>(1,2)(3,4)(5,6)(7,8)</C>.
808
<P/>
809
<Example><![CDATA[
810
gap> OrbitLength( a8, (1,2)(3,4)(5,6)(7,8) );
811
105
812
gap> orb := Orbit( a8, (1,2)(3,4)(5,6)(7,8) );;
813
gap> u105 := Stabilizer( a8, (1,2)(3,4)(5,6)(7,8) );; Index( a8, u105 );
814
105
815
]]></Example>
816
<P/>
817
Note that although the length of a conjugacy class of any element <M>g</M>
818
in any finite group <M>G</M> can be computed as
819
<C>OrbitLength( </C><M>G</M><C>, </C><M>g</M><C> )</C>,
820
the command <C>Size( ConjugacyClass( </C><M>G</M><C>, </C><M>g</M><C> ) )</C>
821
is probably more efficient.
822
<P/>
823
<Example><![CDATA[
824
gap> Size( ConjugacyClass( a8, (1,2)(3,4)(5,6)(7,8) ) );
825
105
826
]]></Example>
827
<P/>
828
Of course the stabilizer <C>u105</C> is in fact the centralizer of the element
829
<C>(1,2)(3,4)(5,6)(7,8)</C>.
830
<Ref Func="Stabilizer" BookName="ref"/> notices that and computes the
831
stabilizer using the centralizer algorithm for permutation groups. In the
832
usual way we now look for the subgroups above <C>u105</C>.
833
<P/>
834
<Example><![CDATA[
835
gap> blocks := Blocks( a8, orb );; Length( blocks );
836
15
837
gap> blocks[1];
838
[ (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8), (1,4)(2,3)(5,8)(6,7),
839
(1,5)(2,6)(3,7)(4,8), (1,6)(2,5)(3,8)(4,7), (1,7)(2,8)(3,5)(4,6),
840
(1,8)(2,7)(3,6)(4,5) ]
841
]]></Example>
842
<P/>
843
To find the subgroup of index 15 we again use closure. Now we must be a
844
little bit careful to avoid confusion. <C>u105</C> is the stabilizer of
845
<C>(1,2)(3,4)(5,6)(7,8)</C>. We know that there is a correspondence between
846
the points of the orbit and the cosets of <C>u105</C>. The point
847
<C>(1,2)(3,4)(5,6)(7,8)</C> corresponds to <C>u105</C>.
848
To get the subgroup above <C>u105</C> that has index 15 in <C>a8</C>,
849
we must form the closure of <C>u105</C> with an element of the coset that
850
corresponds to any other point in the first block.
851
If we choose the point <C>(1,3)(2,4)(5,8)(6,7)</C>,
852
we must use an element of <C>a8</C> that maps <C>(1,2)(3,4)(5,6)(7,8)</C> to
853
<C>(1,3)(2,4)(5,8)(6,7)</C>.
854
The function <Ref Func="RepresentativeAction" BookName="ref"/> does
855
what we need.
856
It takes a group and two points and returns an element of the group
857
that maps the first point to the second.
858
In fact it also allows you to specify the action as an optional fourth
859
argument as usual, but we do not need this here.
860
If no such element exists in the group, i.e., if the two points do not
861
lie in one orbit under the group,
862
<Ref Func="RepresentativeAction" BookName="ref"/> returns <K>fail</K>.
863
<P/>
864
<Example><![CDATA[
865
gap> rep := RepresentativeAction( a8, (1,2)(3,4)(5,6)(7,8),
866
> (1,3)(2,4)(5,8)(6,7) );
867
(2,3)(6,8)
868
gap> u15 := ClosureGroup( u105, rep );; Index( a8, u15 );
869
15
870
]]></Example>
871
<P/>
872
<C>u15</C> is of course a maximal subgroup, because <C>a8</C> has no subgroups of
873
index 3 or&nbsp;5. There is in fact another class of subgroups of index 15
874
above <C>u105</C> that we get by adding <C>(2,3)(6,7)</C> to <C>u105</C>.
875
<P/>
876
<Example><![CDATA[
877
gap> u15b := ClosureGroup( u105, (2,3)(6,7) );; Index( a8, u15b );
878
15
879
gap> RepresentativeAction( a8, u15, u15b );
880
fail
881
]]></Example>
882
<P/>
883
<Ref Func="RepresentativeAction" BookName="ref"/> tells us that there is no
884
element <M>g</M> in <C>a8</C>
885
such that <C>u15 ^ </C><M>g</M><C> = u15b</C>.
886
Because <C>^</C> also denotes the conjugation of subgroups
887
this tells us that <C>u15</C> and <C>u15b</C> are not conjugate.
888
<P/>
889
<E>Summary.</E> In this section we have demonstrated some functions from
890
the actions package. There is a whole class of functions that we did
891
not mention, namely those that take a single element instead of a whole
892
group as first argument, e.g., <Ref Func="Cycle" BookName="ref"/> and
893
<Ref Func="Permutation" BookName="ref"/>. These are fully
894
described in Chapter <Ref Chap="Group Actions" BookName="ref"/>.
895
896
</Section>
897
898
899
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
900
<Section Label="Group Homomorphisms!by Images">
901
<Heading>Group Homomorphisms by Images</Heading>
902
903
We have already seen examples of group homomorphisms in the last
904
sections, namely natural homomorphisms and action homomorphisms.
905
In this section we will show how to construct a group homomorphism
906
<M>G \rightarrow H</M>
907
by specifying a generating set for <M>G</M> and the images of these generators
908
in&nbsp;<M>H</M>.
909
We use the function
910
<C>GroupHomomorphismByImages( <A>G</A>, <A>H</A>, <A>gens</A>,
911
<A>imgs</A> )</C> where <A>gens</A> is a generating set for <A>G</A> and <A>imgs</A> is a list
912
whose <M>i</M>th entry is the image of <M><A>gens</A>[i]</M> under the homomorphism.
913
<P/>
914
<Example><![CDATA[
915
gap> s4 := Group((1,2,3,4),(1,2));; s3 := Group((1,2,3),(1,2));;
916
gap> hom := GroupHomomorphismByImages( s4, s3,
917
> GeneratorsOfGroup(s4), [(1,2),(2,3)] );
918
[ (1,2,3,4), (1,2) ] -> [ (1,2), (2,3) ]
919
gap> Kernel( hom );
920
Group([ (1,4)(2,3), (1,3)(2,4) ])
921
gap> Image( hom, (1,2,3) );
922
(1,2,3)
923
gap> Size( Image( hom, DerivedSubgroup(s4) ) );
924
3
925
]]></Example>
926
<P/>
927
<Log><![CDATA[
928
gap> PreImage( hom, (1,2,3) );
929
Error, <map> must be an inj. and surj. mapping called from
930
<function "PreImage">( <arguments> )
931
called from read-eval loop at line 4 of *stdin*
932
you can 'quit;' to quit to outer loop, or
933
you can 'return;' to continue
934
brk> quit;
935
]]></Log>
936
<P/>
937
<Example><![CDATA[
938
gap> PreImagesRepresentative( hom, (1,2,3) );
939
(1,4,2)
940
gap> PreImage( hom, TrivialSubgroup(s3) ); # the kernel
941
Group([ (1,4)(2,3), (1,3)(2,4) ])
942
]]></Example>
943
<P/>
944
This homomorphism from <M>S_4</M> onto <M>S_3</M> is well known from elementary
945
group theory. Images of elements and subgroups under <C>hom</C> can be
946
calculated with the function <Ref Func="Image" BookName="ref"/>.
947
But since the mapping <C>hom</C> is not bijective, we cannot use the
948
function <Ref Func="PreImage" BookName="ref"/> for preimages of
949
elements (they can have several preimages). Instead, we have to use
950
<Ref Func="PreImagesRepresentative" BookName="ref"/>,
951
which returns one preimage if at least one
952
exists (and would return <K>fail</K> if none exists, which cannot occur for
953
our surjective <C>hom</C>).
954
On the other hand, we can use <Ref Func="PreImage" BookName="ref"/> for the
955
preimage of a set (which always exists, even if it is empty).
956
<P/>
957
Suppose we mistype the input when trying to construct a homomorphism as below.
958
<P/>
959
<Example><![CDATA[
960
gap> GroupHomomorphismByImages( s4, s3,
961
> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );
962
fail
963
]]></Example>
964
<P/>
965
There is no such homomorphism, hence <K>fail</K> is returned.
966
But note that because of this,
967
<Ref Func="GroupHomomorphismByImages" BookName="ref"/> must do
968
some checks, and this was also done for the mapping <C>hom</C> above.
969
One can avoid these checks if one is sure that the desired
970
homomorphism really exists.
971
For that,
972
the function <Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>
973
can be used; the <C>NC</C> stands for <Q>no check</Q>.
974
<P/>
975
But note that horrible things can happen if
976
<Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>
977
is used when the input does not describe a homomorphism.
978
<P/>
979
<Log><![CDATA[
980
gap> hom2 := GroupHomomorphismByImagesNC( s4, s3,
981
> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );
982
[ (1,2,3,4), (1,2) ] -> [ (1,2,3), (2,3) ]
983
gap> Size( Kernel(hom2) );
984
24
985
]]></Log>
986
<P/>
987
In other words, &GAP; claims that the kernel is the full <C>s4</C>,
988
yet <C>hom2</C> obviously has some non-trivial images!
989
Clearly there is no such thing as a homomorphism
990
which maps an element of order&nbsp;4 (namely, (1,2,3,4))
991
to an element of order&nbsp;3 (namely, (1,2,3)).
992
<E>But if you use the command
993
<Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>,
994
&GAP; trusts you.</E>
995
<P/>
996
<Log><![CDATA[
997
gap> IsGroupHomomorphism( hom2 );
998
true
999
]]></Log>
1000
<P/>
1001
And then it produces serious nonsense if the thing is not a homomorphism,
1002
as seen above!
1003
<P/>
1004
Besides the safe command
1005
<Ref Func="GroupHomomorphismByImages" BookName="ref"/>,
1006
which returns <K>fail</K> if the requested homomorphism does not exist,
1007
there is the function
1008
<Ref Func="GroupGeneralMappingByImages" BookName="ref"/>,
1009
which returns a general mapping (that is, a possibly multi-valued
1010
mapping) that can be tested with
1011
<Ref Func="IsGroupHomomorphism" BookName="ref"/>.
1012
<P/>
1013
<Example><![CDATA[
1014
gap> hom2 := GroupGeneralMappingByImages( s4, s3,
1015
> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );;
1016
gap> IsGroupHomomorphism( hom2 );
1017
false
1018
]]></Example>
1019
<P/>
1020
<Index>group general mapping</Index><Index>cokernel</Index><Index>kernel</Index>
1021
<Index Key="GroupHomomorphismByImages vs. GroupGeneralMappingByImages"><C>GroupHomomorphismByImages</C> vs. <C>GroupGeneralMappingByImages</C></Index>
1022
But the possibility of testing for being a homomorphism is not the only
1023
reason why &GAP; offers <E>group general mappings</E>. Another (more
1024
important?) reason is that their existence allows <Q>reversal of arrows</Q>
1025
in a homomorphism such as our original <C>hom</C>.
1026
By this we mean the <Ref Func="GroupHomomorphismByImages" BookName="ref"/>
1027
with left and right sides exchanged, in which
1028
case it is of course merely a
1029
<Ref Func="GroupGeneralMappingByImages" BookName="ref"/>.
1030
<P/>
1031
<Example><![CDATA[
1032
gap> rev := GroupGeneralMappingByImages( s3, s4,
1033
> [(1,2),(2,3)], GeneratorsOfGroup(s4) );;
1034
]]></Example>
1035
<P/>
1036
Now <M>hom</M> maps <M>a</M> to <M>b</M> if and only if
1037
<M>rev</M> maps <M>b</M> to <M>a</M>,
1038
for <M>a \in</M> <C>s4</C> and <M>b \in</M> <C>s3</C>.
1039
Since every such <M>b</M> has four preimages under <C>hom</C>,
1040
it now has four images under <C>rev</C>.
1041
Just as the four preimages form a coset of the kernel
1042
<M>V_4 \leq </M><C>s4</C> of <C>hom</C>,
1043
they also form a coset of the <E>cokernel</E> <M>V_4 \leq </M><C>s4</C> of
1044
<C>rev</C>.
1045
The cokernel itself is the set of all images of <C>One( s3 )</C>.
1046
(It is a normal subgroup in the group of all images under <C>rev</C>.)
1047
The operation <Ref Func="One" BookName="ref"/> returns the identity element
1048
of a group.
1049
And this is why &GAP; wants to perform such a reversal of arrows:
1050
it calculates the kernel of a homomorphism like <C>hom</C>
1051
as the cokernel of the reversed group general mapping (here <C>rev</C>).
1052
<P/>
1053
<Example><![CDATA[
1054
gap> CoKernel( rev );
1055
Group([ (1,4)(2,3), (1,3)(2,4) ])
1056
]]></Example>
1057
<P/>
1058
<Index Subkey="single-valued">group general mapping</Index>
1059
<Index Subkey="total">group general mapping</Index>
1060
The reason why <C>rev</C> is not a homomorphism is that it is not
1061
single-valued (because <C>hom</C> was not injective). But there is another
1062
critical condition: If we reverse the arrows of a non-surjective
1063
homomorphism, we obtain a group general mapping which is not defined
1064
everywhere, i.e., which is not total (although it will be single-valued
1065
if the original homomorphism is injective). &GAP; requires that a group
1066
homomorphism be both single-valued and total,
1067
so you will get <K>fail</K> if you say
1068
<C>GroupHomomorphismByImages( <A>G</A>, <A>H</A>, <A>gens</A>, <A>imgs</A> )</C> where <A>gens</A> does
1069
not generate <A>G</A> (even if this would give a decent homomorphism on the
1070
subgroup generated by <A>gens</A>). For a full description,
1071
see Chapter <Ref Chap="Group Homomorphisms" BookName="ref"/>.
1072
<P/>
1073
The last example of this section shows that the notion of kernel and
1074
cokernel naturally extends even to the case where neither <C>hom2</C> nor its
1075
inverse general mapping (with arrows reversed) is a homomorphism.
1076
<P/>
1077
<Example><![CDATA[
1078
gap> CoKernel( hom2 ); Kernel( hom2 );
1079
Group([ (2,3), (1,3) ])
1080
Group([ (3,4), (2,3,4), (1,2,4) ])
1081
gap> IsGroupHomomorphism( InverseGeneralMapping( hom2 ) );
1082
false
1083
]]></Example>
1084
<P/>
1085
<E>Summary.</E> In this section we have constructed homomorphisms by
1086
specifying images for a set of generators. We have seen that by reversing
1087
the direction of the mapping, we get group general mappings, which need
1088
not be single-valued (unless the mapping was injective) nor total (unless
1089
the mapping was surjective).
1090
1091
</Section>
1092
1093
1094
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
1095
<Section Label="Nice Monomorphisms">
1096
<Heading>Nice Monomorphisms</Heading>
1097
1098
For some types of groups, the best method to calculate in an isomorphic
1099
group in a <Q>better</Q> representation (say, a permutation group).
1100
We call an injective homomorphism,
1101
that will give such an isomorphic image a <Q>nice monomorphism</Q>.
1102
<P/>
1103
For example in the case of a matrix group we can take the action on the
1104
underlying vector space (or a suitable subset) to obtain such a
1105
monomorphism:
1106
<P/>
1107
<Example><![CDATA[
1108
gap> grp:=GL(2,3);;
1109
gap> dom:=GF(3)^2;;
1110
gap> hom := ActionHomomorphism( grp, dom );; IsInjective( hom );
1111
true
1112
gap> p := Image( hom,grp );
1113
Group([ (4,7)(5,8)(6,9), (2,7,6)(3,4,8) ])
1114
]]></Example>
1115
<P/>
1116
To demonstrate the technique of nice monomorphisms, we compute the
1117
conjugacy classes of the permutation group and lift them back into the
1118
matrix group with the monomorphism <C>hom</C>. Lifting back a conjugacy class
1119
means finding the preimage of the representative and of the centralizer;
1120
the latter is called <Ref Func="StabilizerOfExternalSet" BookName="ref"/>
1121
in &GAP; (because conjugacy classes are represented as external sets, see
1122
Section&nbsp;<Ref Sect="Conjugacy Classes" BookName="ref"/>).
1123
<P/>
1124
<Example><![CDATA[
1125
gap> pcls := ConjugacyClasses( p );; gcls := [ ];;
1126
gap> for pc in pcls do
1127
> gc:=ConjugacyClass(grp,
1128
> PreImagesRepresentative(hom,Representative(pc)));
1129
> SetStabilizerOfExternalSet(gc,PreImage(hom,
1130
> StabilizerOfExternalSet(pc)));
1131
> Add( gcls, gc );
1132
> od;
1133
gap> List( gcls, Size );
1134
[ 1, 8, 12, 1, 8, 6, 6, 6 ]
1135
]]></Example>
1136
<P/>
1137
All the steps we have made above are automatically performed by &GAP;
1138
if you simply ask for <C>ConjugacyClasses( grp )</C>,
1139
provided that &GAP; already knows that <C>grp</C> is finite
1140
(e.g., because you asked <C>IsFinite( grp )</C> before).
1141
The reason for this is that a finite matrix group like <C>grp</C> is
1142
<Q>handled by a nice monomorphism</Q>.
1143
For such groups, &GAP; uses the command
1144
<Ref Func="NiceMonomorphism" BookName="ref"/>
1145
to construct a monomorphism (such as the <C>hom</C> in the previous example)
1146
and then proceeds as we have done above.
1147
<P/>
1148
<Example><![CDATA[
1149
gap> grp:=GL(2,3);;
1150
gap> IsHandledByNiceMonomorphism( grp );
1151
true
1152
gap> hom := NiceMonomorphism( grp );
1153
<action isomorphism>
1154
gap> p :=Image(hom,grp);
1155
Group([ (4,7)(5,8)(6,9), (2,7,6)(3,4,8) ])
1156
gap> cc := ConjugacyClasses( grp );; ForAll(cc, x-> x in gcls);
1157
true
1158
gap> ForAll(gcls, x->x in cc); # cc and gcls might be ordered differently
1159
true
1160
]]></Example>
1161
<P/>
1162
Note that a nice monomorphism might be defined on a larger group than
1163
<C>grp</C>
1164
&ndash;so we have to use <C>Image( hom, grp )</C> and not only
1165
<C>Image( hom )</C>.
1166
<P/>
1167
Nice monomorphisms are not only used for matrix groups, but also for
1168
other kinds of groups in which one cannot calculate easily enough. As
1169
another example, let us show that the automorphism group of the
1170
quaternion group of order&nbsp;8 is isomorphic to the symmetric group of
1171
degree&nbsp;4 by examining the <Q>nice object</Q> associated with that
1172
automorphism group.
1173
<P/>
1174
<Example><![CDATA[
1175
gap> p:=Group((1,7,6,8)(2,5,3,4), (1,2,6,3)(4,8,5,7));;
1176
gap> aut := AutomorphismGroup( p );; NiceMonomorphism(aut);;
1177
gap> niceaut := NiceObject( aut );
1178
Group([ (1,4,2,3), (1,5,4)(2,6,3), (1,2)(3,4), (3,4)(5,6) ])
1179
gap> IsomorphismGroups( niceaut, SymmetricGroup( 4 ) );
1180
[ (1,4,2,3), (1,5,4)(2,6,3), (1,2)(3,4), (3,4)(5,6) ] ->
1181
[ (1,4,3,2), (1,3,2), (1,3)(2,4), (1,2)(3,4) ]
1182
]]></Example>
1183
<P/>
1184
The range of a nice monomorphism is in most cases a permutation group,
1185
because nice monomorphisms are mostly action homomorphisms. In some
1186
cases, like in our last example, the group is solvable and you might
1187
prefer a pc group as nice object. You cannot change the nice monomorphism
1188
of the automorphism group (because it is the value of the attribute
1189
<Ref Func="NiceMonomorphism" BookName="ref"/>),
1190
but you can compose it with an isomorphism from the permutation group
1191
to a pc group to obtain your personal nicer monomorphism.
1192
If you reconstruct the automorphism group, you can even prescribe it
1193
this nicer monomorphism as its <Ref Func="NiceMonomorphism" BookName="ref"/>,
1194
because a newly-constructed group will not yet have a
1195
<Ref Func="NiceMonomorphism" BookName="ref"/> set.
1196
<P/>
1197
<Example><![CDATA[
1198
gap> nicer := NiceMonomorphism(aut) * IsomorphismPcGroup(niceaut);;
1199
gap> aut2 := GroupByGenerators( GeneratorsOfGroup( aut ) );;
1200
gap> SetIsHandledByNiceMonomorphism( aut2, true );
1201
gap> SetNiceMonomorphism( aut2, nicer );
1202
gap> NiceObject( aut2 ); # a pc group
1203
Group([ f1*f2, f2^2*f3, f4, f3 ])
1204
]]></Example>
1205
<P/>
1206
The star <C>*</C> denotes composition of mappings from the left to the right,
1207
as we have seen in Section <Ref Sect="Actions of Groups"/> above.
1208
Reconstructing the
1209
automorphism group may of course result in the loss of other information
1210
&GAP; had already gathered, besides the (not-so-)nice monomorphism.
1211
<P/>
1212
<E>Summary.</E> In this section we have seen how calculations in groups
1213
can be carried out in isomorphic images in nicer groups. We have seen
1214
that &GAP; pursues this technique automatically for certain classes of
1215
groups, e.g., for matrix groups that are known to be finite.
1216
1217
</Section>
1218
1219
1220
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
1221
<Section Label="Further Information about Groups and Homomorphisms">
1222
<Heading>Further Information about Groups and Homomorphisms</Heading>
1223
1224
Groups and the functions for groups are treated in
1225
Chapter&nbsp;<Ref Chap="Groups" BookName="ref"/>.
1226
There are several chapters dealing with groups in specific representations,
1227
for example Chapter&nbsp;<Ref Chap="Permutation Groups" BookName="ref"/>
1228
on permutation groups,
1229
<Ref Chap="Polycyclic Groups" BookName="ref"/>
1230
on polycyclic (including finite solvable) groups,
1231
<Ref Chap="Matrix Groups" BookName="ref"/> on matrix groups and
1232
<Ref Chap="Finitely Presented Groups" BookName="ref"/> on
1233
finitely presented groups.
1234
Chapter&nbsp;<Ref Chap="Group Actions" BookName="ref"/> deals
1235
with group actions.
1236
Group homomorphisms are the subject of
1237
Chapter&nbsp;<Ref Chap="Group Homomorphisms" BookName="ref"/>.
1238
1239
</Section>
1240
</Chapter>
1241
1242
1243
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
1244
<!-- %% -->
1245
<!-- %E -->
1246
1247
1248