Boost logo

Boost :

From: Kris Thielemans (kris.thielemans_at_[hidden])
Date: 2004-07-05 20:04:47


3 more comments on the random number library.

1) Further on the topic started by Oliver Kullmann, and the reply by
Cromwell Enage:

-------Start Quote:---------
  typedef boost::uniform_int<> UniformDist;
  UniformDist dist(min,max);
  typedef boost::mt19937 BaseRNG;
  BaseRNG rng;
     your_generator(rng, dist);

Note the ampersand; your program will fail silently if
you omit it.
-------End Quote:---------

An example why you could need the &:

Suppose you have your_generator being defined locally, as it depends on
some run-time parameters

  int f(int min, int max)
     UniformDist dist(min,max);
     static BaseRNG rng;
        your_generator(rng, dist);
     return your_generator();

If you don't have the &, the variate_generator constructor will make a
fresh copy of the
rng object every time f() is called. Result: your random number will
always be the same!

On the other hand, using it without ampersand works fine for me in other

I find this rather subtle (i.e. it took me a few hours to understand why
my data were not what they should have been). So, maybe the
documentation for variate_generator should be more explicit about this.
I've tried to write a doc for this, but find that it probably needs
explicit examples. Here it is anyway

"Whether you use a reference, pointer, or 'plain' type for the Engine
template parameter of variate_generator<Engine, Distribution> depends on
similar considerations as for ordinary functions. E.g. if a reference is
used, subsequent calls of the variate_generator::operator() will modify
the state of the referenced Engine object, which is probably useful if
the same Engine object is used for multiple variate_generator<Engine,
Distribution> objects. "


2) While on the topic of references, the following generates a compiler

  boost::uniform_01<BaseRNG &> random01(generator)

/home/kris/mydoc/include/boost/random/uniform_01.hpp:58: error: forming
   reference to reference type `stir::base_generator_type&'


3) on distribution::operator()(Engine& eng)

template<class Engine>
normal_distribution::operator()(Engine& eng) assumes that Engine is like
uniform_01. This not documented, and worse, also not checked in the

  template<class Engine>
  result_type operator()(Engine& eng)
    if(!_valid) {
      _r1 = eng();
      _r2 = eng();
      _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2));
      _valid = true;
    } else {
      _valid = false;
    // etc

I would recommend to insert something like

Of course, when using
        variate_generator<Engine, normal_distribution<double> >
the Engine is converted into a uniform_01 if necessary.

I'm afraid that the same is true for the gamma_distribution and
geometric_distribution class. So, maybe
some_distribution::operator()(Engine& eng) should not be used at all. If
so, it should not be public (at least for compilers that can do template
friends I guess). However, it is required by the 'Random Distribution'
concept. Any particular reason that we need it?

Kris Thielemans
Hammersmith Imanet
Du Cane Road
London W12 0NN

Boost list run by bdawes at, gregod at, cpdaniel at, john at