Re: [boost] Random number library

Hi 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; boost::variate_generator<BaseRNG&,UniformDist> 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; boost::variate_generator<BaseRNG&,UniformDist> 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 situations. 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 error. 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 code. 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 assert(eng.min()==result_type(0)); assert(eng.max()==result_type(1)); BOOST_STATIC_ASSERT(!std::numeric_limits<Engine::result_type>::is_intege r); 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 UK http://www.HammersmithImanet.com/~kris
participants (1)
-
Kris Thielemans