// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_randf #define tools_randf #include //::rand, RAND_MAX #include "fmath" namespace tools { namespace randf { class flat { public: float shoot() const { // Shoot random numbers in [0,1] according a flat distribution. float value = (float)::rand(); value /= (float)RAND_MAX; return value; } }; class gauss { public: gauss(float a_mean = 0,float a_std_dev = 1) :m_mean(a_mean),m_std_dev(a_std_dev){} public: gauss(const gauss& a_from) :m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){} gauss& operator=(const gauss& a_from) { m_mean = a_from.m_mean; m_std_dev = a_from.m_std_dev; return *this; } public: float shoot() const { // Shoot random numbers according a // gaussian distribution of mean 0 and sigma 1. float v1,v2,r,fac; do { v1 = 2 * m_flat.shoot() - 1; v2 = 2 * m_flat.shoot() - 1; r = v1*v1 + v2*v2; } while ( r > 1 ); fac = fsqrt(-2*flog(r)/r); return (v2 * fac) * m_std_dev + m_mean; } protected: flat m_flat; float m_mean; float m_std_dev; }; class bw { public: bw(float a_mean = 0,float a_gamma = 1) :m_mean(a_mean),m_gamma(a_gamma){} public: bw(const bw& a_from) :m_mean(a_from.m_mean),m_gamma(a_from.m_gamma){} bw& operator=(const bw& a_from) { m_mean = a_from.m_mean; m_gamma = a_from.m_gamma; return *this; } public: float shoot() const { float rval = 2 * m_flat.shoot() - 1; float displ = 0.5f * m_gamma * ftan(rval * fhalf_pi()); return m_mean + displ; } protected: flat m_flat; float m_mean; float m_gamma; }; class exp { public: exp(float a_rate = 1):m_rate(a_rate){} public: exp(const exp& a_from):m_rate(a_from.m_rate){} exp& operator=(const exp& a_from) {m_rate = a_from.m_rate;return *this;} public: float shoot() const { float v; do { v = m_flat.shoot(); } while(v<=0); return -flog(v)/m_rate; } protected: flat m_flat; float m_rate; }; }} #endif