<!-- #################################################################### -->
<!-- ##                                                                ## -->
<!-- ##  resclass.xml      ResClasses documentation       Stefan Kohl  ## -->
<!-- ##                                                                ## -->
<!-- ##  $Id: resclass.xml,v 1.38 2006/09/28 14:51:30 stefan Exp $     ## -->
<!-- ##                                                                ## -->
<!-- #################################################################### -->

<Chapter Label="ch:UnionsOfResidueClasses">
<Heading>Unions of Residue Classes</Heading>

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

<Section Label="sec:DefiningUnionsOfResidueClasses">
<Heading>Entering residue classes and unions thereof</Heading>

<ManSection>
  <Func Name="ResidueClass" Arg="R, m, r" Label="R, m, r"/>
  <Func Name="ResidueClass" Arg="m, r" Label="m, r"/>
  <Func Name="ResidueClass" Arg="r, m" Label="r, m"/>
  <Returns>
    In the three-argument form the residue class
    <A>r</A>&nbsp;mod&nbsp;<A>m</A> of the ring&nbsp;<A>R</A>, and
    in the two-argument form the residue class
    <A>r</A>&nbsp;mod&nbsp;<A>m</A> of the integers.
  </Returns>
  <Description>
    In the two-argument case, <A>r</A> and <A>m</A> must not be negative,
    and <A>r</A> is assumed to lie in the range <C>[0..<A>m</A>-1]</C>.
    The latter is used to decide which of the two arguments is the
    modulus&nbsp;<A>m</A> and which is the residue&nbsp;<A>r</A>.
    For convenience, in the two-argument case it is permitted to enclose
    the argument list in list brackets. <P/>

    <Index Key="IsResidueClass" Subkey="U"><C>IsResidueClass</C></Index>
    <Index Key="Modulus" Subkey="cl"><C>Modulus</C></Index>
    <Index Key="Residue" Subkey="cl"><C>Residue</C></Index>

    Residue classes have the property <C>IsResidueClass</C>.
    Rings are regarded as residue class 0&nbsp;(mod&nbsp;1),
    and therefore have this property. There are operations <C>Modulus</C>
    and <C>Residue</C> to retrieve the modulus&nbsp;<A>m</A> resp.
    residue&nbsp;<A>r</A> of a residue class.
<Example>
<![CDATA[
gap> ResidueClass(2,3);
The residue class 2(3) of Z
gap> ResidueClass(Z_pi([2,5]),2,1);
The residue class 1(2) of Z_( 2, 5 )
gap> R := PolynomialRing(GF(2),1);;
gap> x := Indeterminate(GF(2),1);; SetName(x,"x");
gap> ResidueClass(R,x+One(R),Zero(R));
The residue class 0*Z(2) ( mod x+Z(2)^0 ) of GF(2)[x]
]]>
</Example>
  </Description>
</ManSection>

<ManSection>
  <Func Name="ResidueClassUnion"
        Arg="R, m, r" Label="R, m, r"/>
  <Func Name="ResidueClassUnion"
        Arg="R, m, r, included, excluded"
        Label="R, m, r, included, excluded"/>
  <Returns>
    The union of the residue classes
    <A>r</A>[<M>i</M>]&nbsp;mod&nbsp;<A>m</A>
    of the ring&nbsp;<A>R</A>, plus / minus finite sets <A>included</A>
    and <A>excluded</A> of elements of&nbsp;<A>R</A>.
  </Returns>
  <Description>
<Alt Only="LaTeX">\pagebreak[4]</Alt>
<Example>
<![CDATA[
gap> ResidueClassUnion(Integers,6,[2,4]);
Union of the residue classes 2(6) and 4(6) of Z
gap> ResidueClassUnion(Integers,5,[1,2],[3,8],[-4,1]);
(Union of the residue classes 1(5) and 2(5) of Z) U [ 3, 8 ] \ [ -4, 1 ]
gap> ResidueClassUnion(Z_pi([2,3]),8,[3,5]);
<union of 2 residue classes (mod 8) of Z_( 2, 3 )>
gap> ResidueClassUnion(R,x^2,[One(R),x],[Zero(R)],[One(R)]);
<union of 2 residue classes (mod x^2) of GF(2)[x]> U [ 0*Z(2) ] \ [ Z(2)^0 ]
]]>
</Example>
  </Description>
