00001 #ifndef _theplu_yat_random_ 00002 #define _theplu_yat_random_ 00003 00004 // $Id: random.h 1797 2009-02-12 18:07:10Z peter $ 00005 00006 /* 00007 Copyright (C) 2005, 2006, 2007, 2008 Jari Häkkinen, Peter Johansson 00008 00009 This file is part of the yat library, http://dev.thep.lu.se/yat 00010 00011 The yat library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU General Public License as 00013 published by the Free Software Foundation; either version 3 of the 00014 License, or (at your option) any later version. 00015 00016 The yat library is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with yat. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 #include "yat/statistics/Histogram.h" 00026 00027 #include <gsl/gsl_rng.h> 00028 #include <gsl/gsl_randist.h> 00029 00030 #include <algorithm> 00031 #include <string> 00032 #include <vector> 00033 00034 namespace theplu { 00035 namespace yat { 00036 namespace random { 00037 00038 //forward declarion 00039 class RNG_state; 00040 00076 class RNG 00077 { 00078 public: 00079 00093 static RNG* instance(void); 00094 00099 unsigned long max(void) const; 00100 00105 unsigned long min(void) const; 00106 00110 std::string name(void) const; 00111 00115 const gsl_rng* rng(void) const; 00116 00126 void seed(unsigned long s) const; 00127 00133 unsigned long seed_from_devurandom(void); 00134 00142 int set_state(const RNG_state&); 00143 00144 private: 00145 RNG(void); 00146 00154 RNG(const RNG&); 00155 00160 RNG& operator=(const RNG&); 00161 00162 virtual ~RNG(void); 00163 00164 static RNG* instance_; 00165 gsl_rng* rng_; 00166 }; 00167 00168 00172 class RNG_state 00173 { 00174 public: 00178 RNG_state(const RNG*); 00179 00185 RNG_state(const RNG_state&); 00186 00190 ~RNG_state(void); 00191 00195 const gsl_rng* rng(void) const; 00196 00202 RNG_state& operator=(const RNG_state&); 00203 00204 private: 00205 gsl_rng* rng_; 00206 00207 void clone(const gsl_rng&); 00208 }; 00209 00210 00211 // --------------------- Discrete distribtuions --------------------- 00212 00221 class Discrete 00222 { 00223 public: 00227 Discrete(void); 00228 00232 virtual ~Discrete(void); 00233 00243 void seed(unsigned long s) const; 00244 00252 unsigned long seed_from_devurandom(void); 00253 00257 virtual unsigned long operator()(void) const = 0; 00258 00259 protected: 00261 RNG* rng_; 00262 }; 00263 00267 class DiscreteGeneral : public Discrete 00268 { 00269 public: 00275 DiscreteGeneral(const statistics::Histogram& hist); 00276 00282 DiscreteGeneral(const DiscreteGeneral&); 00283 00287 ~DiscreteGeneral(void); 00288 00297 unsigned long operator()(void) const; 00298 00304 DiscreteGeneral& operator=(const DiscreteGeneral&); 00305 00306 private: 00307 void free(void); 00308 void preproc(void); 00309 00310 gsl_ran_discrete_t* gen_; 00311 std::vector<double> p_; 00312 }; 00313 00326 class DiscreteUniform : public Discrete 00327 { 00328 public: 00342 DiscreteUniform(unsigned long n=0); 00343 00353 unsigned long operator()(void) const; 00354 00365 unsigned long operator()(unsigned long n) const; 00366 00367 private: 00368 unsigned long range_; 00369 }; 00370 00386 class Poisson : public Discrete 00387 { 00388 public: 00394 Poisson(const double m=1); 00395 00399 unsigned long operator()(void) const; 00400 00407 unsigned long operator()(const double m) const; 00408 00409 private: 00410 double m_; 00411 }; 00412 00413 // --------------------- Continuous distribtuions --------------------- 00414 00420 class Continuous 00421 { 00422 public: 00423 00427 Continuous(void); 00428 00432 virtual ~Continuous(void); 00433 00443 void seed(unsigned long s) const; 00444 00452 unsigned long seed_from_devurandom(void) 00453 { return rng_->seed_from_devurandom(); } 00454 00458 virtual double operator()(void) const = 0; 00459 00460 protected: 00462 RNG* rng_; 00463 }; 00464 00465 // ContinuousUniform is declared before ContinuousGeneral to avoid 00466 // forward declaration 00477 class ContinuousUniform : public Continuous 00478 { 00479 public: 00480 double operator()(void) const; 00481 }; 00482 00486 class ContinuousGeneral : public Continuous 00487 { 00488 public: 00494 ContinuousGeneral(const statistics::Histogram& hist); 00495 00504 double operator()(void) const; 00505 00506 private: 00507 const DiscreteGeneral discrete_; 00508 const statistics::Histogram hist_; 00509 ContinuousUniform u_; 00510 }; 00511 00520 class Exponential : public Continuous 00521 { 00522 public: 00528 Exponential(const double m=1); 00529 00533 double operator()(void) const; 00534 00541 double operator()(const double m) const; 00542 00543 private: 00544 double m_; 00545 }; 00546 00560 class Gaussian : public Continuous 00561 { 00562 public: 00569 Gaussian(const double s=1, const double m=0); 00570 00574 double operator()(void) const; 00575 00582 double operator()(const double s) const; 00583 00590 double operator()(const double s, const double m) const; 00591 00592 private: 00593 double m_; 00594 double s_; 00595 }; 00596 00604 template<typename T> 00605 void random_shuffle(T first, T last) 00606 { 00607 DiscreteUniform rnd; 00608 std::random_shuffle(first, last, rnd); 00609 } 00610 00611 }}} // of namespace random, yat, and theplu 00612 00613 #endif