vtf-logo

UniformRandom.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00008 #if !defined(__ads_UniformRandom_h__)
00010 #define __ads_UniformRandom_h__
00011 
00012 #include "../array/FixedArray.h"
00013 
00014 #include <limits>
00015 #include <functional>
00016 
00017 #include <cassert>
00018 
00019 BEGIN_NAMESPACE_ADS
00020 
00021 //-----------------------------------------------------------------------------
00026 // @{
00027 
00029 
00062 template<typename T>
00063 class UniformRandom {
00064 };
00065 
00067 
00071 class SubtractiveRNG : 
00072   public std::unary_function<unsigned int, unsigned int> {
00073 private:
00074 
00075   unsigned int _table[55];
00076   std::size_t _index1;
00077   std::size_t _index2;
00078 
00079 public:
00080 
00082   unsigned int 
00083   operator()(unsigned int limit) {
00084     _index1 = (_index1 + 1) % 55;
00085     _index2 = (_index2 + 1) % 55;
00086     _table[_index1] = _table[_index1] - _table[_index2];
00087     return _table[_index1] % limit;
00088   }
00089 
00091   void 
00092   initialize(unsigned int seed) {
00093     unsigned int k = 1;
00094     _table[54] = seed;
00095     size_t i;
00096     for (i = 0; i < 54; i++) {
00097       size_t ii = (21 * (i + 1) % 55) - 1;
00098       _table[ii] = k;
00099       k = seed - k;
00100       seed = _table[ii];
00101     }
00102     for (int __loop = 0; __loop < 4; __loop++) {
00103       for (i = 0; i < 55; i++) {
00104         _table[i] = _table[i] - _table[(1 + i + 30) % 55];
00105       }
00106     }
00107     _index1 = 0;
00108     _index2 = 31;
00109   }
00110 
00112   SubtractiveRNG(const unsigned int seed) :
00113     _index1(),
00114     _index2() { 
00115     initialize(seed);
00116   }
00117 
00119   SubtractiveRNG() :
00120     _index1(),
00121     _index2() { 
00122     initialize(161803398u); 
00123   }
00124 };
00125 
00126 
00127 
00129 class UniformRandomBase {
00130 private:
00131   
00132   //
00133   // Member data.
00134   //
00135 
00136   mutable SubtractiveRNG _rng;
00137 
00138 protected:
00139 
00140   //
00141   // Constructors, etc.
00142   //
00143 
00145   UniformRandomBase() :
00146     _rng()
00147   {}
00148 
00150   UniformRandomBase(const unsigned int n) :
00151     _rng(n)
00152   {}
00153 
00155   UniformRandomBase(const UniformRandomBase& x) :
00156     _rng(x._rng)
00157   {}
00158 
00160   UniformRandomBase&
00161   operator=( const UniformRandomBase& other) {
00162     if (&other != this) {
00163       _rng = other._rng;
00164     }
00165     return *this;
00166   }
00167 
00169   ~UniformRandomBase()
00170   {}
00171 
00172   //
00173   // Random number generation.
00174   //
00175 
00177   unsigned int
00178   random(const unsigned int n) const {
00179     return _rng(n);
00180   }
00181 
00182 public:
00183 
00185   void
00186   initialize(const unsigned int n) {
00187     SubtractiveRNG tmp(n);
00188     _rng = tmp;
00189   }
00190 
00191 };
00192 
00193 
00194 
00196 template<typename T>
00197 class UniformRandomInteger :
00198   public UniformRandomBase {
00199 private:
00200 
00201   //
00202   // Private types.
00203   //
00204 
00205   typedef UniformRandomBase Base;
00206 
00207 public:
00208 
00209   //
00210   // Public types.
00211   //
00212 
00214   typedef T Number;
00216   typedef void argument_type;
00218   typedef Number result_type;
00219 
00220 private:
00221 
00222   //
00223   // Member data.
00224   //
00225 
00226   Number _min;
00227   Number _extent;
00228 
00229 public:
00230 
00231   //--------------------------------------------------------------------------
00232   // \name Constructors, etc.
00234 
00236   UniformRandomInteger() :
00237     Base(),
00238     _min(0),
00239     _extent(0)
00240   {}
00241 
00243   UniformRandomInteger(const Number min, const Number max) :
00244     Base(),
00245     _min(min),
00246     _extent(max - min + 1) {
00247     assert(_extent > 0);
00248   }
00249 
00251   UniformRandomInteger(const Number min, const Number max,
00252                        const unsigned int n) :
00253     Base(n),
00254     _min(min),
00255     _extent(max - min + 1) {
00256     assert(_extent > 0);
00257   }
00258 
00260   UniformRandomInteger(const UniformRandomInteger& x) :
00261     Base(x),
00262     _min(x._min),
00263     _extent(x._extent)
00264   {}
00265 
00267   UniformRandomInteger&
00268   operator=(const UniformRandomInteger& other) {
00269     if (&other != this) {
00270       Base::operator=(other);
00271       _min = other._min;
00272       _extent = other._extent;
00273     }
00274     return *this;
00275   }
00276   
00278   ~UniformRandomInteger()
00279   {}
00280 
00282   //--------------------------------------------------------------------------
00283   // \name Random number generation.
00285 
00287   Number
00288   min() const {
00289     return _min;
00290   }
00291   
00293   Number
00294   max() const {
00295     return _min + _extent - 1;
00296   }
00297   
00299   result_type
00300   operator()() const {
00301     return _min + random(_extent);
00302   }
00303 
00305 };
00306 
00307 
00308 
00310 template<typename T>
00311 class UniformRandomReal :
00312   public UniformRandomBase {
00313 private:
00314 
00315   //
00316   // Private types.
00317   //
00318 
00319   typedef UniformRandomBase Base;
00320 
00321 public:
00322 
00323   //
00324   // Public types.
00325   //
00326 
00328   typedef T Number;
00330   typedef void argument_type;
00332   typedef Number result_type;
00333 
00334 private:
00335 
00336   //
00337   // Member data.
00338   //
00339 
00340   Number _min;
00341   Number _extent;
00342 
00343 public:
00344 
00345   //--------------------------------------------------------------------------
00346   // \name Constructors, etc.
00348 
00350   UniformRandomReal() :
00351     Base(),
00352     _min(0),
00353     _extent(0)
00354   {}
00355 
00357   UniformRandomReal(const Number min, const Number max) :
00358     Base(),
00359     _min(min),
00360     _extent(max - min) {
00361     assert(_extent >= 0);
00362   }
00363 
00365   UniformRandomReal(const Number min, const Number max,
00366                      const unsigned int n) :
00367     Base(n),
00368     _min(min),
00369     _extent(max - min) {
00370     assert(_extent >= 0);
00371   }
00372 
00374   UniformRandomReal(const UniformRandomReal& x) :
00375     Base(x),
00376     _min(x._min),
00377     _extent(x._extent)
00378   {}
00379 
00381   UniformRandomReal&
00382   operator=(const UniformRandomReal& other) {
00383     if (&other != this) {
00384       Base::operator=(other);
00385       _min = other._min;
00386       _extent = other._extent;
00387     }
00388     return *this;
00389   }
00390   
00392   ~UniformRandomReal()
00393   {}
00394 
00396   //--------------------------------------------------------------------------
00397   // \name Random number generation.
00399 
00401   Number
00402   min() const {
00403     return _min;
00404   }
00405   
00407   Number
00408   max() const {
00409     return _min + _extent;
00410   }
00411   
00413   result_type
00414   operator()() const {
00415     return _min + _extent * 
00416       random(std::numeric_limits<unsigned int>::max()) /
00417       Number(std::numeric_limits<unsigned int>::max() - 1);
00418   }
00419 
00421 };
00422 
00423 
00424 
00426 #define UNIFORM_RANDOM(_T,_Base)\
00427 template<>\
00428 class UniformRandom<_T> :\
00429   public _Base<_T>\
00430 {\
00431 private:\
00432   typedef _Base<_T> Base;\
00433 public:\
00434 \
00435   typedef Base::Number Number;\
00436 \
00437   typedef Base::argument_type argument_type;\
00438 \
00439   typedef Base::result_type result_type;\
00440 public:\
00441 \
00442   UniformRandom() :\
00443     Base()\
00444   {}\
00445 \
00446 \
00447   UniformRandom(const Number min, const Number max) :\
00448     Base(min, max)\
00449   {}\
00450 \
00451 \
00452   UniformRandom(const Number min, const Number max,\
00453                  const unsigned int n) :\
00454     Base(min, max, n)\
00455   {}\
00456 \
00457 \
00458   UniformRandom(const UniformRandom& x) :\
00459     Base(x)\
00460   {}\
00461 \
00462 \
00463   UniformRandom&\
00464   operator=(const UniformRandom& x)\
00465   {\
00466     if (&x != this) {\
00467       Base::operator=(x);\
00468     }\
00469     return *this;\
00470   }\
00471 \
00472 \
00473   ~UniformRandom()\
00474   {}\
00475 }
00476 
00477 
00478 //
00479 // The integer types.
00480 //
00482 UNIFORM_RANDOM(char,UniformRandomInteger);
00484 UNIFORM_RANDOM(signed char,UniformRandomInteger);
00486 UNIFORM_RANDOM(unsigned char,UniformRandomInteger);
00487 
00488 // Conflicts with unsigned short.
00489 // Uniform random number generator for wchar_t.
00490 //UNIFORM_RANDOM(wchar_t,UniformRandomInteger);
00491 
00493 UNIFORM_RANDOM(short,UniformRandomInteger);
00495 UNIFORM_RANDOM(unsigned short,UniformRandomInteger);
00497 UNIFORM_RANDOM(int,UniformRandomInteger);
00499 UNIFORM_RANDOM(unsigned int,UniformRandomInteger);
00500 
00501 //
00502 // The real number types.
00503 //
00505 UNIFORM_RANDOM(float,UniformRandomReal);
00507 UNIFORM_RANDOM(double,UniformRandomReal);
00509 UNIFORM_RANDOM(long double,UniformRandomReal);
00510 
00511 
00512 
00513 
00514 
00516 template<int N, typename T = double>
00517 class UniformRandomPoint {
00518 public:
00519 
00520   //
00521   // Public types.
00522   //
00523 
00525   typedef T Number;
00527   typedef void argument_type;
00529   typedef ads::FixedArray<N,Number> result_type;
00530 
00531 private:
00532 
00533   //
00534   // Member data.
00535   //
00536 
00537   // Lower and upper bounds.
00538   result_type _min, _max;
00539   // A random number generator.
00540   UniformRandom<Number> _rng;
00541 
00542 public:
00543 
00544   //--------------------------------------------------------------------------
00545   // \name Constructors, etc.
00547 
00549   UniformRandomPoint() :
00550     _min(),
00551     _max(),
00552     _rng(Number(0), Number(1))
00553   {}
00554 
00556   UniformRandomPoint(const result_type& min, const result_type& max) :
00557     _min(min),
00558     _max(max),
00559     _rng(Number(0), Number(1))
00560   {}
00561 
00563   UniformRandomPoint(const result_type& min, const result_type& max,
00564                      const unsigned int n) :
00565     _min(min),
00566     _max(max),
00567     _rng(Number(0), Number(1), n)
00568   {}
00569 
00571   UniformRandomPoint(const UniformRandomPoint& x) :
00572     _min(x._min),
00573     _max(x._max),
00574     _rng(x._rng)
00575   {}
00576 
00578   UniformRandomPoint&
00579   operator=(const UniformRandomPoint& other) {
00580     if (&other != this) {
00581       _min = other._min;
00582       _max = other._max;
00583       _rng = other._rng;
00584     }
00585     return *this;
00586   }
00587   
00589   ~UniformRandomPoint()
00590   {}
00591 
00593   //--------------------------------------------------------------------------
00594   // \name Random number generation.
00596 
00598   const result_type&
00599   min() const {
00600     return _min;
00601   }
00602   
00604   const result_type&
00605   max() const {
00606     return _max;
00607   }
00608   
00610   const result_type&
00611   operator()() const {
00612     static result_type x;
00613     for (int n = 0; n != N; ++n) {
00614       x[n] = _min[n] + _rng() * (_max[n] - _min[n]);
00615     }
00616     return x;
00617   }
00618 
00620 };
00621 
00622 
00623 // @}
00624 
00625 END_NAMESPACE_ADS
00626 
00627 #endif

Generated on Fri Aug 24 12:55:36 2007 for Algorithms and Data Structures Package by  doxygen 1.4.7