</ManSection>

<Index Key="Modulus" Subkey="U"><C>Modulus</C></Index>
<Index Key="Residues" Subkey="U"><C>Residues</C></Index>
<Index Key="IncludedElements" Subkey="U"><C>IncludedElements</C></Index>
<Index Key="ExcludedElements" Subkey="U"><C>ExcludedElements</C></Index>

For extracting the components of a residue class union as passed as
arguments to <Ref Func="ResidueClassUnion" Label="R, m, r"/>, there are
operations <C>Modulus</C>, <C>Residues</C>, <C>IncludedElements</C> and
<C>ExcludedElements</C>. <P/>

<Index Key="ResidueClassUnionViewingFormat" Subkey="format">
  <C>ResidueClassUnionViewingFormat</C>
</Index>

The user has the choice between a longer and more descriptive
and a shorter and less bulky output format for residue classes and
unions thereof:

<Example>
<![CDATA[
gap> ResidueClassUnionViewingFormat("short");
gap> ResidueClassUnion(Integers,12,[0,1,4,7,8]);  
0(4) U 1(6)
gap> ResidueClassUnionViewingFormat("long");    
gap> ResidueClassUnion(Integers,12,[0,1,4,7,8]);
Union of the residue classes 0(4) and 1(6) of Z
]]>
</Example>

<ManSection>
  <Func Name="AllResidueClassesModulo" Arg="R, m" Label="R, m"/>
  <Func Name="AllResidueClassesModulo" Arg="m" Label="m"/>
  <Returns>
    A sorted list of all residue classes (mod&nbsp;<A>m</A>)
    of the ring&nbsp;<A>R</A>.
  </Returns>
  <Description>
    If the argument <A>R</A> is omitted it defaults to the default ring of
    <A>m</A> -- cp. the documentation of <C>DefaultRing</C> in the &GAP;
    reference manual.
    <Index Key="AllResidues" Subkey="R, m">
      <C>AllResidues</C>
    </Index>
    <Index Key="NumberOfResidues" Subkey="R, m">
      <C>NumberOfResidues</C>
    </Index>
    A transversal for the residue classes (mod&nbsp;<A>m</A>) can be
    obtained by the operation <C>AllResidues(<A>R</A>,<A>m</A>)</C>,
    and their number can be determined by the operation
    <C>NumberOfResidues(<A>R</A>,<A>m</A>)</C>.
<Example>
<![CDATA[
gap> AllResidueClassesModulo(Integers,2);
[ The residue class 0(2) of Z, The residue class 1(2) of Z ]
gap> AllResidueClassesModulo(Z_pi(2),2);
[ The residue class 0(2) of Z_( 2 ), The residue class 1(2) of Z_( 2 ) ]
gap> AllResidueClassesModulo(R,x);
[ The residue class 0*Z(2) ( mod x ) of GF(2)[x], 
  The residue class Z(2)^0 ( mod x ) of GF(2)[x] ]
gap> AllResidues(Integers,6);
[ 0 .. 5 ]
gap> AllResidues(R,x^3);  
[ 0*Z(2), Z(2)^0, x, x+Z(2)^0, x^2, x^2+Z(2)^0, x^2+x, x^2+x+Z(2)^0 ]
]]>
</Example>
  </Description>
</ManSection>

</Section>

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

<Section Label="sec:MethodsForResidueClassUnions">
<Heading>Methods for unions of residue classes</Heading>

<Index Key="Print" Subkey="U"><C>Print</C></Index>
<Index Key="String" Subkey="U"><C>String</C></Index>
<Index Key="Display" Subkey="U"><C>Display</C></Index>

There are methods for <C>Print</C>, <C>String</C> and <C>Display</C>
which are applicable to unions of residue classes. There is a method
for <C>in</C> which tests whether some ring element lies in a given union
of residue classes.

<Example>
<![CDATA[
gap> Print(ResidueClass(1,2),"\n");
ResidueClassUnion( Integers, 2, [ 1 ] )
gap> 1 in ResidueClass(1,2);
true
]]>
</Example>

