00001 #ifndef _theplu_yat_random_ 00002 #define _theplu_yat_random_ 00003 00004 // $Id: random.h 2268 2010-06-09 03:44:05Z 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 00330 : public Discrete, 00331 public std::unary_function<unsigned long, unsigned long> 00332 { 00333 public: 00347 explicit DiscreteUniform(unsigned long n=0); 00348 00358 unsigned long operator()(void) const; 00359 00370 unsigned long operator()(unsigned long n) const; 00371 00372 private: 00373 unsigned long range_; 00374 }; 00375 00391 class Poisson : public Discrete 00392 { 00393 public: 00399 explicit Poisson(const double m=1); 00400 00404 unsigned long operator()(void) const; 00405 00412 unsigned long operator()(const double m) const; 00413 00414 private: 00415 double m_; 00416 }; 00417 00418 // --------------------- Continuous distribtuions --------------------- 00419 00425 class Continuous 00426 { 00427 public: 00428 00432 Continuous(void); 00433 00437 virtual ~Continuous(void); 00438 00448 void seed(unsigned long s) const; 00449 00457 unsigned long seed_from_devurandom(void) 00458 { return rng_->seed_from_devurandom(); } 00459 00463 virtual double operator()(void) const = 0; 00464 00465 protected: 00467 RNG* rng_; 00468 }; 00469 00470 // ContinuousUniform is declared before ContinuousGeneral to avoid 00471 // forward declaration 00482 class ContinuousUniform : public Continuous 00483 { 00484 public: 00485 double operator()(void) const; 00486 }; 00487 00491 class ContinuousGeneral : public Continuous 00492 { 00493 public: 00499 explicit ContinuousGeneral(const statistics::Histogram& hist); 00500 00509 double operator()(void) const; 00510 00511 private: 00512 const DiscreteGeneral discrete_; 00513 const statistics::Histogram hist_; 00514 ContinuousUniform u_; 00515 }; 00516 00525 class Exponential : public Continuous 00526 { 00527 public: 00533 explicit Exponential(const double m=1); 00534 00538 double operator()(void) const; 00539 00546 double operator()(const double m) const; 00547 00548 private: 00549 double m_; 00550 }; 00551 00565 class Gaussian : public Continuous 00566 { 00567 public: 00574 explicit Gaussian(const double s=1, const double m=0); 00575 00579 double operator()(void) const; 00580 00587 double operator()(const double s) const; 00588 00595 double operator()(const double s, const double m) const; 00596 00597 private: 00598 double m_; 00599 double s_; 00600 }; 00601 00611 template<typename RandomAccessIterator> 00612 void random_shuffle(RandomAccessIterator first, RandomAccessIterator last) 00613 { 00614 typedef RandomAccessIterator rai; 00615 BOOST_CONCEPT_ASSERT((boost::Mutable_RandomAccessIterator<rai>)); 00616 DiscreteUniform rnd; 00617 std::random_shuffle(first, last, rnd); 00618 } 00619 00620 }}} // of namespace random, yat, and theplu 00621 00622 #endif