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_randf 00005 #define inlib_randf 00006 00007 #include <cstdlib> //::rand, RAND_MAX 00008 #include "fmath" 00009 00010 namespace inlib { 00011 namespace randf { 00012 00013 class flat { 00014 public: 00015 float shoot() const { 00016 // Shoot random numbers in [0,1] according a flat distribution. 00017 float value = (float)::rand(); 00018 value /= (float)RAND_MAX; 00019 return value; 00020 } 00021 }; 00022 00023 class gauss { 00024 public: 00025 gauss(float a_mean = 0,float a_std_dev = 1) 00026 :m_mean(a_mean),m_std_dev(a_std_dev){} 00027 public: 00028 gauss(const gauss& a_from) 00029 :m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){} 00030 gauss& operator=(const gauss& a_from) { 00031 m_mean = a_from.m_mean; 00032 m_std_dev = a_from.m_std_dev; 00033 return *this; 00034 } 00035 public: 00036 float shoot() const { 00037 // Shoot random numbers according a 00038 // gaussian distribution of mean 0 and sigma 1. 00039 float v1,v2,r,fac; 00040 do { 00041 v1 = 2 * m_flat.shoot() - 1; 00042 v2 = 2 * m_flat.shoot() - 1; 00043 r = v1*v1 + v2*v2; 00044 } while ( r > 1 ); 00045 fac = fsqrt(-2*flog(r)/r); 00046 return (v2 * fac) * m_std_dev + m_mean; 00047 } 00048 private: 00049 flat m_flat; 00050 float m_mean; 00051 float m_std_dev; 00052 }; 00053 00054 class bw { 00055 public: 00056 bw(float a_mean = 0,float a_gamma = 1) 00057 :m_mean(a_mean),m_gamma(a_gamma){} 00058 public: 00059 bw(const bw& a_from) 00060 :m_mean(a_from.m_mean),m_gamma(a_from.m_gamma){} 00061 bw& operator=(const bw& a_from) { 00062 m_mean = a_from.m_mean; 00063 m_gamma = a_from.m_gamma; 00064 return *this; 00065 } 00066 public: 00067 float shoot() const { 00068 float rval = 2 * m_flat.shoot() - 1; 00069 float displ = 0.5f * m_gamma * ftan(rval * fhalf_pi()); 00070 return m_mean + displ; 00071 } 00072 private: 00073 flat m_flat; 00074 float m_mean; 00075 float m_gamma; 00076 }; 00077 00078 class exp { 00079 public: 00080 exp(float a_rate = 1):m_rate(a_rate){} 00081 public: 00082 exp(const exp& a_from):m_rate(a_from.m_rate){} 00083 exp& operator=(const exp& a_from) {m_rate = a_from.m_rate;return *this;} 00084 public: 00085 float shoot() const { 00086 float v; 00087 do { 00088 v = m_flat.shoot(); 00089 } while(v<=0); 00090 return -flog(v)/m_rate; 00091 } 00092 private: 00093 flat m_flat; 00094 float m_rate; 00095 }; 00096 00097 }} 00098 00099 #endif