next up previous contents
Next: Interpolation Up: A Discrete EVent system Previous: Models with Many Input/Output   Contents

Random Numbers

Adevs has two classes that work together to generate many types of random numbers. These two classes are the random_seq class and the rv class. The random_seq class provides uniformly distributed random numbers to the rv class, and the rv transforms this uniform stream of random numbers into a variety of random number distributions.

The random_seq class is an interface for a random number generator. Its derived classes produce uniformly distributed pseudo-random numbers. The underlying random number stream is accessed with two methods. The next_long returns a raw random number as an unsigned long. The next_dlb refines the next_long method by reducing the raw random number to a double precision number in the interval $ [0,1]$ . The random number sequence is initialized with the set_seed method, and the entire random number generator can be copied with the copy method. To summarize, the random_seq class has four abstract methods

void set_seed(unsigned long seed) 
double next_dbl() 
random_seq* copy() const 
unsigned long next_long()
that must be implemented by any derived class.

Adevs comes with two implementations of the random_seq class: the crand class and the mtrand class. The crand class uses the rand function from the standard C library to implement the required methods. Its implementation is trivial; I've listed it below as an example of how to implement the random_seq interface.

class crand: public random_seq {
    public:
        /// Create a generator with the default seed
        crand(){}
        /// Create a generator with the given seed
        crand(unsigned long seed) { srand (seed); }
        /// Set the seed for the random number generator
        void set_seed(unsigned long seed) { srand (seed); }
        /// Get the next double uniformly distributed in [0, 1]
        double next_dbl() { return (double)rand()/(double)RAND_MAX; } 
        /// Copy the random number generator
        unsigned long next_long() { return (unsigned long)rand(); }

        random_seq* copy() const { return new crand (); }
        /// Destructor
        ~crand(){}
};
The mtrand class implements the Mersenne Twister random number generator11.1. The code is based on their open source implementation of the Mersenne Twister. Aside from its potential advantages as a random number generator, the mtrand class differs from the crand class by its ability to make deep copies; every instance of the mtrand class has its own random number stream.

The rv class uses the uniform random numbers provided by a random_seq object to produce several different random number distributions: triangular, uniform, normal, exponential, lognormal, Poisson, Weibull, binomial, and many others. Every instance of the rv class is created with a random_seq; the default is an mtrand object, but any type of random_seq object can be passed to the rv constructor. The different random distributions are sampled by calling the appropriate method: triangular for a triangular distribution, exponential for an exponential distribution, poisson for a Poisson distribution, etc. Adevs is open source software; if a new distribution is needed then you can add a method that implements it to the rv class (and, I hope, contribute the expansion to the Adevs project).


next up previous contents
Next: Interpolation Up: A Discrete EVent system Previous: Models with Many Input/Output   Contents
rotten 2011-09-07