00001 #ifndef _theplu_yat_random_ 00002 #define _theplu_yat_random_ 00003 00004 // $Id: random.h 2154 2010-01-17 22:21:29Z peter $ 00005 00006 /* 00007 Copyright (C) 2005, 2006, 2007, 2008 Jari Häkkinen, Peter Johansson 00008 Copyright (C) 2009, 2010 Peter Johansson 00009 00010 This file is part of the yat library, http://dev.thep.lu.se/yat 00011 00012 The yat library is free software; you can redistribute it and/or 00013 modify it under the terms of the GNU General Public License as 00014 published by the Free Software Foundation; either version 3 of the 00015 License, or (at your option) any later version. 00016 00017 The yat library is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 General Public License for more details. 00021 00022 You should have received a copy of the GNU General Public License 00023 along with yat. If not, see <http://www.gnu.org/licenses/>. 00024 */ 00025 00026 #include "yat/statistics/Histogram.h" 00027 00028 #include <boost/concept_check.hpp> 00029 00030 #include <gsl/gsl_rng.h> 00031 #include <gsl/gsl_randist.h> 00032 00033 #include <algorithm> 00034 #include <string> 00035 #include <vector> 00036 00037 namespace theplu { 00038 namespace yat { 00039 namespace random { 00040 00041 //forward declarion 00042 class RNG_state; 00043 00079 class RNG 00080 { 00081 public: 00082 00096 static RNG* instance(void); 00097 00102 unsigned long max(void) const; 00103 00108 unsigned long min(void) const; 00109 00113 std::string name(void) const; 00114 00118 const gsl_rng* rng(void) const; 00119 00129 void seed(unsigned long s) const; 00130 00136 unsigned long seed_from_devurandom(void); 00137 00145 int set_state(const RNG_state&); 00146 00147 private: 00148 RNG(void); 00149 00157 RNG(const RNG&); 00158 00163 RNG& operator=(const RNG&); 00164 00165 virtual ~RNG(void); 00166 00167 static RNG* instance_; 00168 gsl_rng* rng_; 00169 }; 00170 00171 00175 class RNG_state 00176 { 00177 public: 00181 explicit RNG_state(const RNG*); 00182 00188 RNG_state(const RNG_state&); 00189 00193 ~RNG_state(void); 00194 00198 const gsl_rng* rng(void) const; 00199 00205 RNG_state& operator=(const RNG_state&); 00206 00207 private: 00208 gsl_rng* rng_; 00209 00210 void clone(const gsl_rng&); 00211 }; 00212 00213 00214 // --------------------- Discrete distribtuions --------------------- 00215 00224 class Discrete 00225 { 00226 public: 00230 Discrete(void); 00231 00235 virtual ~Discrete(void); 00236 00246 void seed(unsigned long s) const; 00247 00255 unsigned long seed_from_devurandom(void); 00256 00260 virtual unsigned long operator()(void) const = 0; 00261 00262 protected: 00264 RNG* rng_; 00265 }; 00266 00270 class DiscreteGeneral : public Discrete 00271 { 00272 public: 00278 explicit DiscreteGeneral(const statistics::Histogram& hist); 00279 00285 DiscreteGeneral(const DiscreteGeneral&); 00286 00290 ~DiscreteGeneral(void); 00291 00300 unsigned long operator()(void) const; 00301 00307 DiscreteGeneral& operator=(const DiscreteGeneral&); 00308 00309 private: 00310 void free(void); 00311 void preproc(void); 00312 00313 gsl_ran_discrete_t* gen_; 00314 std::vector<double> p_; 00315 }; 00316 00329 class DiscreteUniform : public Discrete 00330 { 00331 public: 00345 explicit DiscreteUniform(unsigned long n=0); 00346 00356 unsigned long operator()(void) const; 00357 00368 unsigned long operator()(unsigned long n) const; 00369 00370 private: 00371 unsigned long range_; 00372 }; 00373 00389 class Poisson : public Discrete 00390 { 00391 public: 00397 explicit Poisson(const double m=1); 00398 00402 unsigned long operator()(void) const; 00403 00410 unsigned long operator()(const double m) const; 00411 00412 private: 00413 double m_; 00414 }; 00415 00416 // --------------------- Continuous distribtuions --------------------- 00417 00423 class Continuous 00424 { 00425 public: 00426 00430 Continuous(void); 00431 00435 virtual ~Continuous(void); 00436 00446 void seed(unsigned long s) const; 00447 00455 unsigned long seed_from_devurandom(void) 00456 { return rng_->seed_from_devurandom(); } 00457 00461 virtual double operator()(void) const = 0; 00462 00463 protected: 00465 RNG* rng_; 00466 }; 00467 00468 // ContinuousUniform is declared before ContinuousGeneral to avoid 00469 // forward declaration 00480 class ContinuousUniform : public Continuous 00481 { 00482 public: 00483 double operator()(void) const; 00484 }; 00485 00489 class ContinuousGeneral : public Continuous 00490 { 00491 public: 00497 explicit ContinuousGeneral(const statistics::Histogram& hist); 00498 00507 double operator()(void) const; 00508 00509 private: 00510 const DiscreteGeneral discrete_; 00511 const statistics::Histogram hist_; 00512 ContinuousUniform u_; 00513 }; 00514 00523 class Exponential : public Continuous 00524 { 00525 public: 00531 explicit Exponential(const double m=1); 00532 00536 double operator()(void) const; 00537 00544 double operator()(const double m) const; 00545 00546 private: 00547 double m_; 00548 }; 00549 00563 class Gaussian : public Continuous 00564 { 00565 public: 00572 explicit Gaussian(const double s=1, const double m=0); 00573 00577 double operator()(void) const; 00578 00585 double operator()(const double s) const; 00586 00593 double operator()(const double s, const double m) const; 00594 00595 private: 00596 double m_; 00597 double s_; 00598 }; 00599 00609 template<typename RandomAccessIterator> 00610 void random_shuffle(RandomAccessIterator first, RandomAccessIterator last) 00611 { 00612 typedef RandomAccessIterator rai; 00613 BOOST_CONCEPT_ASSERT((boost::Mutable_RandomAccessIterator<rai>)); 00614 DiscreteUniform rnd; 00615 std::random_shuffle(first, last, rnd); 00616 } 00617 00618 }}} // of namespace random, yat, and theplu 00619 00620 #endif