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
2
3 Circle functions
3
4
To use the Circle package first you need to load it as follows:
5
6
 Example 
7

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

18
19
Note that if you entered examples from the previous chapter, you need to
20
restart GAP before loading the Circle package.
21
22
23
3.1 Circle objects
24
25
Because for elements of the ring R the ordinary multiplication is already
26
denoted by *, for the implementation of the circle multiplication in the
27
adjoint semigroup we need to wrap up ring elements as CircleObjects, for
28
which * is defined to be the circle multiplication.
29
30
3.1-1 CircleObject
31
32
CircleObject( x )  attribute
33
34
Let x be a ring element. Then CircleObject(x) returns the corresponding
35
circle object. If x lies in the family fam, then CircleObject(x) lies in the
36
family CircleFamily (3.1-5), corresponding to the family fam.
37
38
 Example 
39

40
gap> a := CircleObject( 2 );
41
CircleObject( 2 )
42

43

44
45
3.1-2 UnderlyingRingElement
46
47
UnderlyingRingElement( x )  attribute
48
49
Returns the corresponding ring element for the circle object x.
50
51
 Example 
52

53
gap> a := CircleObject( 2 );
54
CircleObject( 2 )
55
gap> UnderlyingRingElement( a ); 
56
2
57

58

59
60
3.1-3 IsCircleObject
61
62
IsCircleObject( x )  Category
63
IsCircleObjectCollection( x )  Category
64
65
An object x lies in the category IsCircleObject if and only if it lies in a
66
family constructed by CircleFamily (3.1-5). Since circle objects can be
67
multiplied via * with elements in their family, and we need operations One
68
and Inverse to deal with groups they generate, circle objects are
69
implemented in the category IsMultiplicativeElementWithInverse. A collection
70
of circle objects (e.g. adjoint semigroup or adjoint group) will lie in the
71
category IsCircleObjectCollection.
72
73
 Example 
74

75
gap> IsCircleObject( 2 ); IsCircleObject( CircleObject( 2 ) ); 
76
false
77
true
78
gap> IsMultiplicativeElementWithInverse( CircleObject( 2 ) );
79
true
80
gap> IsCircleObjectCollection( [ CircleObject(0), CircleObject(2) ] );
81
true
82

83

84
85
3.1-4 IsPositionalObjectOneSlotRep
86
87
IsPositionalObjectOneSlotRep( x )  Representation
88
IsDefaultCircleObject( x )  Representation
89
90
To store the corresponding circle object, we need only to store the
91
underlying ring element. Since this is quite common situation, we defined
92
the representation IsPositionalObjectOneSlotRep for a more general case.
93
Then we defined IsDefaultCircleObject as a synonym of
94
IsPositionalObjectOneSlotRep for objects in IsCircleObject (3.1-3).
95
96
 Example 
97

98
gap> IsPositionalObjectOneSlotRep( CircleObject( 2 ) );
99
true
100
gap> IsDefaultCircleObject( CircleObject( 2 ) ); 
101
true
102

103

104
105
3.1-5 CircleFamily
106
107
CircleFamily( fam )  attribute
108
109
CircleFamily(fam) is a family, elements of which are in one-to-one
110
correspondence with elements of the family fam, but with the circle
111
multiplication as an infix multiplication. That is, for x, y in fam, the
112
product of their images in the CircleFamily(fam) will be the image of x + y
113
+ x y. The relation between these families is demonstrated by the following
114
equality:
115
116
 Example 
117

118
gap> FamilyObj( CircleObject ( 2 ) ) = CircleFamily( FamilyObj( 2 ) );
119
true
120

121

122
123
124
3.2 Operations with circle objects
125
126
3.2-1 One
127
128
One( x )  operation
129
130
This operation returns the multiplicative neutral element for the circle
131
object x. The result is the circle object corresponding to the additive
132
neutral element of the appropriate ring.
133
134
 Example 
135

