inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_random 00005 #define inlib_random 00006 00007 #include <cstdlib> //::rand, RAND_MAX 00008 #include <cmath> //::sqrt, ::log 00009 00010 #include "math" 00011 00012 namespace inlib { 00013 namespace random { 00014 00015 class flat { 00016 public: 00017 double shoot() const { 00018 // Shoot random numbers in [0,1] according a flat distribution. 00019 double value = (double)::rand(); 00020 value /= (double)RAND_MAX; 00021 return value; 00022 } 00023 }; 00024 00025 class gauss { 00026 public: 00027 gauss(double a_mean = 0,double a_std_dev = 1) 00028 :m_mean(a_mean),m_std_dev(a_std_dev){} 00029 public: 00030 gauss(const gauss& a_from) 00031 :m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){} 00032 gauss& operator=(const gauss& a_from) { 00033 m_mean = a_from.m_mean; 00034 m_std_dev = a_from.m_std_dev; 00035 return *this; 00036 } 00037 public: 00038 double shoot() const { 00039 // Shoot random numbers according a 00040 // gaussian distribution of mean 0 and sigma 1. 00041 double v1,v2,r,fac; 00042 do { 00043 v1 = 2.0 * m_flat.shoot() - 1.0; 00044 v2 = 2.0 * m_flat.shoot() - 1.0; 00045 r = v1*v1 + v2*v2; 00046 } while ( r > 1.0 ); 00047 fac = ::sqrt(-2.0*::log(r)/r); 00048 return (v2 * fac) * m_std_dev + m_mean; 00049 } 00050 private: 00051 flat m_flat; 00052 double m_mean; 00053 double m_std_dev; 00054 }; 00055 00056 class bw { 00057 public: 00058 bw(double a_mean = 0,double a_gamma = 1) 00059 :m_mean(a_mean),m_gamma(a_gamma){} 00060 public: 00061 bw(const bw& a_from) 00062 :m_mean(a_from.m_mean),m_gamma(a_from.m_gamma){} 00063 bw& operator=(const bw& a_from) { 00064 m_mean = a_from.m_mean; 00065 m_gamma = a_from.m_gamma; 00066 return *this; 00067 } 00068 public: 00069 double shoot() const { 00070 double rval = 2.0 * m_flat.shoot() - 1.0; 00071 double displ = 0.5 * m_gamma * ::tan(rval * half_pi()); 00072 return m_mean + displ; 00073 } 00074 private: 00075 flat m_flat; 00076 double m_mean; 00077 double m_gamma; 00078 }; 00079 00080 class exp { 00081 public: 00082 exp(double a_rate = 1):m_rate(a_rate){} 00083 public: 00084 exp(const exp& a_from):m_rate(a_from.m_rate){} 00085 exp& operator=(const exp& a_from) {m_rate = a_from.m_rate;return *this;} 00086 public: 00087 double shoot() const { 00088 double v; 00089 do { 00090 v = m_flat.shoot(); 00091 } while(v<=0); 00092 return -::log(v)/m_rate; 00093 } 00094 private: 00095 flat m_flat; 00096 double m_rate; 00097 }; 00098 00099 }} 00100 00101 #endif