<!-- $Id: funct.xml,v 1.1 2006/07/25 11:37:05 alexk Exp $ -->
<Chapter Label="Funct">
<Heading>&Circle; functions</Heading>

To use the &Circle; package first you need to load it as follows:

<Example>
<![CDATA[
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>
]]>
</Example>


<Section Label="CircleObjects">
<Heading>Circle objects</Heading>

Because for elements of the ring <M>R</M> the ordinary multiplication
is already denoted by <C>*</C>, for the implementation of the circle
multiplication in the adjoint semigroup we need to wrap up ring 
elements as CircleObjects, for which <C>*</C> is defined to be the 
circle multiplication.

<ManSection>
   <Attr Name="CircleObject" 
         Arg="x" />
<Description>	      
Let <A>x</A> be a ring element. Then <C>CircleObject(x)</C> returns the
corresponding circle object. If <A>x</A> lies in the family <C>fam</C>,
then <C>CircleObject(x)</C> lies in the family <Ref Fam="CircleFamily"/>,
corresponding to the family <C>fam</C>.

<Example>
<![CDATA[
gap> x := 2;                                   
2
gap> a := CircleObject( x );
CircleObject( 2 )
gap> FamilyObj( a ) = CircleFamily( FamilyObj( x ) ); 
true
]]>
</Example>

</Description>        
</ManSection>


<ManSection>
   <Oper Name="UnderlyingRingElement" 
         Arg="x" />
<Description>	      
Let <A>x</A> be a circle object. Then <C>UnderlyingRingElement(<A>x</A>)</C> 
returns the corresponding ring element.
<Example>
<![CDATA[
gap> x := 2;                                   
2
gap> a := CircleObject( x );
CircleObject( 2 )
gap> UnderlyingRingElement( a );    
2
gap> FamilyObj( a ) = CircleFamily( FamilyObj( x ) ); 
true
]]>
</Example>

</Description>        
</ManSection>


<ManSection>
   <Filt Name="IsCircleObject" 
         Arg="x" 
         Type="Category" />
   <Filt Name="IsCircleObjectCollection" 
         Arg="x" 
         Type="Category" />  
<Description>	      
An object <A>x</A> lies in the category <C>IsCircleObject</C> if and
only if it lies in a family constructed by <Ref Attr="CircleFamily"/>. 
Since circle objects can be multiplied via <C>*</C> with elements in 
their family, and we want to implement operations <C>One</C> and 
<C>Inverse</C> to deal with groups they generate, circle objects are
implemented in the category <C>IsMultiplicativeElementWithInverse</C>. 
  
<Example>
<![CDATA[
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 )
]]>
</Example>

</Description> 
</ManSection>

<ManSection>
   <Filt Name="IsPositionalObjectOneSlotRep" 
         Arg="x" 
         Type="Representation" />
   <Filt Name="IsDefaultCircleObject" 
         Arg="x" 
         Type="Representation" />         
<Description>
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 <C>IsPositionalObjectOneSlotRep</C> for a 
more general case. Then we defined <C>IsDefaultCircleObject</C> as a
synonym of <C>IsPositionalObjectOneSlotRep</C> for objects in 
<Ref Filt="IsCircleObject" />.

<Example>
<![CDATA[
gap> IsPositionalObjectOneSlotRep( CircleObject( 2 ) );
true
gap> IsDefaultCircleObject( CircleObject( 2 ) );                          
true
]]>
</Example>

</Description>              
</ManSection>

<ManSection>
   <Attr Name="CircleFamily"
         Arg="fam" />
<Description>    
<C>CircleFamily(fam)</C> is a family, elements of which are in one-to-one
correspondence with elements of the family <A>fam</A>,
but with the circle multiplication as an infix multiplication.
That is, for <M>x</M>, <M>y</M> in <A>fam</A>, the product of their images 
in the <C>CircleFamily(fam)</C> will be the image of <M> x + y + x y </M>.

<Example>
<![CDATA[
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
]]>
</Example>

</Description> 
</ManSection>

</Section>

<Section Label="CircleOperations">
<Heading>Operations with circle objects</Heading>
 
<ManSection>
   <Oper Name="OneOp" 
         Arg="x" />
<Description>	      
This operation returns the multiplicative neutral element 
for the circle object <A>x</A>. The result is the circle 
object corresponding to the additive neutral element of 
the appropriate ring. 

<Example>
<![CDATA[
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 ] ] )
]]>
</Example>

</Description>        
</ManSection>

<Alt Only="LaTeX">\pagebreak</Alt>

<ManSection>
   <Oper Name="InverseOp" 
         Arg="x" />
<Description>	      
For a circle object <A>x</A>, returns the multiplicative 
inverse of <A>x</A> with respect to the circle multiplication; 
if such one does not exist then <K>fail</K> is returned.

<Example>
<![CDATA[
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
]]>
</Example>

</Description>        
</ManSection>


<ManSection>
   <Oper Name="IsUnit" 
         Arg="R x" />
   <Oper Name="IsUnit" 
         Arg="x" />      
<Description>
Let <A>x</A> be a circle object corresponding to an element of 
the ring <A>R</A>. Then the operation <C>IsUnit</C> returns 
<C>true</C>, if <A>x</A> is invertible in <A>R</A> with respect
to the circle multiplication, and <C>false</C> otherwise.