136
gap> One( CircleObject( 5 ) );
137
CircleObject( 0 )
138
gap> One( CircleObject( 5 ) ) = CircleObject( Zero( 5 ) );
139
true
140
gap> One( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
141
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
142

143

144
145
3.2-2 InverseOp
146
147
InverseOp( x )  operation
148
149
For a circle object x, returns the multiplicative inverse of x with respect
150
to the circle multiplication; if such one does not exist then fail is
151
returned.
152
153
In our implementation we assume that the underlying ring is a subring of the
154
ring with one, thus, if the circle inverse for an element x exists, than it
155
can be computed as -x(1+x)^-1.
156
157
 Example 
158

159
gap> CircleObject( -2 )^-1; 
160
CircleObject( -2 )
161
gap> CircleObject( 2 )^-1; 
162
CircleObject( -2/3 )
163
gap> CircleObject( -2 )*CircleObject( -2 )^-1;
164
CircleObject( 0 )
165

166

167
168
 Example 
169

170
gap> m := CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] ); 
171
CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] )
172
gap> m^-1; 
173
CircleObject( [ [ -1/2, -1/4 ], [ 0, -1/2 ] ] )
174
gap> m * m^-1;
175
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
176
gap> CircleObject( [ [ 0, 1 ], [ 1, 0 ] ] )^-1; 
177
fail
178

179

180
181
3.2-3 IsUnit
182
183
IsUnit( [R, ]x )  operation
184
185
Let x be a circle object corresponding to an element of the ring R. Then the
186
operation IsUnit returns true, if x is invertible in R with respect to the
187
circle multiplication, and false otherwise.
188
189
 Example 
190

191
gap> IsUnit( Integers, CircleObject( -2 ) );
192
true
193
gap> IsUnit( Integers, CircleObject( 2 ) ); 
194
false
195
gap> IsUnit( Rationals, CircleObject( 2 ) ); 
196
true
197
gap> IsUnit( ZmodnZ(8), CircleObject( ZmodnZObj(2,8) ) );
198
true
199
gap> m := CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] );;
200
gap> IsUnit( FullMatrixAlgebra( Rationals, 2 ), m );
201
true
202

203

204
205
If the first argument is omitted, the result will be returned with respect
206
to the default ring of the circle object x.
207
208
 Example 
209

210
gap> IsUnit( CircleObject( -2 ) );
211
true
212
gap> IsUnit( CircleObject( 2 ) ); 
213
false
214
gap> IsUnit( CircleObject( ZmodnZObj(2,8) ) );
215
true
216
gap> IsUnit( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) ); 
217
false
218

219

220
221
3.2-4 IsCircleUnit
222
223
IsCircleUnit( [R, ]x )  operation
224
225
Let x be an element of the ring R. Then IsCircleUnit( R, x ) determines
226
whether x is invertible in R with respect to the circle multilpication. This
227
is equivalent to the condition that 1+x is a unit in R with respect to the
228
ordinary multiplication.
229
230
 Example 
231

232
gap> IsCircleUnit( Integers, -2 );
233
true
234
gap> IsCircleUnit( Integers, 2 ); 
235
false
236
gap> IsCircleUnit( Rationals, 2 ); 
237
true
238
gap> IsCircleUnit( ZmodnZ(8), ZmodnZObj(2,8) ); 
239
true
240
gap> m := [ [ 1, 1 ],[ 0, 1 ] ]; 
241
[ [ 1, 1 ], [ 0, 1 ] ]
242
gap> IsCircleUnit( FullMatrixAlgebra(Rationals,2), m );
243
true
244

245

246
247
If the first argument is omitted, the result will be returned with respect
248
to the default ring of x.
249
250
 Example 
251

252
gap> IsCircleUnit( -2 ); 
253
true
254
gap> IsCircleUnit( 2 ); 
255
false
256
gap> IsCircleUnit( ZmodnZObj(2,8) ); 
257
true
258
gap> IsCircleUnit( [ [ 1, 1 ],[ 0, 1 ] ] ); 
259
false
260

261

262
263
264
3.3 Construction of the adjoint semigroup and adjoint group
265
266
3.3-1 AdjointSemigroup
267
268
AdjointSemigroup( R )  attribute
269
270
If R is a finite ring then AdjointSemigroup(R) will return the monoid which
271
is formed by all elements of R with respect to the circle multiplication.
272
273
The implementation is rather straightforward and was added to provide a link
274
to the GAP functionality for semigroups. It assumes that the enumaration of
275
all elements of the ring R is feasible.
276
277
 Example 
278

279
gap> R:=Ring( [ ZmodnZObj(2,8) ] );
280
<ring with 1 generators>
281
gap> S:=AdjointSemigroup(R);
282
<monoid with 4 generators>
283

284

