00001
00002
00008 #if !defined(__ads_UniformRandom_h__)
00009
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
00134
00135
00136 mutable SubtractiveRNG _rng;
00137
00138 protected:
00139
00140
00141
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
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
00203
00204
00205 typedef UniformRandomBase Base;
00206
00207 public:
00208
00209
00210
00211
00212
00214 typedef T Number;
00216 typedef void argument_type;
00218 typedef Number result_type;
00219
00220 private:
00221
00222
00223
00224
00225
00226 Number _min;
00227 Number _extent;
00228
00229 public:
00230
00231
00232
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
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
00317
00318
00319 typedef UniformRandomBase Base;
00320
00321 public:
00322
00323
00324
00325
00326
00328 typedef T Number;
00330 typedef void argument_type;
00332 typedef Number result_type;
00333
00334 private:
00335
00336
00337
00338
00339
00340 Number _min;
00341 Number _extent;
00342
00343 public:
00344
00345
00346
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
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
00480
00482 UNIFORM_RANDOM(char,UniformRandomInteger);
00484 UNIFORM_RANDOM(signed char,UniformRandomInteger);
00486 UNIFORM_RANDOM(unsigned char,UniformRandomInteger);
00487
00488
00489
00490
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
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
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
00535
00536
00537
00538 result_type _min, _max;
00539
00540 UniformRandom<Number> _rng;
00541
00542 public:
00543
00544
00545
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
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