<Index Key="Union" Subkey="U1, U2"><C>Union</C></Index>
<Index Key="Intersection" Subkey="U1, U2"><C>Intersection</C></Index>
<Index Key="Difference" Subkey="U1, U2"><C>Difference</C></Index>
<Index Key="IsSubset" Subkey="U1, U2"><C>IsSubset</C></Index>

There are methods for <C>Union</C>, <C>Intersection</C>, <C>Difference</C>
and <C>IsSubset</C> available for unions of residue classes.
They also accept finite subsets of the base ring as arguments.

<Example>
<![CDATA[
gap> S := Union(ResidueClass(0,2),ResidueClass(0,3));         
Z \ Union of the residue classes 1(6) and 5(6) of Z
gap> Intersection(S,ResidueClass(0,7));
Union of the residue classes 0(14) and 21(42) of Z
gap> Difference(S,ResidueClass(2,4));
Union of the residue classes 0(4) and 3(6) of Z
gap> IsSubset(ResidueClass(0,2),ResidueClass(4,8));
true
gap> Union(S,[1..10]);
(Union of the residue classes 0(2) and 3(6) of Z) U [ 1, 5, 7 ]
gap> Intersection(S,[1..10]);
[ 2, 3, 4, 6, 8, 9, 10 ]
gap> Difference(S,[1..10]);
(Union of the residue classes 0(2) and 3(6) of Z) \ [ 2, 3, 4, 6, 8, 9, 10 ]
gap> Difference(Integers,[1..10]);
Z \ <set of cardinality 10>
gap> IsSubset(S,[1..10]);
false
]]>
</Example>

If the underlying ring has a residue class ring of a given
cardinality&nbsp;<M>t</M>, then a residue class can be written as
a disjoint union of <M>t</M> residue classes with equal moduli:

<ManSection>
  <Oper Name="SplittedClass" Arg="cl, t" Label="cl, t"/>
  <Returns>
    A partition of the residue class <A>cl</A> into <A>t</A> residue
    classes with equal moduli, provided that such a partition exists.
    Otherwise <C>fail</C>.
  </Returns>
  <Description>
<Example>
<![CDATA[
gap> SplittedClass(ResidueClass(1,2),2);
[ The residue class 1(4) of Z, The residue class 3(4) of Z ]
gap> SplittedClass(ResidueClass(Z_pi(3),3,0),2);
fail
]]>
</Example>
  </Description>
</ManSection>

Often one needs a partition of a given union of residue classes into
<Q>few</Q> residue classes. Ensuring to get always a partition of minimal
possible length seems to be algorithmically difficult.
The following operation finds usually <Q>reasonably short</Q> partitions:

<ManSection>
  <Oper Name="AsUnionOfFewClasses" Arg="U" Label="U"/>
  <Returns>
    A set of disjoint residue classes whose union is <A>U</A>.
  </Returns>
  <Description>
    As the name of the operation suggests, it is taken care that
    the number of residue classes in the returned list is kept
    <Q>reasonably small</Q>. It is not necessarily minimal.
    No care is taken of <C>IncludedElements</C> and
    <C>ExcludedElements</C>.
<Example>
<![CDATA[
gap> AsUnionOfFewClasses(Difference(Integers,ResidueClass(0,12)));
[ The residue class 1(2) of Z, The residue class 2(4) of Z, 
  The residue class 4(12) of Z, The residue class 8(12) of Z ]
]]>
</Example>
  </Description>
</ManSection>

One can compute the sets of sums, differences, products and quotients of
the elements of a union of residue classes and an element of the base ring:

<Example>
<![CDATA[
gap> ResidueClass(0,2) + 1;
The residue class 1(2) of Z
gap> ResidueClass(0,2) - 2 = ResidueClass(0,2); 
true
gap> 3 * ResidueClass(0,2);
The residue class 0(6) of Z
gap> ResidueClass(0,2)/2;
Integers
]]>
</Example>

<ManSection>
  <Oper Name="Density" Arg="U" Label="U"/>
  <Returns>
    The natural density of&nbsp;<A>U</A> as a subset of the underlying ring.
  </Returns>
  <Description>
    The <E>natural density</E> of a residue class <M>r(m)</M>
    of a ring&nbsp;<M>R</M> is defined by <M>1/|R/mR|</M>, and
    the <E>natural density</E> of a union&nbsp;<M>U</M> of finitely many
    residue classes is defined by the sum of the densities of the elements
    of a partition of&nbsp;<M>U</M> into finitely many residue classes.
