<!-- 

         random.xml            orb package documentation             
                                                                Juergen Mueller
                                                            and Max Neunhoeffer
                                                               and Felix Noeske

  Copyright (C) 2005-2008 by the authors

This chapter explains functionality for random elements.

-->

<Chapter Label="random">
<Heading>Random elements</Heading>

In this chapter we describe some fundamental mechanisms to produce
(pseudo-) random elements that are used later in Chapter 
<Ref Chap="search"/> about searching in groups and orbits.


<Section>
<Heading>Randomizing mutable objects</Heading>

For certain types of mutable objects one can get a <Q>random one</Q>
by calling the following operation:

<ManSection>
<Oper Name="Randomize" Arg="ob [,rs]"/>
<Returns> nothing </Returns>
<Description>
The mutable object <A>ob</A> is changed in place. The value afterwards
is random. The optional second argument <A>rs</A> must be a random
source and the random numbers used to randomize <A>ob</A> are created
using the random source <A>rs</A> 
(see <Ref Subsect="Random Sources" BookName="ref"/>). 
If <A>rs</A> is not given, then
the global &GAP; random number generator is used.

<P/>
Currently, there are <Ref Oper="Randomize"/> methods for compressed
vectors and compressed matrices over finite fields. See also the 
<Package>cvec</Package> package for methods for <C>cvec</C>s and <C>cmat</C>s.
</Description>
</ManSection>

For vectors and one-dimensional subspaces there are two special functions
to create a list of random objects:

<ManSection>
<Func Name="MakeRandomVectors" Arg="sample, number [,rs]"/>
<Returns> a list of random vectors </Returns>
<Description>
<A>sample</A> must be a vector for the mutable copies of which
<Ref Oper="Randomize"/> is applicable and <A>number</A> must be a positive
integer. If given, <A>rs</A> must be a random source. This function
creates a list of <A>number</A> random vectors with the same type as 
<A>sample</A> using <Ref Oper="Randomize"/>. For the creation of random
numbers the random source <A>rs</A> is used or, if not given, the
global &GAP; random number generator.
</Description>
</ManSection>

<ManSection>
<Func Name="MakeRandomLines" Arg="sample, number [,rs]"/>
<Returns> a list of normalised random vectors </Returns>
<Description>
<A>sample</A> must be a vector for the mutable copies of which
<Ref Oper="Randomize"/> is applicable and <A>number</A> must be a positive
integer. If given, <A>rs</A> must be a random source. This function
creates a list of <A>number</A> normalised random vectors with the same
type as <A>sample</A> using <Ref Oper="Randomize"/>. <Q>Normalised</Q>
here means that the first non-zero entry in the vector is equal to <M>1</M>.
For the creation of random numbers the random source <A>rs</A> is used
or, if not given, the global &GAP; random number generator.
</Description>
</ManSection>

</Section>

<Section Label="prodrepl">
<Heading>Product replacement</Heading>

For computations in finite groups product replacement algorithms
are a viable method of generating pseudo-random elements. This section
describes a framework and an object type to provide these algorithms.
Roughly speaking a <Q>product replacer object</Q> is something that
is created with a list of group generators and produces a sequence
of pseudo random group elements using some random source for random numbers.

<ManSection>
<Oper Name="ProductReplacer" Arg="gens [,opt]"/>
<Returns> a new product replacer object </Returns>
<Description>
<A>gens</A> must be a list of group generators. If given, <A>opt</A> is
a &GAP; record with options. The operation creates a new product replacer
object producing pseudo random elements in the group generated by the
generators <A>gens</A>.
<P/>
The exact algorithm used is explained below after the description
of the options.
<P/>
The following components in the options record have a defined meaning:
<List>
<Mark><C>randomsource</C></Mark>
<Item>A random source object that is used to generate the random numbers
    used. If none is specified the global &GAP; random number generator
    is used.
</Item>
<Mark><C>scramble</C></Mark>
<Item>The <C>scramble</C> value in the algorithm described below can be
    set using this option. The default value is <M>30</M>.
</Item>
<Mark><C>scramblefactor</C></Mark>
<Item>The <C>scramblefactor</C> value in the algorithm described below
    can be set using this option. The default value is <M>4</M>.
</Item>
<Mark><C>addslots</C></Mark>
<Item>The <C>addslots</C> value in the algorithm described below
    can be set using this option. The default value is <M>5</M>.
</Item>
<Mark><C>maxdepth</C></Mark>
<Item>If <C>maxdepth</C> is set, then the production of pseudo random
    elements starts all over whenever <C>maxdepth</C> product replacements
    have been performed. The rationale behind this is that the elements
    created should be evenly distributed but that the expressions in
    the generators should not be too long. A good compromise is usually
    to set <C>maxdepth</C> to <M>300</M> or <M>400</M>.