285
286
3.3-2 AdjointGroup
287
288
AdjointGroup( R )  attribute
289
290
If R is a finite radical algebra then AdjointGroup(R) will return the
291
adjoint group of R, given as a group generated by a set of circle objects.
292
293
To compute the adjoint group of a finite radical algebra, Circle uses the
294
fact that all elements of a radical algebra form a group with respect to the
295
circle multiplication. Thus, the adjoint group of R coincides with R
296
elementwise, and we can randomly select an appropriate set of generators for
297
the adjoint group.
298
299
The warning is displayed by IsGeneratorsOfMagmaWithInverses method defined
300
in gap4r4/lib/grp.gi and may be ignored.
301
302
WARNINGS:
303
304
1. The set of generators of the returned group is not required to be a
305
generating set of minimal possible order.
306
307
2. AdjointGroup is stored as an attribute of R, so for the same copy of R
308
calling it again you will get the same result. But if you will create
309
another copy of R in the future, the output may differ because of the random
310
selection of generators. If you want to have the same generating set, next
311
time you should construct a group immediately specifying circle objects that
312
generate it.
313
314
3. In most cases, to investigate some properties of the adjoint group, it is
315
necessary first to convert it to an isomorphic permutation group or to a
316
PcGroup.
317
318
For example, we can create the following commutative 2-dimensional radical
319
algebra of order 4 over the field of two elements, and show that its adjoint
320
group is a cyclic group of order 4:
321
322
 Example 
323

324
gap> x:=[ [ 0, 1, 0 ],
325
>  [ 0, 0, 1 ],
326
>  [ 0, 0, 0 ] ];;
327
gap> R := Algebra( GF(2), [ One(GF(2))*x ] ); 
328
<algebra over GF(2), with 1 generators>
329
gap> RadicalOfAlgebra( R ) = R;
330
true
331
gap> Dimension(R);
332
2
333
gap> G := AdjointGroup( R );;
334
gap> Size( R ) = Size( G );
335
true
336
gap> StructureDescription( G );
337
"C4"
338

339

340
341
In the following example we construct a non-commutative 3-dimensional
342
radical algebra of order 8 over the field of two elements, and demonstrate
343
that its adjoint group is the dihedral group of order 8:
344
345
 Example 
346

347
gap> x:=[ [ 0, 1, 0 ],
348
>  [ 0, 0, 0 ], 
349
>  [ 0, 0, 0 ] ];;
350
gap> y:=[ [ 0, 0, 0 ], 
351
>  [ 0, 0, 1 ], 
352
>  [ 0, 0, 0 ] ];;
353
gap> R := Algebra( GF(2), One(GF(2))*[x,y] ); 
354
<algebra over GF(2), with 2 generators>
355
gap> RadicalOfAlgebra(R) = R; 
356
true
357
gap> Dimension(R);
358
3
359
gap> G := AdjointGroup( R );
360
<group of size 8 with 2 generators>
361
gap> StructureDescription( G );
362
"D8"
363

364

365
366
If the ring R is not a radical algebra, then Circle will use another
367
approach. We will enumerate all elements of the ring R and select those that
368
are units with respect to the circle multiplication. Then we will use a
369
random approach similar to the case of the radical algebra, to find some
370
generating set of the adjoint group. Again, all warnings 1-3 above refer
371
also to this case.
372
373
Of course, enumeration of all elements of R should be feasible for this
374
computation. In the following example we demonstrate how it works for rings,
375
generated by residue classes:
376
377
 Example 
378

379
gap> R := Ring( [ ZmodnZObj(2,8) ] );
380
<ring with 1 generators>
381
gap> G := AdjointGroup( R );
382
<group of size 4 with 2 generators>
383
gap> StructureDescription( G );
384
"C2 x C2"
385
gap> R := Ring( [ ZmodnZObj(2,256) ] ); 
386
<ring with 1 generators>
387
gap> G := AdjointGroup( R );;
388
gap> StructureDescription( G );
389
"C64 x C2"
390

391

392
393
Due to the AdjointSemigroup (3.3-1), there is also another way to compute
394
the adjoint group of a ring R by means of the computation of its adjoint
395
semigroup S(R) and taking the Green's H-class of the multiplicative neutral
396
element of S(R). Let us repeat the last example in this way:
397
398
 Example 
399