<Example>
<![CDATA[
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
]]>
</Example>

<Alt Only="LaTeX">\pagebreak</Alt>

In the second form the result will be returned with respect
to the default ring of the circle object <A>x</A>.

<Example>
<![CDATA[
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
]]>
</Example>

</Description>              
</ManSection>


<ManSection>
   <Oper Name="IsCircleUnit" 
         Arg="R x" />
   <Oper Name="IsCircleUnit" 
         Arg="x" />         
<Description>
Let <A>x</A> be an element of the ring <A>R</A>. Then 
<C>IsCircleUnit( R, x )</C> determines whether <A>x</A> is invertible
in <A>R</A> with respect to the circle multilpication. This is 
equivalent to the condition that 1+<A>x</A> is a unit in <A>R</A> 
with respect to the ordinary multiplication. 

<Example>
<![CDATA[
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
]]>
</Example>

In the second form the result will be returned with respect
to the default ring of <A>x</A>.

<Example>
<![CDATA[
gap> IsCircleUnit( -2 );                               
true
gap> IsCircleUnit( 2 ); 
false
gap> IsCircleUnit( ZmodnZObj(2,8) );           
true
gap> IsCircleUnit( [ [ 1, 1 ],[ 0, 1 ] ] ); 
true
]]>
</Example>

</Description>              
</ManSection>

</Section>


<Alt Only="LaTeX">\pagebreak</Alt>

<Section Label="CircleAdjointGroups">
<Heading>Construction of the adjoint group</Heading>

<ManSection>
   <Attr Name="AdjointGroup" 
         Arg="R" />
<Description>
If <A>R</A> is a finite radical algebra then 
<C>AdjointGroup(<A>R</A>)</C> will return the adjoint group 
of <A>R</A>, given as a group generated by a set of circle objects.
<P/> 

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 <A>R</A> coincides with <A>R</A> elementwise,
and we can randomly select an appropriate set of generators for
the adjoint group. 
<P/>

The warning is displayed by <C>IsGeneratorsOfMagmaWithInverses</C>
method defined in <File>gap4r4/lib/grp.gi</File> and may be ignored.
<P/>

<B>WARNINGS:</B>
<P/>

1. The set of generators of the returned group is not required 
to be the minimal generating set.
<P/>

2. <C>AdjointGroup</C> is stored as an attribute of <A>R</A>, 
so for the same copy of <A>R</A> calling it again you will get 
the same result. But if you will create another copy of <A>R</A>
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.
<P/>

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.
<P/>

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:

<Example>
<![CDATA[
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"
]]>
</Example>

<Alt Only="LaTeX">\pagebreak</Alt>

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:

<Example>
<![CDATA[
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"
]]>
</Example>

If the ring <A>R</A> 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 <A>R</A> 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. 
<P/>

Of course, enumeration of all elements of <A>R</A> should be feasible
for this computation.
In the following example we demonstrate how it works for rings, 
generated by residue classes:

<Example>
<![CDATA[
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"
]]>
</Example>

<Alt Only="LaTeX">\pagebreak</Alt>

If <A>R</A> has a unity <M>1</M>, then the set <M>1+R^{ad}</M>, 
where <M>R^{ad}</M> is the adjoint semigroup of <A>R</A>, coincides
with the multiplicative semigroup <M>R^{mult}</M> of <M>R</M>, and the map 
<M> r \mapsto (1+r) </M> for <M>r</M> in <M>R</M> is an isomorphism 
from <M>R^{ad}</M> onto <M>R^{mult}</M>. 
<P/>

Similarly, the set <M>1+R^*</M>, where <M>R^{*}</M> is the adjoint 
group of <A>R</A>, coincides with the unit group of <M>R</M>, 
which we denote <M>U(R)</M>, and the map <M>r \mapsto (1+r)</M> 
for <M>r</M> in <M>R</M> is an isomorphism from <M>R^*</M> onto 
<M>U(R)</M>.
<P/>

We demonstrate this isomorphism using the following example. 

<Example>
<![CDATA[
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 ]
]]>
</Example>

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.
<P/>

If <A>R</A> is infinite, an error message will appear,
telling that &Circle; does not provide methods to deal
with infinite rings.

</Description>              
</ManSection>
  
</Section>

<Alt Only="LaTeX">\pagebreak</Alt>

<!-- ######################################################### -->

<Section Label="Service">
<Heading>Service functions</Heading>


<ManSection>
   <InfoClass Name="InfoCircle" />
<Description>
<C>InfoCircle</C> is a special Info class for &Circle; algorithms.
It has 2 levels: 0 (default) and 1. To change info level to 
<C>k</C>, use command <C>SetInfoLevel(InfoCircle, k)</C>. 

<Example>
<![CDATA[
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 );
]]>
</Example>

</Description>
</ManSection>


<ManSection>
   <Func Name="CIRCLEBuildManual" 
         Arg=""
	 Comm="requires GAPDoc, UNIX or Linux and &TeX;" />
   <Description>
      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.
   </Description>
</ManSection>


<ManSection>
   <Func Name="CIRCLEBuildManualHTML" 
         Arg=""
	 Comm="requires only GAPDoc" />
   <Description>
      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.
   </Description>
</ManSection>

</Section>

</Chapter>