# A potential pitfall when using boost::uniform_01

The Boost library collection has a highly useful random number library (Boost.Random). One of the classes in this library, boost::uniform_01, does however present a potential pitfall which I will briefly describe in this post. This pitfall is mentioned briefly in the library documentation but this post expands on this substantially.

## The problem

The following pair of examples illustrate the problem with boost::uniform_01.

The quick, introductory example on the front page of random number library documentation demonstrates how to generate random integers between one and six and reads as follows:

```// Note: *not* a compilable example, just fragment

boost::mt19937 rng;                 // produces randomness out of thin air
// see pseudo-random number generators
boost::uniform_int<> six(1,6)       // distribution that maps to 1..6
// see random number distributions
boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
die(rng, six);             // glues randomness with mapping
int x = die();                      // simulate rolling a die
```

This works fine.

Now, say instead of an integer between 1 and 6 you require a real number between 0 and 1. You may wish to use the class uniform_01 designed specifically for this purpose. Here is a an example that should compile and one that you would naturally try:

```// Bojan Nikolic <bojan@bnikolic.co.uk>

#include <boost/random.hpp>

double rn(void)
{
boost::mt19937 rng;
boost::uniform_01<> zeroone;
boost::variate_generator<boost::mt19937&,
boost::uniform_01<> >
gen(rng, zeroone);
return gen()
}
```

This fails to compile with the following error message:

```t1.cpp: In function ‘double rn()’:
t1.cpp:8: error: wrong number of template arguments (0, should be 2)
/usr/include/boost/random/uniform_01.hpp:30: error: provided for ‘template<class UniformRandomNumberGenerator, class RealType> class boost::uniform_01’
t1.cpp:8: error: invalid type in declaration before ‘;’ token
t1.cpp:10: error: wrong number of template arguments (0, should be 2)
/usr/include/boost/random/uniform_01.hpp:30: error: provided for ‘template<class UniformRandomNumberGenerator, class RealType> class boost::uniform_01’
t1.cpp:10: error: template argument 2 is invalid
t1.cpp:11: error: invalid type in declaration before ‘(’ token
t1.cpp:11: error: initializer expression list treated as compound expression
t1.cpp:12: error: ‘gen’ cannot be used as a function
t1.cpp:13: error: expected ‘;’ before ‘}’ token
```

The next logical step would be to provide the missing template parameter:

```// Bojan Nikolic <bojan@bnikolic.co.uk>

#include <boost/random.hpp>

double rn(void)
{
boost::mt19937 rng;
boost::uniform_01<boost::mt19937> zeroone;
boost::variate_generator<boost::mt19937&,
boost::uniform_01<> >
gen(rng, zeroone);
return gen()
}
```

but that fails with a difficult-to-decipher error message:

```t2.cpp: In function ‘double rn()’:
t2.cpp:8: error: no matching function for call to ‘boost::uniform_01<boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u>, double>::uniform_01()’
/usr/include/boost/random/uniform_01.hpp:42: note: candidates are: boost::uniform_01<UniformRandomNumberGenerator, RealType>::uniform_01(UniformRandomNumberGenerator) [with UniformRandomNumberGenerator = boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u>, RealType = double]
/usr/include/boost/random/uniform_01.hpp:31: note:                 boost::uniform_01<boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u>, double>::uniform_01(const boost::uniform_01<boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u>, double>&)
t2.cpp:10: error: wrong number of template arguments (0, should be 2)
/usr/include/boost/random/uniform_01.hpp:30: error: provided for ‘template<class UniformRandomNumberGenerator, class RealType> class boost::uniform_01’
t2.cpp:10: error: template argument 2 is invalid
t2.cpp:11: error: invalid type in declaration before ‘(’ token
t2.cpp:11: error: initializer expression list treated as compound expression
t2.cpp:11: error: cannot convert ‘boost::uniform_01<boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u>, double>’ to ‘int’ in initialization
t2.cpp:12: error: ‘gen’ cannot be used as a function
t2.cpp:13: error: expected ‘;’ before ‘}’ token
```

## A Solution

The reason for these error messages is that the design and interface of the boost::uniform_01 class is different to the other distribution classes. The primary differences in the interface are:

• The constructor of boost::uniform_01 takes a random number generator as parameter
• operator() of boost::uniform_01 does not take a random number generator as parameter.

As a result, there is a random number generator permanently attached to the boost::uniform_01 class and the use of boost::variate_generator is not necessary. The above example can therefore be reduced to the following compilable fragment:

```// Bojan Nikolic <bojan@bnikolic.co.uk>

#include <boost/random.hpp>

double rn(void)
{
boost::mt19937 rng;
boost::uniform_01<boost::mt19937> zeroone(rng);
return zeroone();
}
```

## The Pitfall

A pitfall arises because the boost::uniform_01 constructor makes a new copy of the random number generator passed to it. Therefore, calls to the boost::uniform_01 do not advance the random number generator that the distribution was initialised with.

Here is an example how things could go wrong because of this:

```// Bojan Nikolic <bojan@bnikolic.co.uk>

#include <iostream>

#include <boost/random.hpp>
#include <boost/format.hpp>

double rn(void)
{
// The rng is made static to preserve its state across calls
static boost::mt19937 rng(43);
// but zeroone makes a copy which means the rng above *never advances*
boost::uniform_01<boost::mt19937> zeroone(rng);
return zeroone();
}

int main(void)
{
std::cout<<boost::format("First draw: %g; second draw: %g") % rn() % rn()
<<std::endl;
}
```

The result of running this code is the surprising:

```First draw: 0.0114427; second draw: 0.0114427
```

I.e., not very random at all! This is however easily fixed by making the boost::uniform_01 object static:

```// Bojan Nikolic <bojan@bnikolic.co.uk>

#include <iostream>

#include <boost/random.hpp>
#include <boost/format.hpp>

double rn(void)
{
boost::mt19937 rng(43);
static boost::uniform_01<boost::mt19937> zeroone(rng);
return zeroone();
}

int main(void)
{
std::cout<<boost::format("First draw: %g; second draw: %g") % rn() % rn()
<<std::endl;
}
```

## Summary

The interface of boost::uniform_01 is significantly different to other random number distributions in Boost.Random library. Therefore, read the documentation and watch out for the copy of the random number generator parameter.