00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef MY_RANDOM_HEADER
00030 #define MY_RANDOM_HEADER
00031
00032
00033 #include <iostream>
00034 #include <vector>
00035 #include <stdexcept>
00036
00037
00038
00039 #include <gsl/gsl_rng.h>
00040
00041 #include <simthetic/misc.h>
00042
00043
00044 namespace simth
00045 {
00046
00061 extern "C"
00062 {
00063 double gsl_ran_gaussian(const gsl_rng*,double);
00064 double gsl_ran_rayleigh(const gsl_rng*,double);
00065 }
00066
00076 class GslRandomWrapper
00077 {
00078
00079 public:
00080
00087 GslRandomWrapper(const gsl_rng_type& generatorAlgorithm = *gsl_rng_taus);
00088
00091 virtual ~GslRandomWrapper();
00092
00096 const gsl_rng* rng() const {return rng_;}
00097
00098 private:
00099
00100 gsl_rng* rng_;
00101
00102 };
00103
00104
00105
00106 class RandomGenerator
00107 {
00108 public:
00109 RandomGenerator() {};
00110 virtual ~RandomGenerator() {};
00114 virtual double get() const = 0;
00115
00116
00117
00118 };
00119
00120
00128 class RandomGeneratorGsl : public RandomGenerator
00129 {
00130 public:
00137 RandomGeneratorGsl(const gsl_rng_type& generatorAlgorithm = *gsl_rng_taus);
00138
00141 virtual ~RandomGeneratorGsl();
00142
00143 protected:
00144
00148 const gsl_rng* rng() const {return rng_;}
00149
00150 private:
00151
00152 gsl_rng* rng_;
00153
00154 };
00155
00156
00157
00158
00159
00179 class GaussRng : public RandomGeneratorGsl
00180 {
00181 protected:
00182
00183
00184 double variance_;
00185
00186 double stdDev_;
00187
00188 public:
00190 GaussRng(double variance);
00191 virtual ~GaussRng();
00192
00196 double variance() const;
00197
00201 void setVariance(double x);
00202
00206 virtual double get() const;
00207
00210 double get_inl() const;
00211 };
00212
00213
00214 inline double GaussRng::variance() const
00215 {
00216 return variance_;
00217 }
00218
00219 inline void GaussRng::setVariance(double x)
00220 {
00221 if(x<0.0) {
00222 throw std::out_of_range("GaussRng::setVariance(double x) : variance must be non negative");
00223 }
00224 variance_ = x;
00225 stdDev_ = sqrt(x);
00226 }
00227
00228 inline double GaussRng::get_inl() const
00229 {
00230 return gsl_ran_gaussian(rng(),stdDev_);
00231
00232
00233 }
00234
00235
00236
00237
00238
00280 class RayleighRng : public RandomGeneratorGsl
00281 {
00282 private:
00283
00284
00285 double sigma_;
00286
00287 public:
00295 RayleighRng(double sigma);
00296 virtual ~RayleighRng();
00297
00301 double sigma() const;
00302
00306 void setSigma(double x);
00307
00311 virtual double get() const;
00312
00315 double get_inl() const;
00316
00317 };
00318
00319
00320 inline double RayleighRng::sigma() const
00321 {
00322 return sigma_;
00323 }
00324
00325 inline void RayleighRng::setSigma(double x)
00326 {
00327 sigma_ = x;
00328 }
00329
00330 inline double RayleighRng::get_inl() const
00331 {
00332 return gsl_ran_rayleigh(rng(),sigma_);
00333
00334 }
00335
00336
00337
00338
00339
00370 class JakesRng : public RandomGeneratorGsl
00371 {
00372
00373 public:
00379 JakesRng(double df_max);
00380
00384 virtual double get() const;
00385
00388 double get_inl() const;
00389
00392 double maxDoppler() const {return dopp_freq_max;}
00393
00394 private:
00396 double dopp_freq_max;
00397
00398
00399 };
00400
00401
00402 inline double JakesRng::get_inl() const
00403 {
00404 double uni = gsl_rng_uniform(rng());
00405 return dopp_freq_max * cos(PI2*uni);
00406 }
00407
00408
00409
00410
00411
00412
00426 class UniformRng : public RandomGeneratorGsl
00427 {
00428
00429 public:
00430 UniformRng();
00431 virtual ~UniformRng();
00432
00436 virtual double get() const;
00437
00440 double get_inl() const;
00441
00442 };
00443
00444
00445 inline double UniformRng::get_inl() const
00446 {
00447 return gsl_rng_uniform(rng());
00448 }
00449
00450
00451
00452
00453
00454
00455
00542 class ExponentialMaxLimitRng : public RandomGeneratorGsl
00543 {
00544
00545 public:
00546
00557 ExponentialMaxLimitRng(double lambda, double Tmax);
00558
00560 virtual ~ExponentialMaxLimitRng();
00561
00565 virtual double get() const;
00566
00569 double attenuationFactor() const {return lambda;}
00570
00571
00572
00573 double maxLimit() const {return Tmax;}
00574
00575
00576 private:
00580 double lambda;
00581
00582
00583
00584 double Tmax;
00585
00588 double oneOverLambda;
00589
00592 double oneMinusExpMaxX;
00593
00594 };
00595
00596
00597
00598
00599
00600
00601
00610 class DiscreteUniformRng : public RandomGeneratorGsl
00611 {
00612 private:
00613 typedef std::vector<double> container_type;
00614 container_type values;
00615
00616 public:
00617
00620 DiscreteUniformRng(size_t K);
00621 virtual ~DiscreteUniformRng();
00622
00626 virtual double get() const;
00627
00630 double get_inl() const;
00631
00637 void refresh(size_t K = 0);
00638
00639 };
00640
00641
00642 inline double DiscreteUniformRng::get_inl() const
00643 {
00644 return values[unsigned(double(values.size())*gsl_rng_uniform(rng()))];
00645 }
00646
00647 }
00648
00649
00650 #endif