From: Oliver Kullmann (O.Kullmann_at_[hidden])
Date: 2004-06-22 18:24:01


Hi,

following the request for some improved documentation
in my first e-mail (illustrated by some "case study" from a student's
experience) I would like to propose to include the
following class template RandomGeneratorInterval
into the documentation of the random number library
(a first draft, more explanations
should be added; of course, names can be changed).
It solves the task from my previous e-mail, and seems to
me a very typical first use of the library:

  template <class bgt = boost::minstd_rand, class dt = boost::uniform_int<> >
  class RandomGeneratorInterval {
  public :
    typedef bgt base_generator_type;
    typedef dt distribution_type;
    typedef boost::variate_generator<base_generator_type, distribution_type> generator_type;
    typedef typename generator_type::result_type interval_type;
    typedef typename base_generator_type::result_type seed_type;
    RandomGeneratorInterval(interval_type min, interval_type max) : min(min), max(max) {}
    generator_type operator() (seed_type seed = 1) const {
      assert(seed != 0);
      return generator_type(base_generator_type(seed), distribution_type(min, max));
    }
  private :
    const interval_type min, max;
  };
  // An object rgi defined by "RandomGeneratorInterval rgi(min, max)" can create a random number generator g via g = rgi(seed).
  // Random numbers in the interval from min to max then are created with g().
  // It is g() of type interval_type as well as min and max, while seed is of type seed_type; g itself is of type generator_type.
  // g is a model of a uniform random number generator (even a model of a pseudo-random number generator?!).

Examples for usage are

  typedef Algorithms::RandomGeneratorInterval<> RI;
  RI rgi(10,20);
  RI::generator_type g1 = rgi(456);
  RI::generator_type g2 = rgi();
  RI::generator_type g3 = rgi(1);
  assert(g1.min() == 10);
  assert(g1.max() == 20);
  assert(g1() == 10);
  assert(g1() == 18);
  assert(g1() == 12);
  assert(g2() == 10);
  assert(g2() == 10);
  assert(g2() == 16);
  assert(g3() == 10);
  assert(g3() == 10);
  assert(g3() == 16);
  // Attention: std::cout << g1() << " " << g1() results in implementation-defined behaviour (could be "10 18" or "18 12") !

(The last line seems a typical trap to me one has to be aware of, and thus it seems worth to
be included.)

Does the above code look reasonable?!

Oliver