Hi Kevin, others,
Thank you for your responses, sorry for the long delay.
I have decided to try to do without the whole singleton (although I
don't really see what the point is of avoiding a singleton if we still
have a global pointer, its almost the same thing) as an exercise and
try out Kevin's implementation.
I made some small changes to the code (code at bottom fo post) to make
sure that the generator is constructed if it wasn't yet (and seeded in
the process) so i don't have to do that by hand in my code. That
exactly fits what i need, and as it is seeded automatically, i cannot
forget to do so. I would never want to change my seed, nor be able to
set it to a specific value manually.
On Wed, Aug 5, 2009 at 12:10 AM, Kevin Martin wrote:
On 4 Aug 2009, at 06:39, Diederick C. Niehorster wrote:
I have looked it up, thank you for the suggestion. I, however do not
see the advantage of wrapping the generator.
Well you are wrapping up the variate_generator yourself with your
specializations of the CRandom template. My suggestion is that
instead of your CRandom class, you just return the variate_generator
inside a boost function.
Hmm, i have tried so, but the syntax to actually extract the random
numbers becomes very complicated now (I think i am missing a point
here, i am new to boost.function). With my class, i could simply
create an instance of a variate generator and then get a random number
using the () operator. See example:
CRandom Cr(1,100);
int test = Cr();
which with a typedef "typedef CRandom CRandomI;"
i can easily shorten to:
CRandomI Cr(1,100);
int test = Cr();
I have only managed to find two ways to get my random number using the
boost.function approach, both of which need considerably more typeing
by the user. It makes me want to wrap the boost.function in a class...
(Method one is stupid of course, it would generate a new distribution
every time i request a number.)
What step am I still missing here?
Thanks and best regards,
Diederick
----
// includes
#include
#include
#include <iostream>
#include
#include
// could use a macro to set the generator used in the code, for easy change
// kevin martin:
static boost::shared_ptrboost::mt19937 generator_;
void grng_setGenerator(boost::shared_ptrboost::mt19937 ptr)
{
if(!ptr) throw std::runtime_error("Tried to set generator to NULL pointer");
if(generator_) throw std::runtime_error("Tried to set generator
more than once");
generator_ = ptr;
}
boost::mt19937 &grng_generator()
{
if(generator_) return *generator_;
// if doesn't exist, set
grng_setGenerator(boost::shared_ptrboost::mt19937(new
boost::mt19937(unsigned int(time(NULL)))));
if(generator_) return *generator_;
// if still doesn't exist, error
throw std::runtime_error("Requested RNG, but there isn't one");
}
template<class Distribution_>
boost::function
grng_randomVariable(const Distribution_ &d)
{
boost::variate_generator
rv(grng_generator(), d);
return boost::function(rv);
}
//main
int main(int argc, char* argv[])
{
// 1
int a = grng_randomVariable(boost::uniform_int<int>(1,100))();
std::cout << a << std::endl;
// 2
boost::function
Ci(grng_randomVariable(boost::uniform_int<int>(1,100)));
std::cout << Ci() << std::endl;
return 1;
}