Randomness

Learning Objective
In this tutorial, you will get a short walk-through of SeqAn’s module random. The module contains code for generating random numbers in various distributions.
Difficulty
Basic
Duration
10 min
Prerequisites
A First Example, Sequences

This tutorial explains how to use the module random. random primarily provides the two classes Rng (Random Number Generator) and Pdf (Probability Density Functions).

Warning

This module is deprecated in favor of C++11 random number generation facilities.

Random Number Generation

Instances of the class Rng are responsible for random number generation. Currently, SeqAn provides only one specialization, the MersenneTwisterRng. This class is used for generating random 32-bit numbers. These 32-bit numbers are then used by the Pdf specializations to generate random numbers in certain distributions as explained further below.

The following program gives an example. First, we include the header <seqan/random.h> to get access to the module’s functionality.

#include <iostream>

#include <seqan/basic.h>
#include <seqan/stream.h>
#include <seqan/random.h>

using namespace seqan;

const int SEED = 42;

int main()
{

During the initialization of the Rng object you have to pass a seed used as a start point for the randomization. Finally, function pickRandomNumber picks a random number from a Rng.

    Rng<MersenneTwister> rng(SEED);
    std::cout << "pickRandomNumber(rng) == " << pickRandomNumber(rng) << std::endl;

The output of this fragment is:

pickRandomNumber(rng) == 1608637542

Mersenne Twister Rng generates 32-bit unsigned numbers. However, you should not rely on any specific type and use Value metafunction instead.

    typedef Value<Rng<MersenneTwister> >::Type TMTValue;
    TMTValue value = pickRandomNumber(rng);

If you prefer a special distribution of the randomly generated numbers you can use the above mentioned specializations of Pdf. SeqAn currently provides normal, log-normal and uniform probability density functions. Note, for uniform distributions the range of values is given as a closed interval, i.e. the last value is enclosed in the range.

    Pdf<Uniform<double> > uniformDouble(0, 1);
    std::cout << "pickRandomNumber(rng, uniformDouble) == " << pickRandomNumber(rng, uniformDouble) << std::endl;
    Pdf<Uniform<int> > uniformInt(0, 42);
    std::cout << "pickRandomNumber(rng, uniformInt) == " << pickRandomNumber(rng, uniformInt) << std::endl;
    Pdf<Normal> normal(0, 1);
    std::cout << "pickRandomNumber(rng, normal) == " << pickRandomNumber(rng, normal) << std::endl;
    Pdf<LogNormal> logNormal(0, 1);
    std::cout << "pickRandomNumber(rng, logNormal) == " << pickRandomNumber(rng, logNormal) << std::endl;

The output of this fragment is:

pickRandomNumber(rng, uniformDouble) == 0.950714
pickRandomNumber(rng, uniformInt) == 27
pickRandomNumber(rng, normal) == 0.419823

Also note that you can initialize the Log-Normal Pdf either with mean and standard deviation of the log-normal distribution or the underlying normal distribution. By default, you initialize it with the mean and standard deviation (mu and sigma) of the underlying normal distribution. Use the tags MuSigma and MeanStdDev in the constructor to select a mode.

    Pdf<LogNormal> logNormal2(0, 1, MuSigma());
    std::cout << "pickRandomNumber(rng, logNormal2) == " << pickRandomNumber(rng, logNormal2) << std::endl;
    Pdf<LogNormal> logNormal3(0.1, 1, MeanStdDev());
    std::cout << "pickRandomNumber(rng, logNormal3) == " << pickRandomNumber(rng, logNormal3) << std::endl;
pickRandomNumber(rng, logNormal) == 1.22431
pickRandomNumber(rng, logNormal2) == 2.78004
pickRandomNumber(rng, logNormal3) == 0.00155248

Shuffling

The function shuffle allows to shuffle a container, given a random number generator:

    CharString container = "Hello World!";
    shuffle(container, rng);
    std::cout << "shuffle(\"Hello World!\") == " << container << std::endl;

    return 0;
}

The output of this fragment is:

shuffle("Hello World!") == oreWlloHld