400
gap> R := Ring( [ ZmodnZObj(2,256) ] ); 
401
<ring with 1 generators>
402
gap> S := AdjointSemigroup( R );
403
<monoid with 128 generators>
404
gap> H := GreensHClassOfElement(S,One(S));
405
<Green's H-class: <object>>
406
gap> G:=AsGroup(H);
407
<group of size 128 with 2 generators>
408
gap> StructureDescription(G);
409
"C64 x C2"
410

411

412
413
However, the conversion of the Green's H-class to the group may take some
414
time which may vary dependently on the particular ring in question, and will
415
also display a lot of warnings about the default
416
IsGeneratorsOfMagmaWithInverses method, so we did not implemented this as as
417
standard method. In the following example the method based on Green's
418
H-class is much slower than an application of earlier described random
419
approach (20s vs 10ms):
420
421
 Example 
422

423
gap> R := Ring( [ ZmodnZObj(2,256) ] ); 
424
<ring with 1 generators>
425
gap> AdjointGroup(R);;
426
gap> R := Ring( [ ZmodnZObj(2,256) ] );
427
<ring with 1 generators>
428
gap> S:=AdjointSemigroup(R); 
429
<monoid with 128 generators>
430
gap> AsGroup(GreensHClassOfElement(S,One(S))); 
431
<group of size 128 with 2 generators>
432

433

434
435
Finally, note that if R has a unity 1, then the set 1+R^ad, where R^ad is
436
the adjoint semigroup of R, coincides with the multiplicative semigroup
437
R^mult of R, and the map r ↦ (1+r) for r in R is an isomorphism from R^ad
438
onto R^mult.
439
440
Similarly, the set 1+R^*, where R^* is the adjoint group of R, coincides
441
with the unit group of R, which we denote U(R), and the map r ↦ (1+r) for r
442
in R is an isomorphism from R^* onto U(R).
443
444
We demonstrate this isomorphism using the following example.
445
446
 Example 
447

448
gap> LoadPackage( "laguna", false );
449
true
450
gap> FG := GroupRing( GF(2), DihedralGroup(8) );
451
<algebra-with-one over GF(2), with 3 generators>
452
gap> R := AugmentationIdeal( FG );;
453
gap> G := AdjointGroup( R );;
454
gap> IdGroup( G );
455
[ 128, 170 ]
456
gap> IdGroup( Units( FG ) );
457
#I LAGUNA package: Computing the unit group ...
458
[ 128, 170 ]
459

460

461
462
Thus, dependently on the ring R in question, it might be possible that you
463
can compute much faster its unit group using Units(R) than its adjoint group
464
using AdjointGroup(R). This is why in an attempt of computation of the
465
adjoint group of the ring with one a warning message will be displayed:
466
467
 Example 
468

469
gap> Size( AdjointGroup( GroupRing( GF(2), DihedralGroup(8) ) ) );
470

471
WARNING: usage of AdjointGroup for associative ring <R> with one!!! 
472
In this case the adjoint group is isomorphic to the unit group 
473
Units(<R>), which possibly may be computed faster!!! 
474

475
128
476
gap> Size( AdjointGroup( Integers mod 11 ) ); 
477

478
WARNING: usage of AdjointGroup for associative ring <R> with one!!! 
479
In this case the adjoint group is isomorphic to the unit group 
480
Units(<R>), which possibly may be computed faster!!! 
481

482
10
483

484

485
486
If R is infinite, an error message will appear, telling that Circle does not
487
provide methods to deal with infinite rings.
488
489
490
3.4 Service functions
491
492
3.4-1 InfoCircle
493
494
InfoCircle info class
495
496
InfoCircle is a special Info class for Circle algorithms. It has 2 levels: 0
497
(default) and 1. To change info level to k, use command
498
SetInfoLevel(InfoCircle, k).
499
500
 Example 
501

502
gap> SetInfoLevel( InfoCircle, 1 );
503
gap> SetInfoLevel(InfoCircle,1);
504
gap> R := Ring( [ ZmodnZObj(2,8) ]);
505
<ring with 1 generators>
506
gap> G := AdjointGroup( R );
507
#I Circle : <R> is not a radical algebra, computing circle units ...
508
#I Circle : searching generators for adjoint group ...
509
<group of size 4 with 2 generators>
510
gap> SetInfoLevel( InfoCircle, 0 );
511

512

513
514
515