IT++ Logo
random.h
Go to the documentation of this file.
1 
29 #ifndef RANDOM_H
30 #define RANDOM_H
31 
32 #include <itpp/base/random_dsfmt.h>
33 #include <itpp/base/operators.h>
34 #include <itpp/itexports.h>
35 
36 namespace itpp
37 {
38 
104 
105 ITPP_EXPORT void GlobalRNG_reset(unsigned int seed);
106 
108 ITPP_EXPORT void GlobalRNG_reset();
109 
111 ITPP_EXPORT unsigned int GlobalRNG_get_local_seed();
112 
114 ITPP_EXPORT void GlobalRNG_randomize();
115 
117 ITPP_EXPORT void GlobalRNG_get_state(ivec &state);
118 
120 ITPP_EXPORT void GlobalRNG_set_state(const ivec &state);
121 
123 
124 
140 
141 ITPP_EXPORT void RNG_reset(unsigned int seed);
142 
149 ITPP_EXPORT void RNG_reset();
150 
152 ITPP_EXPORT void RNG_randomize();
153 
155 ITPP_EXPORT void RNG_get_state(ivec &state);
156 
158 ITPP_EXPORT void RNG_set_state(const ivec &state);
159 
161 
162 
171 class ITPP_EXPORT Random_Generator
172 {
174 public:
176  Random_Generator(): _dsfmt(random_details::lc_get()) {
178  _dsfmt.init_gen_rand(GlobalRNG_get_local_seed());
180  }
181  }
182 
183  //Constructor using a certain seed - do not want to provide it. Use free-standing functions to change per-thread local seed
184  //Random_Generator(unsigned int seed) { init_gen_rand(seed); random_details::lc_mark_initialized();}
185 
186  //provide wrappers for DSFMT algorithm functions
187 
188  //Set the seed to a semi-random value (based on hashed time and clock) - do not want to provide it. Use free-standing functions to change per-thread local seed
189  //void randomize(){RNG_randomize();}
190 
191  //Reset the generator with the same seed as used last time - do not want to provide it. Use free-standing functions to change per-thread local seed
192  //void reset() {RNG_reset();}
193 
194  //Initialise the generator with a new seed (\sa init_gen_rand()) - do not want to provide it. Use free-standing functions to change per-thread local seed
195  //void reset(unsigned int seed) { RNG_reset(seed); }
196 
197  //Resume the state of the generator from a previously saved ivec - do not want to provide it. Use free-standing functions to change per-thread local seed
198  //void set_state(const ivec &state) {RNG_set_state(state);}
199 
200  //Return current state of generator in the form of ivec - do not want to provide it. Use free-standing functions to change per-thread local seed
201  //ivec get_state() const {ivec ret; RNG_get_state(ret); return ret; }
202 
204  double random_01() { return genrand_open_open(); }
206  double random_01_lclosed() { return genrand_close_open(); }
208  double random_01_rclosed() { return genrand_open_close(); }
210  uint32_t random_int() { return genrand_uint32(); }
211 
213  uint32_t genrand_uint32() { return _dsfmt.genrand_uint32(); }
214 
224  double genrand_close1_open2() { return _dsfmt.genrand_close1_open2(); }
225 
234  double genrand_close_open() { return genrand_close1_open2() - 1.0; }
235 
244  double genrand_open_close() { return 2.0 - genrand_close1_open2(); }
245 
254  double genrand_open_open() { return _dsfmt.genrand_open_open();}
255 
256 private:
257  DSFMT _dsfmt;
258 };
259 
264 class ITPP_EXPORT Bernoulli_RNG
265 {
266 public:
268  Bernoulli_RNG(double prob) { setup(prob); }
270  Bernoulli_RNG() { p = 0.5; }
272  void setup(double prob) {
273  it_assert(prob >= 0.0 && prob <= 1.0, "The Bernoulli source probability "
274  "must be between 0 and 1");
275  p = prob;
276  }
278  double get_setup() const { return p; }
280  bin operator()() { return sample(); }
282  bvec operator()(int n) { bvec temp(n); sample_vector(n, temp); return temp; }
284  bmat operator()(int h, int w) { bmat temp(h, w); sample_matrix(h, w, temp); return temp; }
286  bin sample() { return RNG.genrand_close_open() < p ? bin(1) : bin(0); }
288  void sample_vector(int size, bvec &out) {
289  out.set_size(size, false);
290  for(int i = 0; i < size; i++) out(i) = sample();
291  }
293  void sample_matrix(int rows, int cols, bmat &out) {
294  out.set_size(rows, cols, false);
295  for(int i = 0; i < rows * cols; i++) out(i) = sample();
296  }
297 protected:
298 private:
300  double p;
302  Random_Generator RNG;
303 };
304 
322 class ITPP_EXPORT I_Uniform_RNG
323 {
324 public:
326  I_Uniform_RNG(int min = 0, int max = 1);
328  void setup(int min, int max);
330  void get_setup(int &min, int &max) const;
332  int operator()() { return sample(); }
334  ivec operator()(int n);
336  imat operator()(int h, int w);
338  int sample() {
339  return floor_i(RNG.genrand_close_open() * (hi - lo + 1)) + lo;
340  }
341 private:
343  int lo;
345  int hi;
347  Random_Generator RNG;
348 };
349 
354 class ITPP_EXPORT Uniform_RNG
355 {
356 public:
358  Uniform_RNG(double min = 0, double max = 1.0);
360  void setup(double min, double max);
362  void get_setup(double &min, double &max) const;
364  double operator()() { return (sample() * (hi_bound - lo_bound) + lo_bound); }
366  vec operator()(int n) {
367  vec temp(n);
368  sample_vector(n, temp);
369  temp *= hi_bound - lo_bound;
370  temp += lo_bound;
371  return temp;
372  }
374  mat operator()(int h, int w) {
375  mat temp(h, w);
376  sample_matrix(h, w, temp);
377  temp *= hi_bound - lo_bound;
378  temp += lo_bound;
379  return temp;
380  }
382  double sample() { return RNG.genrand_close_open(); }
384  void sample_vector(int size, vec &out) {
385  out.set_size(size, false);
386  for(int i = 0; i < size; i++) out(i) = sample();
387  }
389  void sample_matrix(int rows, int cols, mat &out) {
390  out.set_size(rows, cols, false);
391  for(int i = 0; i < rows * cols; i++) out(i) = sample();
392  }
393 protected:
394 private:
396  double lo_bound, hi_bound;
398  Random_Generator RNG;
399 };
400 
405 class ITPP_EXPORT Exponential_RNG
406 {
407 public:
409  Exponential_RNG(double lambda = 1.0);
411  void setup(double lambda) { l = lambda; }
413  double get_setup() const;
415  double operator()() { return sample(); }
417  vec operator()(int n);
419  mat operator()(int h, int w);
420 private:
421  double sample() { return (-std::log(RNG.genrand_open_close()) / l); }
422  double l;
423  Random_Generator RNG;
424 };
425 
440 class ITPP_EXPORT Normal_RNG
441 {
442 public:
444  Normal_RNG(double meanval, double variance):
445  mean(meanval), sigma(std::sqrt(variance)) {}
447  Normal_RNG(): mean(0.0), sigma(1.0) {}
449  void setup(double meanval, double variance)
450  { mean = meanval; sigma = std::sqrt(variance); }
452  void get_setup(double &meanval, double &variance) const;
454  double operator()() { return (sigma * sample() + mean); }
456  vec operator()(int n) {
457  vec temp(n);
458  sample_vector(n, temp);
459  temp *= sigma;
460  temp += mean;
461  return temp;
462  }
464  mat operator()(int h, int w) {
465  mat temp(h, w);
466  sample_matrix(h, w, temp);
467  temp *= sigma;
468  temp += mean;
469  return temp;
470  }
472  double sample();
473 
475  void sample_vector(int size, vec &out) {
476  out.set_size(size, false);
477  for(int i = 0; i < size; i++) out(i) = sample();
478  }
479 
481  void sample_matrix(int rows, int cols, mat &out) {
482  out.set_size(rows, cols, false);
483  for(int i = 0; i < rows * cols; i++) out(i) = sample();
484  }
485 private:
486  double mean, sigma;
487  static const double ytab[128];
488  static const unsigned int ktab[128];
489  static const double wtab[128];
490  static const double PARAM_R;
491  Random_Generator RNG;
492 };
493 
510 class ITPP_EXPORT Gamma_RNG
511 {
512 public:
514  Gamma_RNG(double a = 1.0, double b = 1.0): alpha(a), beta(b) {init_state();}
516  void setup(double a, double b) { alpha = a; beta = b; }
518  double operator()() { return sample(); }
520  vec operator()(int n);
522  mat operator()(int r, int c);
524  double sample();
525 private:
527  void init_state();
529  double alpha;
531  double beta;
532 
533  Random_Generator RNG;
534  Normal_RNG NRNG;
535 
536  /* State variables - used in Gamma_Rng::sample()*/
537  double _s, _s2, _d, _scale;
538  double _q0, _b, _si, _c;
539 };
540 
545 class ITPP_EXPORT Laplace_RNG
546 {
547 public:
549  Laplace_RNG(double meanval = 0.0, double variance = 1.0);
551  void setup(double meanval, double variance);
553  void get_setup(double &meanval, double &variance) const;
555  double operator()() { return sample(); }
557  vec operator()(int n);
559  mat operator()(int h, int w);
561  double sample() {
562  double u = RNG.genrand_open_open();
563  double l = sqrt_12var;
564  if(u < 0.5)
565  l *= std::log(2.0 * u);
566  else
567  l *= -std::log(2.0 * (1 - u));
568  return (l + mean);
569  }
570 private:
571  double mean, var, sqrt_12var;
572  Random_Generator RNG;
573 };
574 
579 class ITPP_EXPORT Complex_Normal_RNG
580 {
581 public:
583  Complex_Normal_RNG(std::complex<double> mean, double variance):
584  norm_factor(1.0 / std::sqrt(2.0)) {
585  setup(mean, variance);
586  }
588  Complex_Normal_RNG(): m_re(0.0), m_im(0.0), sigma(1.0), norm_factor(1.0 / std::sqrt(2.0)) {}
590  void setup(std::complex<double> mean, double variance) {
591  m_re = mean.real();
592  m_im = mean.imag();
593  sigma = std::sqrt(variance);
594  }
596  void get_setup(std::complex<double> &mean, double &variance) {
597  mean = std::complex<double>(m_re, m_im);
598  variance = sigma * sigma;
599  }
601  std::complex<double> operator()() { return sigma * sample() + std::complex<double>(m_re, m_im); }
603  cvec operator()(int n) {
604  cvec temp(n);
605  sample_vector(n, temp);
606  temp *= sigma;
607  temp += std::complex<double>(m_re, m_im);
608  return temp;
609  }
611  cmat operator()(int h, int w) {
612  cmat temp(h, w);
613  sample_matrix(h, w, temp);
614  temp *= sigma;
615  temp += std::complex<double>(m_re, m_im);
616  return temp;
617  }
619  std::complex<double> sample() {
620  double a = nRNG.sample() * norm_factor;
621  double b = nRNG.sample() * norm_factor;
622  return std::complex<double>(a, b);
623  }
624 
626  void sample_vector(int size, cvec &out) {
627  out.set_size(size, false);
628  for(int i = 0; i < size; i++) out(i) = sample();
629  }
630 
632  void sample_matrix(int rows, int cols, cmat &out) {
633  out.set_size(rows, cols, false);
634  for(int i = 0; i < rows * cols; i++) out(i) = sample();
635  }
636 
638  Complex_Normal_RNG & operator=(const Complex_Normal_RNG&) { return *this; }
639 
640 private:
641  double m_re;
642  double m_im;
643  double sigma;
644  const double norm_factor;
645  Normal_RNG nRNG;
646 };
647 
652 class ITPP_EXPORT AR1_Normal_RNG
653 {
654 public:
656  AR1_Normal_RNG(double meanval = 0.0, double variance = 1.0,
657  double rho = 0.0);
659  void setup(double meanval, double variance, double rho);
661  void get_setup(double &meanval, double &variance, double &rho) const;
663  void reset();
665  double operator()() { return sample(); }
667  vec operator()(int n);
669  mat operator()(int h, int w);
670 private:
671  double sample() {
672  mem *= r;
673  if(odd) {
674  r1 = m_2pi * RNG.genrand_open_close();
675  r2 = std::sqrt(factr * std::log(RNG.genrand_open_close()));
676  mem += r2 * std::cos(r1);
677  }
678  else {
679  mem += r2 * std::sin(r1);
680  }
681  odd = !odd;
682  return (mem + mean);
683  }
684  double mem, r, factr, mean, var, r1, r2;
685  bool odd;
686  Random_Generator RNG;
687 };
688 
694 
700 
705 class ITPP_EXPORT Weibull_RNG
706 {
707 public:
709  Weibull_RNG(double lambda = 1.0, double beta = 1.0);
711  void setup(double lambda, double beta);
713  void get_setup(double &lambda, double &beta) { lambda = l; beta = b; }
715  double operator()() { return sample(); }
717  vec operator()(int n);
719  mat operator()(int h, int w);
720 private:
721  double sample() {
722  return (std::pow(-std::log(RNG.genrand_open_close()), 1.0 / b) / l);
723  }
724  double l, b;
725  double mean, var;
726  Random_Generator RNG;
727 };
728 
733 class ITPP_EXPORT Rayleigh_RNG
734 {
735 public:
737  Rayleigh_RNG(double sigma = 1.0);
739  void setup(double sigma) { sig = sigma; }
741  double get_setup() { return sig; }
743  double operator()() { return sample(); }
745  vec operator()(int n);
747  mat operator()(int h, int w);
748 private:
749  double sample() {
750  double s1 = nRNG.sample();
751  double s2 = nRNG.sample();
752  // s1 and s2 are N(0,1) and independent
753  return (sig * std::sqrt(s1 * s1 + s2 * s2));
754  }
755  double sig;
756  Normal_RNG nRNG;
757 };
758 
763 class ITPP_EXPORT Rice_RNG
764 {
765 public:
767  Rice_RNG(double sigma = 1.0, double v = 1.0);
769  void setup(double sigma, double v) { sig = sigma; s = v; }
771  void get_setup(double &sigma, double &v) { sigma = sig; v = s; }
773  double operator()() { return sample(); }
775  vec operator()(int n);
777  mat operator()(int h, int w);
778 private:
779  double sample() {
780  double s1 = nRNG.sample() + s;
781  double s2 = nRNG.sample();
782  // s1 and s2 are N(0,1) and independent
783  return (sig * std::sqrt(s1 * s1 + s2 * s2));
784  }
785  double sig, s;
786  Normal_RNG nRNG;
787 };
788 
791 
793 inline bin randb(void) { Bernoulli_RNG src; return src.sample(); }
795 inline void randb(int size, bvec &out) { Bernoulli_RNG src; src.sample_vector(size, out); }
797 inline bvec randb(int size) { bvec temp; randb(size, temp); return temp; }
799 inline void randb(int rows, int cols, bmat &out) { Bernoulli_RNG src; src.sample_matrix(rows, cols, out); }
801 inline bmat randb(int rows, int cols) { bmat temp; randb(rows, cols, temp); return temp; }
802 
804 inline double randu(void) { Uniform_RNG src; return src.sample(); }
806 inline void randu(int size, vec &out) { Uniform_RNG src; src.sample_vector(size, out); }
808 inline vec randu(int size) { vec temp; randu(size, temp); return temp; }
810 inline void randu(int rows, int cols, mat &out) { Uniform_RNG src; src.sample_matrix(rows, cols, out); }
812 inline mat randu(int rows, int cols) { mat temp; randu(rows, cols, temp); return temp; }
813 
815 inline int randi(int low, int high) { I_Uniform_RNG src; src.setup(low, high); return src(); }
817 inline ivec randi(int size, int low, int high) { I_Uniform_RNG src; src.setup(low, high); return src(size); }
819 inline imat randi(int rows, int cols, int low, int high) { I_Uniform_RNG src; src.setup(low, high); return src(rows, cols); }
820 
822 inline vec randray(int size, double sigma = 1.0) { Rayleigh_RNG src; src.setup(sigma); return src(size); }
823 
825 inline vec randrice(int size, double sigma = 1.0, double s = 1.0) { Rice_RNG src; src.setup(sigma, s); return src(size); }
826 
828 inline vec randexp(int size, double lambda = 1.0) { Exponential_RNG src; src.setup(lambda); return src(size); }
829 
831 inline double randn(void) { Normal_RNG src; return src.sample(); }
833 inline void randn(int size, vec &out) { Normal_RNG src; src.sample_vector(size, out); }
835 inline vec randn(int size) { vec temp; randn(size, temp); return temp; }
837 inline void randn(int rows, int cols, mat &out) { Normal_RNG src; src.sample_matrix(rows, cols, out); }
839 inline mat randn(int rows, int cols) { mat temp; randn(rows, cols, temp); return temp; }
840 
845 inline std::complex<double> randn_c(void) { Complex_Normal_RNG src; return src.sample(); }
847 inline void randn_c(int size, cvec &out) { Complex_Normal_RNG src; src.sample_vector(size, out); }
849 inline cvec randn_c(int size) { cvec temp; randn_c(size, temp); return temp; }
851 inline void randn_c(int rows, int cols, cmat &out) { Complex_Normal_RNG src; src.sample_matrix(rows, cols, out); }
853 inline cmat randn_c(int rows, int cols) { cmat temp; randn_c(rows, cols, temp); return temp; }
854 
856 
857 } // namespace itpp
858 
859 #endif // #ifndef RANDOM_H
SourceForge Logo

Generated on Sat Jul 6 2013 10:54:21 for IT++ by Doxygen 1.8.2