/* * RandomNumberGenerator_Encapsulation.hpp * * Created on: Dec 31, 2010 * Author: heber */ #ifndef RANDOMNUMBERGENERATOR_ENCAPSULATION_HPP_ #define RANDOMNUMBERGENERATOR_ENCAPSULATION_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CodePatterns/Clone.hpp" #include "RandomNumberDistribution_Encapsulation.hpp" #include "RandomNumberDistributionFactory.hpp" #include "RandomNumberEngine_Encapsulation.hpp" #include "RandomNumberEngineFactory.hpp" #include "RandomNumberGenerator.hpp" class RandomNumberGeneratorFactory; /** Template class that encapsulates the random number generators from * random::boost. * * We inherit the interface RandomNumberGenerator such that all are * accessible in the same way (i.e. RandomNumberGeneratorFactory will * spit out only references to RandomNumberGenerator). * * Note that we always returns double values although the distribution * might be integer or even a discrete distribution of integers. * * We need two template parameters: * -# the engine - generates uniform random numbers * -# the distribution - transforms uniform into a desired distribution */ template class RandomNumberGenerator_Encapsulation : public RandomNumberGenerator, public Clone { /** * Factory is friend such that it can access private cstor when filling its * table */ friend class RandomNumberGeneratorFactory; public: /** obtain a random number via generator and the specific distribution. * */ double operator()() const { const double value = (*randomgenerator)(); //std::cout << "Current random value from (" << EngineName() << "," << DistributionName() << ") is " << value << std::endl; return value; } /** Set the generator's seed. * * @param _seed seed to set to */ void seed(unsigned int _seed) { engine_type->seed(_seed); } /** Getter for smallest possible random number * * @return smallest possible random number */ double min() const { return distribution_type->min(); } /** Getter for largest possible random number * * @return largest possible random number */ double max() const { return distribution_type->max(); } /** Getter for the type name of the internal engine. * */ std::string EngineName() const { return engine_type->name(); } /** Getter for the type name of the internal distribution. * */ std::string DistributionName() const { return distribution_type->name(); } /** Clones the current instance and returns pointer. * * @return pointer to cloned instance */ RandomNumberGenerator* clone() const { RandomNumberGenerator_Encapsulation *MyClone = NULL; // sadly (due to construction of variate_generator without any abstract // base class) we need RTTI here ... RandomNumberEngine *engine_clone = RandomNumberEngineFactory::getInstance().getProduct(typeid(engine)); RandomNumberDistribution *distribution_clone = RandomNumberDistributionFactory::getInstance().getProduct(typeid(distribution)); MyClone = new RandomNumberGenerator_Encapsulation( engine_clone, distribution_clone ); return MyClone; } protected: /** Constructor that instantiates a specific random number generator and * distribution. * * This is one is supposed to create the prototypes. Hence, must only be * called from the factory. */ RandomNumberGenerator_Encapsulation() : randomgenerator(NULL) { engine_type = RandomNumberEngineFactory::getInstance().getProduct(typeid(engine)); distribution_type = RandomNumberDistributionFactory::getInstance().getProduct(typeid(distribution)); randomgenerator = new boost::variate_generator( (dynamic_cast *>(engine_type)) ->getEngine(), (dynamic_cast *>(distribution_type)) ->getDistribution()); } /** Constructor that instantiates a specific random number generator and * distribution. * @param _engine_type instance of the desired generator * @param _distribution_type instance of the desired distribution */ RandomNumberGenerator_Encapsulation( RandomNumberEngine *_engine_type, RandomNumberDistribution *_distribution_type ) : randomgenerator(NULL) { engine_type = _engine_type; distribution_type = _distribution_type; randomgenerator = new boost::variate_generator ( (dynamic_cast *>(engine_type)) ->getEngine(), (dynamic_cast *>(distribution_type)) ->getDistribution()); } /** Destructor of the class. * */ virtual ~RandomNumberGenerator_Encapsulation() { // NULL pointer may be deleted delete randomgenerator; } private: mutable boost::variate_generator *randomgenerator; }; #endif /* RANDOMNUMBERGENERATOR_ENCAPSULATION_HPP_ */