</Item>
<Mark><C>noaccu</C></Mark>
<Item>Without this option set to <K>true</K> the <Q>rattle</Q> version
    of product replacement is used which involves an accumulator and
    uses two or three products per random element. To use the <Q>shake</Q>
    version with only one or two product replacement per random element set
    this component to <K>true</K>. The exact number of multiplications
    per random element also depends on the value of the
    <C>accelerator</C> component.
</Item>
<Mark><C>normalin</C></Mark>
<Item>There is a variant of the product replacement algorithm that
    produces elements in the normal closure of the group generated by
    a list of elements. It needs random elements in the ambient group
    in which the normal closure is defined. This is implemented here
    by setting the <C>normalin</C> component to a product replacer
    object working in the ambient group. In every step two elements
    <M>a</M> and <M>b</M> are picked and then <M>a</M> is either replaced
    by <M>a*b^c</M> or <M>b^c*a</M> (with equal probability), where
    <M>c</M> is a random element from the ambient group produced by the
    product replacer in the <C>normalin</C> component. It is recommended
    to switch off the accumulator and accelerator 
    in the product replacer object for
    the ambient group. Then to produce one random element in the normal
    closure needs four multiplications.
</Item>
<Mark><C>accelerator</C></Mark>
<Item>If this option is set to <K>true</K> (which is the default),
    then the accelerator is used. This means that in each step two
    product replacement steps are performed, where both involve one
    distinguished slot called the <Q>captain</Q>. The idea is that
    the current <Q>team</Q> of random elements uses one amongst them
    more often to increase the length of the words produced. See below
    for details of the algorithm with and without accelerator.
</Item>
<Mark><C>retirecaptain</C></Mark>
<Item>If this component is bound to a positive integer then the
    captain retires after so many steps of the algorithm. This is to
    use only two multiplications for each random element in the long
    run after proper mixing. The default value for
    <C>retirecaptain</C> is twice the scrambling time.
</Item>
<Mark><C>accus</C></Mark>
<Item>This component (default is 5) is the number of accumulators to
    use in the rattle variant. All accus are used in a round robin
    fashion. The purpose of multiple accus is to have a greater
    stochastical independence of adjacent random elements in the
    sequence.
</Item>
</List>

The algorithm used does the following: A list of 
<C>Length(</C><A>gens</A><C>)+addslots</C>
elements is created that starts with the elements <A>gens</A> and is
filled up with random generators from <A>gens</A>. This element is
called the <Q>team</Q>. A product replacement without accelerator
randomly chooses two elements in the list and replaces one of them
by the product of the two. If an accelerator is used, then one
product replacement step randomly chooses two slots <M>i</M> and
<M>j</M> where <M>i,j > 1</M> but <M>i=j</M> is possible. Then first
<M>l[1]</M> is replaced by <M>l[1]*l[i]</M> and after that <M>l[j]</M> is
replaced by <M>l[j]*l[1]</M>. The first team member is called the
<Q>captain</Q>, so the captain is involved in every product
replacement.
<P/>
One step in the algorithm is to do
one product replacement followed by post-multiplying the result to 
the accumulator if one (or more) is used. Multiple accus (see the
<C>accus</C> component) are used in a round robin fashion.
<P/>
First
<C>Maximum(Length(</C><A>gens</A><C>)*scramblefactor,scramble)</C>
steps are performed. After this initialisation
for every random element requested one step is done
and the resulting element returned. </Description>
</ManSection>

<ManSection>
<Oper Name="Next" Arg="pr"/>
<Returns> a (pseudo-) random group element g </Returns>
<Description>
<A>pr</A> must be a product replacer object. This operation makes the
object generate the next random element and return it.
</Description>
</ManSection>

<ManSection>
<Oper Name="Reset" Arg="pr"/>
<Returns> nothing </Returns>
<Description>
    <A>pr</A> must be a product replacer object. This operation resets the
    object in the sense that it resets the product replacement back to
    the state it had after scrambling. Note that since the random
    source is not reset, the product replacer object will return
    another sequence of random elements than before.
</Description>
</ManSection>

<ManSection>
    <Oper Name="AddGeneratorToProductReplacer" Arg="pr, el"/>
    <Returns> nothing </Returns>
    <Description>
        <A>pr</A> must be a product replacer object. This operation
        adds the new generator <A>el</A> to the product replacer
        without needing a completely new initialisation phase. From
        after this call on the product replacer will generate random
        elements in the group generated by the old generators and the
        new element <A>el</A>.
    </Description>
</ManSection>

</Section>

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

</Chapter>
