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

Views: 418346
1
<Chapter Label="Funct">
2
<Heading>&Circle; functions</Heading>
3
4
To use the &Circle; package first you need to load it as follows:
5
6
<Log>
7
<![CDATA[
8
gap> LoadPackage("circle");
9
-----------------------------------------------------------------------------
10
Loading Circle 1.4.0 (Adjoint groups of finite rings)
11
by Alexander Konovalov (http://www.cs.st-andrews.ac.uk/~alexk/) and
12
Panagiotis Soules ([email protected]).
13
-----------------------------------------------------------------------------
14
true
15
gap>
16
]]>
17
</Log>
18
19
Note that if you entered examples from the previous chapter, you need
20
to restart &GAP; before loading the &Circle; package.
21
22
23
<Section Label="CircleObjects">
24
<Heading>Circle objects</Heading>
25
26
Because for elements of the ring <M>R</M> the ordinary multiplication
27
is already denoted by <C>*</C>, for the implementation of the circle
28
multiplication in the adjoint semigroup we need to wrap up ring
29
elements as CircleObjects, for which <C>*</C> is defined to be the
30
circle multiplication.
31
32
<ManSection>
33
<Attr Name="CircleObject"
34
Arg="x" />
35
<Description>
36
Let <A>x</A> be a ring element. Then <C>CircleObject(x)</C> returns the
37
corresponding circle object. If <A>x</A> lies in the family <C>fam</C>,
38
then <C>CircleObject(x)</C> lies in the family <Ref Fam="CircleFamily"/>,
39
corresponding to the family <C>fam</C>.
40
41
<Example>
42
<![CDATA[
43
gap> a := CircleObject( 2 );
44
CircleObject( 2 )
45
]]>
46
</Example>
47
48
</Description>
49
</ManSection>
50
51
52
<ManSection>
53
<Attr Name="UnderlyingRingElement"
54
Arg="x" />
55
<Description>
56
Returns the corresponding ring element for the circle object <A>x</A>.
57
<Example>
58
<![CDATA[
59
gap> a := CircleObject( 2 );
60
CircleObject( 2 )
61
gap> UnderlyingRingElement( a );
62
2
63
]]>
64
</Example>
65
66
</Description>
67
</ManSection>
68
69
70
<ManSection>
71
<Filt Name="IsCircleObject"
72
Arg="x"
73
Type="Category" />
74
<Filt Name="IsCircleObjectCollection"
75
Arg="x"
76
Type="Category" />
77
<Description>
78
An object <A>x</A> lies in the category <C>IsCircleObject</C> if and
79
only if it lies in a family constructed by <Ref Attr="CircleFamily"/>.
80
Since circle objects can be multiplied via <C>*</C> with elements in
81
their family, and we need operations <C>One</C> and <C>Inverse</C> to
82
deal with groups they generate, circle objects are implemented in the
83
category <C>IsMultiplicativeElementWithInverse</C>. A collection of
84
circle objects (e.g. adjoint semigroup or adjoint group) will lie in
85
the category <C>IsCircleObjectCollection</C>.
86
87
<Example>
88
<![CDATA[
89
gap> IsCircleObject( 2 ); IsCircleObject( CircleObject( 2 ) );
90
false
91
true
92
gap> IsMultiplicativeElementWithInverse( CircleObject( 2 ) );
93
true
94
gap> IsCircleObjectCollection( [ CircleObject(0), CircleObject(2) ] );
95
true
96
]]>
97
</Example>
98
99
</Description>
100
</ManSection>
101
102
<ManSection>
103
<Filt Name="IsPositionalObjectOneSlotRep"
104
Arg="x"
105
Type="Representation" />
106
<Filt Name="IsDefaultCircleObject"
107
Arg="x"
108
Type="Representation" />
109
<Description>
110
To store the corresponding circle object, we need only to store the
111
underlying ring element. Since this is quite common situation, we
112
defined the representation <C>IsPositionalObjectOneSlotRep</C> for a
113
more general case. Then we defined <C>IsDefaultCircleObject</C> as a
114
synonym of <C>IsPositionalObjectOneSlotRep</C> for objects in
115
<Ref Filt="IsCircleObject" />.
116
117
<Example>
118
<![CDATA[
119
gap> IsPositionalObjectOneSlotRep( CircleObject( 2 ) );
120
true
121
gap> IsDefaultCircleObject( CircleObject( 2 ) );
122
true
123
]]>
124
</Example>
125
126
</Description>
127
</ManSection>
128
129
<ManSection>
130
<Attr Name="CircleFamily"
131
Arg="fam" />
132
<Description>
133
<C>CircleFamily(fam)</C> is a family, elements of which are in one-to-one
134
correspondence with elements of the family <A>fam</A>,
135
but with the circle multiplication as an infix multiplication.
136
That is, for <M>x</M>, <M>y</M> in <A>fam</A>, the product of their images
137
in the <C>CircleFamily(fam)</C> will be the image of <M> x + y + x y </M>.
138
The relation between these families is demonstrated by the following equality:
139
140
<Example>
141
<![CDATA[
142
gap> FamilyObj( CircleObject ( 2 ) ) = CircleFamily( FamilyObj( 2 ) );
143
true
144
]]>
145
</Example>
146
147
</Description>
148
</ManSection>
149
150
</Section>
151
152
<Section Label="CircleOperations">
153
<Heading>Operations with circle objects</Heading>
154
155
<ManSection>
156
<Oper Name="One"
157
Arg="x" />
158
<Description>
159
This operation returns the multiplicative neutral element
160
for the circle object <A>x</A>. The result is the circle
161
object corresponding to the additive neutral element of
162
the appropriate ring.
163
164
<Example>
165
<![CDATA[
166
gap> One( CircleObject( 5 ) );
167
CircleObject( 0 )
168
gap> One( CircleObject( 5 ) ) = CircleObject( Zero( 5 ) );
169
true
170
gap> One( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
171
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
172
]]>
173
</Example>
174
175
</Description>
176
</ManSection>
177
178
179
<ManSection>
180
<Oper Name="InverseOp"
181
Arg="x" />
182
<Description>
183
For a circle object <A>x</A>, returns the multiplicative
184
inverse of <A>x</A> with respect to the circle multiplication;
185
if such one does not exist then <K>fail</K> is returned.<P/>
186
187
In our implementation we assume that the underlying ring is a
188
subring of the ring with one, thus, if the circle inverse for
189
an element <M>x</M> exists, than it can be computed as <M>-x(1+x)^{-1}</M>.
190
191
<Example>
192
<![CDATA[
193
gap> CircleObject( -2 )^-1;
194
CircleObject( -2 )
195
gap> CircleObject( 2 )^-1;
196
CircleObject( -2/3 )
197
gap> CircleObject( -2 )*CircleObject( -2 )^-1;
198
CircleObject( 0 )
199
]]>
200
</Example>
201
202
<Example>
203
<![CDATA[
204
gap> m := CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] );
205
CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] )
206
gap> m^-1;
207
CircleObject( [ [ -1/2, -1/4 ], [ 0, -1/2 ] ] )
208
gap> m * m^-1;
209
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
210
gap> CircleObject( [ [ 0, 1 ], [ 1, 0 ] ] )^-1;
211
fail
212
]]>
213
</Example>
214
215
</Description>
216
</ManSection>
217
218
219
<ManSection>
220
<Oper Name="IsUnit"
221
Arg="[ R, ] x" />
222
<Description>
223
Let <A>x</A> be a circle object corresponding to an element of
224
the ring <A>R</A>. Then the operation <C>IsUnit</C> returns
225
<C>true</C>, if <A>x</A> is invertible in <A>R</A> with respect
226
to the circle multiplication, and <C>false</C> otherwise.
227
228
<Example>
229
<![CDATA[
230
gap> IsUnit( Integers, CircleObject( -2 ) );
231
true
232
gap> IsUnit( Integers, CircleObject( 2 ) );
233
false
234
gap> IsUnit( Rationals, CircleObject( 2 ) );
235
true
236
gap> IsUnit( ZmodnZ(8), CircleObject( ZmodnZObj(2,8) ) );
237
true
238
gap> m := CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] );;
239
gap> IsUnit( FullMatrixAlgebra( Rationals, 2 ), m );
240
true
241
]]>
242
</Example>
243
244
245
246
If the first argument is omitted, the result will be returned with respect
247
to the default ring of the circle object <A>x</A>.
248
249
<Example>
250
<![CDATA[
251
gap> IsUnit( CircleObject( -2 ) );
252
true
253
gap> IsUnit( CircleObject( 2 ) );
254
false
255
gap> IsUnit( CircleObject( ZmodnZObj(2,8) ) );
256
true
257
gap> IsUnit( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
258
false
259
]]>
260
</Example>
261
262
</Description>
263
</ManSection>
264
265
266
<ManSection>
267
<Oper Name="IsCircleUnit"
268
Arg="[ R, ] x" />
269
<Description>
270
Let <A>x</A> be an element of the ring <A>R</A>. Then
271
<C>IsCircleUnit( R, x )</C> determines whether <A>x</A> is invertible
272
in <A>R</A> with respect to the circle multilpication. This is
273
equivalent to the condition that 1+<A>x</A> is a unit in <A>R</A>
274
with respect to the ordinary multiplication.
275
276
<Example>
277
<![CDATA[
278
gap> IsCircleUnit( Integers, -2 );
279
true
280
gap> IsCircleUnit( Integers, 2 );
281
false
282
gap> IsCircleUnit( Rationals, 2 );
283
true
284
gap> IsCircleUnit( ZmodnZ(8), ZmodnZObj(2,8) );
285
true
286
gap> m := [ [ 1, 1 ],[ 0, 1 ] ];
287
[ [ 1, 1 ], [ 0, 1 ] ]
288
gap> IsCircleUnit( FullMatrixAlgebra(Rationals,2), m );
289
true
290
]]>
291
</Example>
292
293
If the first argument is omitted, the result will be returned with respect
294
to the default ring of <A>x</A>.
295
296
<Example>
297
<![CDATA[
298
gap> IsCircleUnit( -2 );
299
true
300
gap> IsCircleUnit( 2 );
301
false
302
gap> IsCircleUnit( ZmodnZObj(2,8) );
303
true
304
gap> IsCircleUnit( [ [ 1, 1 ],[ 0, 1 ] ] );
305
false
306
]]>
307
</Example>
308
309
</Description>
310
</ManSection>
311
312
</Section>
313
314
315
<Section Label="CircleAdjointGroups">
316
<Heading>Construction of the adjoint semigroup and adjoint group</Heading>
317
318
<ManSection>
319
<Attr Name="AdjointSemigroup"
320
Arg="R" />
321
<Description>
322
If <A>R</A> is a finite ring then <C>AdjointSemigroup(<A>R</A>)</C> will
323
return the monoid which is formed by all elements of <A>R</A> with
324
respect to the circle multiplication.
325
<P/>
326
327
The implementation is rather straightforward and was added to provide a
328
link to the &GAP; functionality for semigroups. It assumes that the
329
enumaration of all elements of the ring <A>R</A> is feasible.
330
331
<Example>
332
<![CDATA[
333
gap> R:=Ring( [ ZmodnZObj(2,8) ] );
334
<ring with 1 generators>
335
gap> S:=AdjointSemigroup(R);
336
<monoid with 4 generators>
337
]]>
338
</Example>
339
340
</Description>
341
342
</ManSection>
343
344
345
<ManSection>
346
<Attr Name="AdjointGroup"
347
Arg="R" />
348
<Description>
349
If <A>R</A> is a finite radical algebra then
350
<C>AdjointGroup(<A>R</A>)</C> will return the adjoint group
351
of <A>R</A>, given as a group generated by a set of circle objects.
352
<P/>
353
354
To compute the adjoint group of a finite radical algebra,
355
&Circle; uses the fact that all elements of a radical algebra
356
form a group with respect to the circle multiplication. Thus,
357
the adjoint group of <A>R</A> coincides with <A>R</A> elementwise,
358
and we can randomly select an appropriate set of generators for
359
the adjoint group.
360
<P/>
361
362
The warning is displayed by <C>IsGeneratorsOfMagmaWithInverses</C>
363
method defined in <File>gap4r4/lib/grp.gi</File> and may be ignored.
364
<P/>
365
366
<B>WARNINGS:</B>
367
<P/>
368
369
1. The set of generators of the returned group is not required
370
to be a generating set of minimal possible order.
371
<P/>
372
373
2. <C>AdjointGroup</C> is stored as an attribute of <A>R</A>,
374
so for the same copy of <A>R</A> calling it again you will get
375
the same result. But if you will create another copy of <A>R</A>
376
in the future, the output may differ because of the random
377
selection of generators. If you want to have the same generating
378
set, next time you should construct a group immediately specifying
379
circle objects that generate it.
380
<P/>
381
382
3. In most cases, to investigate some properties of the adjoint
383
group, it is necessary first to convert it to an isomorphic
384
permutation group or to a PcGroup.
385
<P/>
386
387
For example, we can create the following commutative 2-dimensional
388
radical algebra of order 4 over the field of two elements,
389
and show that its adjoint group is a cyclic group of order 4:
390
391
<Example>
392
<![CDATA[
393
gap> x:=[ [ 0, 1, 0 ],
394
> [ 0, 0, 1 ],
395
> [ 0, 0, 0 ] ];;
396
gap> R := Algebra( GF(2), [ One(GF(2))*x ] );
397
<algebra over GF(2), with 1 generators>
398
gap> RadicalOfAlgebra( R ) = R;
399
true
400
gap> Dimension(R);
401
2
402
gap> G := AdjointGroup( R );;
403
gap> Size( R ) = Size( G );
404
true
405
gap> StructureDescription( G );
406
"C4"
407
]]>
408
</Example>
409
410
In the following example we construct a non-commutative
411
3-dimensional radical algebra of order 8 over the field
412
of two elements, and demonstrate that its adjoint group
413
is the dihedral group of order 8:
414
415
<Alt Only="LaTeX">\pagebreak</Alt>
416
417
<Example>
418
<![CDATA[
419
gap> x:=[ [ 0, 1, 0 ],
420
> [ 0, 0, 0 ],
421
> [ 0, 0, 0 ] ];;
422
gap> y:=[ [ 0, 0, 0 ],
423
> [ 0, 0, 1 ],
424
> [ 0, 0, 0 ] ];;
425
gap> R := Algebra( GF(2), One(GF(2))*[x,y] );
426
<algebra over GF(2), with 2 generators>
427
gap> RadicalOfAlgebra(R) = R;
428
true
429
gap> Dimension(R);
430
3
431
gap> G := AdjointGroup( R );
432
<group of size 8 with 2 generators>
433
gap> StructureDescription( G );
434
"D8"
435
]]>
436
</Example>
437
438
If the ring <A>R</A> is not a radical algebra,
439
then &Circle; will use another approach. We will enumerate
440
all elements of the ring <A>R</A> and select those that are units with
441
respect to the circle multiplication.
442
Then we will use a random approach similar to the case of the radical
443
algebra, to find some generating set of the adjoint group. Again, all
444
warnings 1-3 above refer also to this case.
445
<P/>
446
447
Of course, enumeration of all elements of <A>R</A> should be feasible
448
for this computation.
449
In the following example we demonstrate how it works for rings,
450
generated by residue classes:
451
452
<Example>
453
<![CDATA[
454
gap> R := Ring( [ ZmodnZObj(2,8) ] );
455
<ring with 1 generators>
456
gap> G := AdjointGroup( R );
457
<group of size 4 with 2 generators>
458
gap> StructureDescription( G );
459
"C2 x C2"
460
gap> R := Ring( [ ZmodnZObj(2,256) ] );
461
<ring with 1 generators>
462
gap> G := AdjointGroup( R );;
463
gap> StructureDescription( G );
464
"C64 x C2"
465
]]>
466
</Example>
467
468
Due to the <Ref Attr="AdjointSemigroup" />, there is also another way to
469
compute the adjoint group of a ring <M>R</M> by means of the computation of its
470
adjoint semigroup <M>S(R)</M> and taking the Green's <M>H</M>-class of the
471
multiplicative neutral element of <M>S(R)</M>. Let us repeat the last example
472
in this way:
473
474
<Example>
475
<![CDATA[
476
gap> R := Ring( [ ZmodnZObj(2,256) ] );
477
<ring with 1 generators>
478
gap> S := AdjointSemigroup( R );
479
<monoid with 128 generators>
480
gap> H := GreensHClassOfElement(S,One(S));
481
<Green's H-class: <object>>
482
gap> G:=AsGroup(H);
483
<group of size 128 with 2 generators>
484
gap> StructureDescription(G);
485
"C64 x C2"
486
]]>
487
</Example>
488
489
However, the conversion of the Green's <M>H</M>-class to the group may take
490
some time which may vary dependently on the particular ring in question, and
491
will also display a lot of warnings about the default
492
<C>IsGeneratorsOfMagmaWithInverses</C> method, so we did not implemented
493
this as as standard method. In the following example the method based on
494
Green's <M>H</M>-class is much slower than an application of
495
earlier described random approach (20s vs 10ms):
496
497
<Example>
498
<![CDATA[
499
gap> R := Ring( [ ZmodnZObj(2,256) ] );
500
<ring with 1 generators>
501
gap> AdjointGroup(R);;
502
gap> R := Ring( [ ZmodnZObj(2,256) ] );
503
<ring with 1 generators>
504
gap> S:=AdjointSemigroup(R);
505
<monoid with 128 generators>
506
gap> AsGroup(GreensHClassOfElement(S,One(S)));
507
<group of size 128 with 2 generators>
508
]]>
509
</Example>
510
511
512
Finally, note that if <A>R</A> has a unity <M>1</M>, then the set <M>1+R^{ad}</M>,
513
where <M>R^{ad}</M> is the adjoint semigroup of <A>R</A>, coincides
514
with the multiplicative semigroup <M>R^{mult}</M> of <M>R</M>, and the map
515
<M> r \mapsto (1+r) </M> for <M>r</M> in <M>R</M> is an isomorphism
516
from <M>R^{ad}</M> onto <M>R^{mult}</M>.
517
<P/>
518
519
Similarly, the set <M>1+R^*</M>, where <M>R^{*}</M> is the adjoint
520
group of <A>R</A>, coincides with the unit group of <M>R</M>,
521
which we denote <M>U(R)</M>, and the map <M>r \mapsto (1+r)</M>
522
for <M>r</M> in <M>R</M> is an isomorphism from <M>R^*</M> onto
523
<M>U(R)</M>.
524
<P/>
525
526
We demonstrate this isomorphism using the following example.
527
528
<Example>
529
<![CDATA[
530
gap> LoadPackage( "laguna", false );
531
true
532
gap> FG := GroupRing( GF(2), DihedralGroup(8) );
533
<algebra-with-one over GF(2), with 3 generators>
534
gap> R := AugmentationIdeal( FG );;
535
gap> G := AdjointGroup( R );;
536
gap> IdGroup( G );
537
[ 128, 170 ]
538
gap> IdGroup( Units( FG ) );
539
#I LAGUNA package: Computing the unit group ...
540
[ 128, 170 ]
541
]]>
542
</Example>
543
544
Thus, dependently on the ring <C>R</C> in question, it might be possible
545
that you can compute much faster its unit group using <C>Units(R)</C> than
546
its adjoint group using <C>AdjointGroup(R)</C>. This is why in an attempt
547
of computation of the adjoint group of the ring with one a warning message
548
will be displayed:
549
<P/>
550
551
<Example>
552
<![CDATA[
553
gap> Size( AdjointGroup( GroupRing( GF(2), DihedralGroup(8) ) ) );
554
555
WARNING: usage of AdjointGroup for associative ring <R> with one!!!
556
In this case the adjoint group is isomorphic to the unit group
557
Units(<R>), which possibly may be computed faster!!!
558
559
128
560
gap> Size( AdjointGroup( Integers mod 11 ) );
561
562
WARNING: usage of AdjointGroup for associative ring <R> with one!!!
563
In this case the adjoint group is isomorphic to the unit group
564
Units(<R>), which possibly may be computed faster!!!
565
566
10
567
]]>
568
</Example>
569
570
If <A>R</A> is infinite, an error message will appear,
571
telling that &Circle; does not provide methods to deal
572
with infinite rings.
573
574
</Description>
575
</ManSection>
576
577
</Section>
578
579
580
<!-- ######################################################### -->
581
582
<Section Label="Service">
583
<Heading>Service functions</Heading>
584
585
586
<ManSection>
587
<InfoClass Name="InfoCircle" />
588
<Description>
589
<C>InfoCircle</C> is a special Info class for &Circle; algorithms.
590
It has 2 levels: 0 (default) and 1. To change info level to
591
<C>k</C>, use command <C>SetInfoLevel(InfoCircle, k)</C>.
592
593
<Example>
594
<![CDATA[
595
gap> SetInfoLevel( InfoCircle, 1 );
596
gap> SetInfoLevel(InfoCircle,1);
597
gap> R := Ring( [ ZmodnZObj(2,8) ]);
598
<ring with 1 generators>
599
gap> G := AdjointGroup( R );
600
#I Circle : <R> is not a radical algebra, computing circle units ...
601
#I Circle : searching generators for adjoint group ...
602
<group of size 4 with 2 generators>
603
gap> SetInfoLevel( InfoCircle, 0 );
604
]]>
605
</Example>
606
607
</Description>
608
</ManSection>
609
610
</Section>
611
612
</Chapter>
613