2. Circle functions
To use the Circle package first you need to load it as follows:
gap> LoadPackage("circle");
-----------------------------------------------------------------------------
Loading Circle 1.0 (Adjoint groups of associative rings)
by Alexander Konovalov (http://homepages.vub.ac.be/~okonoval/) and
Panagiotis Soules (psoules@math.uoa.gr).
-----------------------------------------------------------------------------
true
gap>
|
2.1 Circle objects
Because for elements of the ring R the ordinary multiplication is already denoted by *
, for the implementation of the circle multiplication in the adjoint semigroup we need to wrap up ring elements as CircleObjects, for which *
is defined to be the circle multiplication.
2.1-1 CircleObject
> CircleObject ( x ) | ( attribute ) |
Let x be a ring element. Then CircleObject(x)
returns the corresponding circle object. If x lies in the family fam
, then CircleObject(x)
lies in the family CircleFamily
(2.1-5), corresponding to the family fam
.
gap> x := 2;
2
gap> a := CircleObject( x );
CircleObject( 2 )
gap> FamilyObj( a ) = CircleFamily( FamilyObj( x ) );
true
|
2.1-2 UnderlyingRingElement
> UnderlyingRingElement ( x ) | ( operation ) |
Let x be a circle object. Then UnderlyingRingElement(x)
returns the corresponding ring element.
gap> x := 2;
2
gap> a := CircleObject( x );
CircleObject( 2 )
gap> UnderlyingRingElement( a );
2
gap> FamilyObj( a ) = CircleFamily( FamilyObj( x ) );
true
|
2.1-3 IsCircleObject
> IsCircleObject ( x ) | ( Category ) |
> IsCircleObjectCollection ( x ) | ( Category ) |
An object x lies in the category IsCircleObject
if and only if it lies in a family constructed by CircleFamily
(2.1-5). Since circle objects can be multiplied via *
with elements in their family, and we want to implement operations One
and Inverse
to deal with groups they generate, circle objects are implemented in the category IsMultiplicativeElementWithInverse
.
gap> IsCircleObject( 2 );
false
gap> IsCircleObject( CircleObject( 2 ) );
true
gap> IsMultiplicativeElementWithInverse( CircleObject( 2 ) );
true
gap> One( CircleObject( 2 ) );
CircleObject( 0 )
gap> CircleObject( -2 )^-1;
CircleObject( -2 )
|
2.1-4 IsPositionalObjectOneSlotRep
> IsPositionalObjectOneSlotRep ( x ) | ( Representation ) |
> IsDefaultCircleObject ( x ) | ( Representation ) |
To store the corresponding circle object, we need only to store the underlying ring element. Since this is quite common situation, we defined the representation IsPositionalObjectOneSlotRep
for a more general case. Then we defined IsDefaultCircleObject
as a synonym of IsPositionalObjectOneSlotRep
for objects in IsCircleObject
(2.1-3).
gap> IsPositionalObjectOneSlotRep( CircleObject( 2 ) );
true
gap> IsDefaultCircleObject( CircleObject( 2 ) );
true
|
2.1-5 CircleFamily
> CircleFamily ( fam ) | ( attribute ) |
CircleFamily(fam)
is a family, elements of which are in one-to-one correspondence with elements of the family fam, but with the circle multiplication as an infix multiplication. That is, for x, y in fam, the product of their images in the CircleFamily(fam)
will be the image of x + y + x y.
gap> x:=CircleObject(2)*CircleObject(3);
CircleObject( 11 )
gap> y:=CircleObject(2+3+2*3);
CircleObject( 11 )
gap> x=y;
true
gap> FamilyObj(x)=FamilyObj(y);
true
|
2.2 Operations with circle objects
2.2-1 OneOp
> OneOp ( x ) | ( operation ) |
This operation returns the multiplicative neutral element for the circle object x. The result is the circle object corresponding to the additive neutral element of the appropriate ring.
gap> One( CircleObject( 5 ) );
CircleObject( 0 )
gap> One( CircleObject( 5 ) ) = CircleObject( Zero( 5 ) );
true
gap> One( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
|
2.2-2 InverseOp
> InverseOp ( x ) | ( operation ) |
For a circle object x, returns the multiplicative inverse of x with respect to the circle multiplication; if such one does not exist then fail
is returned.
gap> CircleObject( -2 )^-1;
CircleObject( -2 )
gap> CircleObject( 2 )^-1;
CircleObject( -2/3 )
gap> CircleObject( -2 )*CircleObject( -2 )^-1;
CircleObject( 0 )
gap> m := CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] );
CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] )
gap> m^-1;
CircleObject( [ [ -1/2, -1/4 ], [ 0, -1/2 ] ] )
gap> m * m^-1;
CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
gap> CircleObject( [ [ 0, 1 ], [ 1, 0 ] ] )^-1;
fail
|
2.2-3 IsUnit
> IsUnit ( R, x ) | ( operation ) |
> IsUnit ( x ) | ( operation ) |
Let x be a circle object corresponding to an element of the ring R. Then the operation IsUnit
returns true
, if x is invertible in R with respect to the circle multiplication, and false
otherwise.
gap> IsUnit( Integers, CircleObject( -2 ) );
true
gap> IsUnit( Integers, CircleObject( 2 ) );
false
gap> IsUnit( Rationals, CircleObject( 2 ) );
true
gap> IsUnit( ZmodnZ(8), CircleObject( ZmodnZObj(2,8) ) );
true
gap> m := CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] );
CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] )
gap> IsUnit( FullMatrixAlgebra( Rationals, 2 ), m );
true
|
In the second form the result will be returned with respect to the default ring of the circle object x.
gap> IsUnit( CircleObject( -2 ) );
true
gap> IsUnit( CircleObject( 2 ) );
false
gap> IsUnit( CircleObject( ZmodnZObj(2,8) ) );
true
gap> IsUnit( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
true
|
2.2-4 IsCircleUnit
> IsCircleUnit ( R, x ) | ( operation ) |
> IsCircleUnit ( x ) | ( operation ) |
Let x be an element of the ring R. Then IsCircleUnit( R, x )
determines whether x is invertible in R with respect to the circle multilpication. This is equivalent to the condition that 1+x is a unit in R with respect to the ordinary multiplication.
gap> IsCircleUnit( Integers, -2 );
true
gap> IsCircleUnit( Integers, 2 );
false
gap> IsCircleUnit( Rationals, 2 );
true
gap> IsCircleUnit( ZmodnZ(8), ZmodnZObj(2,8) );
true
gap> m := [ [ 1, 1 ],[ 0, 1 ] ];
[ [ 1, 1 ], [ 0, 1 ] ]
gap> IsCircleUnit( FullMatrixAlgebra(Rationals,2), m );
true
|
In the second form the result will be returned with respect to the default ring of x.
gap> IsCircleUnit( -2 );
true
gap> IsCircleUnit( 2 );
false
gap> IsCircleUnit( ZmodnZObj(2,8) );
true
gap> IsCircleUnit( [ [ 1, 1 ],[ 0, 1 ] ] );
true
|
2.3 Construction of the adjoint group
2.3-1 AdjointGroup
> AdjointGroup ( R ) | ( attribute ) |
If R is a finite radical algebra then AdjointGroup(R)
will return the adjoint group of R, given as a group generated by a set of circle objects.
To compute the adjoint group of a finite radical algebra, Circle uses the fact that all elements of a radical algebra form a group with respect to the circle multiplication. Thus, the adjoint group of R coincides with R elementwise, and we can randomly select an appropriate set of generators for the adjoint group.
The warning is displayed by IsGeneratorsOfMagmaWithInverses
method defined in gap4r4/lib/grp.gi
and may be ignored.
WARNINGS:
1. The set of generators of the returned group is not required to be the minimal generating set.
2. AdjointGroup
is stored as an attribute of R, so for the same copy of R calling it again you will get the same result. But if you will create another copy of R in the future, the output may differ because of the random selection of generators. If you want to have the same generating set, next time you should construct a group immediately specifying circle objects that generate it.
3. In most cases, to investigate some properties of the adjoint group, it is necessary first to convert it to an isomorphic permutation group or to a PcGroup.
For example, we can create the following commutative 2-dimensional radical algebra of order 4 over the field of two elements, and show that its adjoint group is a cyclic group of order 4:
gap> x:=[ [ 0, 1, 0 ],
> [ 0, 0, 1 ],
> [ 0, 0, 0 ] ];;
gap> R := Algebra( GF(2), [ One(GF(2))*x ] );
<algebra over GF(2), with 1 generators>
gap> RadicalOfAlgebra( R ) = R;
true
gap> Dimension(R);
2
gap> G := AdjointGroup( R );
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( [ [ 0*Z(2), 0*Z(2), Z(2)^0 ], [ 0*Z(2), 0*Z(2), 0*Z(2) ],
[ 0*Z(2), 0*Z(2), 0*Z(2) ] ] ) ]
<group of size 4 with 2 generators>
gap> Size( R ) = Size( G );
true
gap> StructureDescription( G );
"C4"
|
In the following example we construct a non-commutative 3-dimensional radical algebra of order 8 over the field of two elements, and demonstrate that its adjoint group is the dihedral group of order 8:
gap> x:=[ [ 0, 1, 0 ],
> [ 0, 0, 0 ],
> [ 0, 0, 0 ] ];;
gap> y:=[ [ 0, 0, 0 ],
> [ 0, 0, 1 ],
> [ 0, 0, 0 ] ];;
gap> R := Algebra( GF(2), One(GF(2))*[x,y] );
<algebra over GF(2), with 2 generators>
gap> RadicalOfAlgebra(R) = R;
true
gap> Dimension(R);
3
gap> G := AdjointGroup( R );
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( [ [ 0*Z(2), Z(2)^0, Z(2)^0 ], [ 0*Z(2), 0*Z(2), Z(2)^0 ],
[ 0*Z(2), 0*Z(2), 0*Z(2) ] ] ) ]
<group of size 8 with 2 generators>
gap> StructureDescription( G );
"D8"
|
If the ring R is not a radical algebra, but also is not a ring with one, then Circle will use another approach. We will enumerate all elements of the ring R and select those that are units with respect to the circle multiplication. Then we will use a random approach similar to the case of the radical algebra, to find some generating set of the adjoint group. Again, all warnings 1-3 above refer also to this case.
Of course, enumeration of all elements of R should be feasible for this computation. In the following example we demonstrate how it works for rings, generated by residue classes:
gap> R := Ring( [ ZmodnZObj(2,8) ] );
<ring with 1 generators>
gap> G := AdjointGroup( R );
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( ZmodnZObj( 2, 8 ) ) ]
<group of size 4 with 2 generators>
gap> StructureDescription( G );
"C2 x C2"
gap> R := Ring( [ ZmodnZObj(2,256) ] );
<ring with 1 generators>
gap> G := AdjointGroup( R );
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( ZmodnZObj( 234, 256 ) ) ]
<group of size 128 with 2 generators>
gap> StructureDescription( G );
"C64 x C2"
|
If R has a unity 1, then the set 1+R^ad, where R^ad is the adjoint semigroup of R, coincides with the multiplicative semigroup R^mult of R, and the map r -> (1+r) for r in R is an isomorphism from R^ad onto R^mult.
Similarly, the set 1+R^*, where R^* is the adjoint group of R, coincides with the unit group of R, which we denote U(R), and the map r -> (1+r) for r in R is an isomorphism from R^* onto U(R).
We demonstrate this isomorphism using the following example.
gap> FG := GroupRing( GF(2), DihedralGroup(8) );
<algebra-with-one over GF(2), with 3 generators>
gap> R := AugmentationIdeal( FG );
<two-sided ideal in <algebra-with-one over GF(2), with 3 generators>,
(dimension 7)>
gap> G := AdjointGroup( R );
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( (Z(2)^0)*f2+(Z(2)^0)*f1*f2 ) ]
<group of size 128 with 4 generators>
gap> IdGroup( G );
[ 128, 170 ]
gap> IdGroup( Units( FG ) );
#I LAGUNA package: Computing the unit group ...
[ 128, 170 ]
|
This is is why we did not implemented in Circle adjoint groups for associative rings with one. If you will try to compute the adjoint group for such a ring, you will get an error message telling that you can investigate the unit group of the ring instead.
If R is infinite, an error message will appear, telling that Circle does not provide methods to deal with infinite rings.
2.4 Service functions
2.4-1 InfoCircle
> InfoCircle | ( info class ) |
InfoCircle
is a special Info class for Circle algorithms. It has 2 levels: 0 (default) and 1. To change info level to k
, use command SetInfoLevel(InfoCircle, k)
.
gap> SetInfoLevel( InfoCircle, 1 );
gap> SetInfoLevel(InfoCircle,1);
gap> R := Ring( [ ZmodnZObj(2,8) ]);
<ring with 1 generators>
gap> G := AdjointGroup( R );
#I Circle : <R> is not a radical algebra, computing circle units ...
#I Circle : searching generators for adjoint group ...
#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for
[ CircleObject( ZmodnZObj( 6, 8 ) ) ]
<group of size 4 with 2 generators>
gap> SetInfoLevel( InfoCircle, 0 );
|
2.4-2 CIRCLEBuildManual
> CIRCLEBuildManual ( ) | ( function ) |
This function is used to build the manual in the following formats: DVI, PDF, PS, HTML and text for online help. We recommend that the user should have a recent and fairly complete TeX distribution. Since Circle is distributed together with its manual, it is not necessary for the user to use this function. Normally it is intended to be used by the developers only. This is the only function of Circle which requires UNIX/Linux environment.
2.4-3 CIRCLEBuildManualHTML
> CIRCLEBuildManualHTML ( ) | ( function ) |
This fuction is used to build the manual only in HTML format. This does not depend on the availability of the TeX installation and works under Windows and MacOS as well. Since Circle is distributed together with its manual, it is not necessary for the user to use this function. Normally it is intended to be used by the developers only.