<Example>
<![CDATA[
gap> Density(ResidueClass(0,2));
1/2
gap> Density(Difference(Integers,ResidueClass(0,5)));
4/5
]]>
</Example>
  </Description>
</ManSection>

<ManSection>
  <Oper Name="RandomPartitionIntoResidueClasses"
        Arg="R, length, primes" Label="R, length, primes"/>
  <Returns>
    A <Q>random</Q> partition of the ring&nbsp;<A>R</A> into <A>length</A>
    residue classes whose moduli have only prime factors in <A>primes</A>,
    resp. <C>fail</C> if no such partition exists.
  </Returns>
  <Description>
<Log>
<![CDATA[
gap> ResidueClassUnionViewingFormat("short");
gap> RandomPartitionIntoResidueClasses(Integers,30,[2,3,5,7]);
[ 2(7), 3(7), 4(7), 5(7), 6(7), 1(35), 8(35), 14(35), 21(35), 22(35), 28(35), 
  29(35), 7(105), 15(105), 42(105), 50(105), 77(105), 85(105), 70(175), 
  105(175), 35(350), 210(350), 0(525), 140(525), 315(525), 350(525), 
  490(525), 175(1575), 700(1575), 1225(1575) ]
gap> Union(last);
Integers
gap> Sum(List(last2,Density));
1
]]>
</Log>
  </Description>
</ManSection>


<Index Key="Iterator" Subkey="U"><C>Iterator</C></Index>
<Index Key="NextIterator" Subkey="iter"><C>NextIterator</C></Index>

For looping over unions of residue classes of the integers, there are
methods for the operations <C>Iterator</C> and <C>NextIterator</C>.

</Section>

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

<Section Label="sec:CategoriesOfUnionsOfResidueClasses">
<Heading>The categories and families of unions of residue classes</Heading>

<ManSection>
  <Filt Name="IsUnionOfResidueClasses" Arg="U" Label="U"/>
  <Filt Name="IsUnionOfResidueClassesOfZ" Arg="U" Label="U"/>
  <Filt Name="IsUnionOfResidueClassesOfZ_pi" Arg="U" Label="U"/>
  <Filt Name="IsUnionOfResidueClassesOfGFqx" Arg="U" Label="U"/>
  <Returns>
    <C>true</C> if <A>U</A> is a union of residue classes resp.
    a union of residue classes of the ring of integers resp.
    a union of residue classes of a semilocalization of the ring of integers
    resp. a union of residue classes of a polynomial ring in one variable
    over a finite field, and <C>false</C> otherwise.
  </Returns>
  <Description>
    Often the same methods can be used for residue classes of the ring of
    integers and of its semilocalizations. For this reason there is
    a category <C>IsUnionOfResidueClassesOfZorZ&uscore;pi</C> which is the
    union of <C>IsUnionOfResidueClassesOfZ</C> and
    <C>IsUnionOfResidueClassesOfZ&uscore;pi</C>.
    <Index Key="IsUnionOfResidueClassesOfZorZ_pi" Subkey="U">
      <C>IsUnionOfResidueClassesOfZorZ&uscore;pi</C>
    </Index>
    The internal representation of unions of residue classes is called
    <C>IsResidueClassUnionSparseRep</C>.
    <Index Key="IsResidueClassUnionSparseRep">
      <C>IsResidueClassUnionSparseRep</C>
    </Index>
  </Description>
</ManSection>

<ManSection>
  <Func Name="ResidueClassUnionsFamily"
        Arg="R" Label="R"/>
  <Func Name="ResidueClassUnionsFamily"
        Arg="R, fixedreps" Label="R, fixedreps"/>
  <Returns>
    The family of unions of residue classes resp. the family of unions
    of residue classes with fixed representatives of the ring&nbsp;<A>R</A>,
    depending on whether <A>fixedreps</A> is present and <C>true</C>.
  </Returns>
  <Description>
    The ring <A>R</A> can be retrieved as
    <C>UnderlyingRing(ResidueClassUnionsFamily(<A>R</A>))</C>.
    Unions of residue classes with fixed representatives are described
    in the next chapter.
  </Description>
</ManSection>

</Section>

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

</Chapter>

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