Random.h

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @class  Random
00003    @author travis fischer (fisch0920@gmail.com)
00004    @author matthew jacobs (jacobs.mh@gmail.com)
00005    @date   fall 2008
00006    
00007    @brief
00008       Provides static functionality for generating base random numbers, 
00009    wrapping around boost::random, shared by all Samplers
00010    <!-------------------------------------------------------------------->**/
00011 
00012 #ifndef RANDOM_H_
00013 #define RANDOM_H_
00014 
00015 #include <boost/random.hpp>
00016 #include <ctime>
00017 
00018 #include <stats/Event.h>
00019 #include <stats/Sampler.h>
00020 
00021 struct Random {
00022    
00023    ///@name Typedefs for boost's generator/distribution interface
00024    //@{-----------------------------------------------------------------
00025    
00026    typedef boost::mt19937 Generator;
00027    
00028    typedef boost::normal_distribution<real_t> NormalDist;
00029    typedef boost::variate_generator<Generator&, NormalDist > 
00030       BoostNormalSampler;
00031    
00032    typedef boost::uniform_real<real_t> ContUniformDist;
00033    typedef boost::variate_generator<Generator&, ContUniformDist > 
00034       BoostContUniformSampler;
00035    
00036    typedef boost::uniform_int<int> DiscreteUniformDist;
00037    typedef boost::variate_generator<Generator&, DiscreteUniformDist > 
00038       BoostDiscreteUniformSampler;
00039    
00040    typedef boost::exponential_distribution<real_t> ExponentialDist;
00041    typedef boost::variate_generator<Generator&, ExponentialDist > 
00042       BoostExponentialSampler;
00043    
00044    typedef boost::uniform_on_sphere<real_t> UniformOnSphereDist;
00045    typedef boost::variate_generator<Generator&, UniformOnSphereDist > 
00046       BoostUniformOnSphereSampler;
00047    
00048    //@}-----------------------------------------------------------------
00049    ///@name Static utility methods
00050    //@{-----------------------------------------------------------------
00051    
00052    /**
00053     * @brief
00054     *    Initializes the Random library routines; must be called before 
00055     * using any functionality of the Milton random number generators 
00056     */
00057    static void init() {
00058       s_generator.seed(static_cast<unsigned int>(std::time(0)));
00059       
00060       ASSERT(s_contUniformSampler);
00061       s_contUniformSampler->init();
00062    }
00063    
00064    /**
00065     * @returns a random floating point number inbetween the specified 
00066     *    bounds [@p min, @p max)
00067     */
00068    static real_t sample(real_t min = 0, real_t max = 1) {
00069       const real_t x = s_contUniformSampler->sample();
00070       ASSERT(x >= 0.0 && x < 1.0);
00071       
00072       return (x * (max - min)) + min;
00073    }
00074    
00075    /**
00076     * @returns a random floating point number inbetween the specified 
00077     *    bounds [@p min, @p max)
00078     */
00079    static inline real_t uniform(real_t min = 0, real_t max = 1) {
00080       return sample(min, max);
00081    }
00082    
00083    /**
00084     * @returns a random integer inbetween the specified bounds [@p min, @p max)
00085     */
00086    static int sampleInt(int min, int max) {
00087       return floor(Random::sample(min, max));
00088    }
00089    
00090    /**
00091     * @returns a random index from the cdf given according to the cumulative 
00092     *    distribution function
00093     */
00094    static unsigned sampleCDF(const real_t *cdf, unsigned n) {
00095       ASSERT(cdf);
00096       ASSERT(n > 0);
00097       
00098       const real_t x = Random::sample(0.0, 1.0);
00099       real_t total   = 0;
00100       real_t sum     = 0;
00101       
00102       for(unsigned i = 0; i < n; ++i) {
00103          ASSERT(cdf[i] >= 0);
00104          total += cdf[i];
00105       }
00106       
00107       ASSERT(total > 0);
00108       for(unsigned i = 0; i < n - 1; ++i) {
00109          sum += cdf[i] / total;
00110          
00111          if (x <= sum)
00112             return i;
00113       }
00114       
00115       return (n - 1);
00116    }
00117    
00118    /**
00119     * @returns a random index from the cdf given according to the cumulative 
00120     *    distribution function
00121     * 
00122     * @note assumes the given cdf is already normalized
00123     */
00124    static unsigned sampleNormalizedCDF(const real_t *cdf, unsigned n) {
00125       ASSERT(cdf);
00126       ASSERT(n > 0);
00127       
00128       const real_t x = Random::sample(0.0, 1.0);
00129       real_t sum     = 0;
00130       
00131       for(unsigned i = 0; i < n - 1; ++i) {
00132          sum += cdf[i];
00133          
00134          if (x <= sum)
00135             return i;
00136       }
00137       
00138       return (n - 1);
00139    }
00140 
00141    //@}-----------------------------------------------------------------
00142    ///@name Static boost helper classes
00143    //@{-----------------------------------------------------------------
00144    
00145    static Generator s_generator;
00146    
00147    //@}-----------------------------------------------------------------
00148    
00149    private:
00150       static Sampler *s_contUniformSampler;
00151 };
00152 
00153 #endif // RANDOM_H_
00154 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6