00001 /** @file rutz/rand.h random-number generation */ 00002 00003 /////////////////////////////////////////////////////////////////////// 00004 // 00005 // Copyright (c) 1999-2004 California Institute of Technology 00006 // Copyright (c) 2004-2007 University of Southern California 00007 // Rob Peters <rjpeters at usc dot edu> 00008 // 00009 // created: Fri Jun 25 14:09:24 1999 00010 // commit: $Id: rand.h 8249 2007-04-12 06:03:40Z rjpeters $ 00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/rand.h $ 00012 // 00013 // The random number generator classes here are taken from _The C++ 00014 // Programming Language_, 3rd ed., by Bjarne Stroustrup. 00015 // 00016 // -------------------------------------------------------------------- 00017 // 00018 // This file is part of GroovX. 00019 // [http://ilab.usc.edu/rjpeters/groovx/] 00020 // 00021 // GroovX is free software; you can redistribute it and/or modify it 00022 // under the terms of the GNU General Public License as published by 00023 // the Free Software Foundation; either version 2 of the License, or 00024 // (at your option) any later version. 00025 // 00026 // GroovX is distributed in the hope that it will be useful, but 00027 // WITHOUT ANY WARRANTY; without even the implied warranty of 00028 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00029 // General Public License for more details. 00030 // 00031 // You should have received a copy of the GNU General Public License 00032 // along with GroovX; if not, write to the Free Software Foundation, 00033 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00034 // 00035 /////////////////////////////////////////////////////////////////////// 00036 00037 #ifndef GROOVX_RUTZ_RAND_H_UTC20050626084020_DEFINED 00038 #define GROOVX_RUTZ_RAND_H_UTC20050626084020_DEFINED 00039 00040 #include <cstdlib> // for rand() 00041 00042 namespace rutz 00043 { 00044 class urand; 00045 class urand_irange; 00046 class urand_frange; 00047 00048 template <class T> 00049 inline T rand_range(const T& min, const T& max) 00050 { 00051 return T( (double(rand()) / (double(RAND_MAX)+1.0)) * (max-min) + min ); 00052 } 00053 00054 /// A hook that allows various code to start from a predictable seed. 00055 /** This allows code in disparate locations to all be triggered by 00056 the same random seed. This is useful in allowing for predictable 00057 and repeatable execution sequences e.g. in a testing 00058 context. Initial value is 0. The most sensible use case involves 00059 setting this value just once, at or near the beginning of 00060 program execution. */ 00061 extern unsigned long default_rand_seed; 00062 } 00063 00064 /// Uniform random distribution 00065 class rutz::urand 00066 { 00067 private: 00068 unsigned long randx; 00069 00070 int abs(int x) { return x & 0x7fffffff; } 00071 static double max() { return 2147483648.0 /* == 0x80000000u */; } 00072 00073 int idraw() { return randx = randx * 0x41c64e6d + 0x3039; } 00074 00075 public: 00076 urand(long s = 0) : randx(s) {} 00077 void seed(long s) { randx = s; } 00078 00079 /// Uniform random distribution in the interval [0.0:1.0[ 00080 double fdraw() 00081 { 00082 return abs(idraw())/max(); 00083 } 00084 00085 /// Uniform random distribution in the interval [min:max[ 00086 double fdraw_range(double min, double max) 00087 { 00088 return min + fdraw() * (max-min); 00089 } 00090 00091 /// Uniform random distribution between true:false 00092 bool booldraw() 00093 { 00094 return fdraw() < 0.5; 00095 } 00096 00097 /// Uniform random distribution in the interval [0:n[ 00098 int idraw(int n) 00099 { 00100 int r = int(n*fdraw()); return (r==n) ? n-1 : r; 00101 } 00102 00103 /// Uniform random distribution in the interval [lo:hi[ 00104 int idraw_range(int lo, int hi) 00105 { 00106 return lo + idraw(hi - lo); 00107 } 00108 00109 /// Uniform random distribution in the interval [0:n[ 00110 int operator()(int n) { return idraw(n); } 00111 }; 00112 00113 /// uniform distribution over a specified integer range 00114 class rutz::urand_irange 00115 { 00116 private: 00117 rutz::urand m_generator; 00118 int m_min; 00119 int m_max; 00120 00121 public: 00122 /// Construct with a given min/max range and an initial seed (default 0). 00123 urand_irange(int lo, int hi, long s = 0) 00124 : m_generator(s), m_min(lo), m_max(hi) 00125 {} 00126 00127 int draw() { return m_generator.idraw_range(m_min, m_max); } 00128 int operator()() { return draw(); } 00129 }; 00130 00131 /// uniform distribution over a specified floating-point range 00132 class rutz::urand_frange 00133 { 00134 private: 00135 rutz::urand m_generator; 00136 double m_min; 00137 double m_max; 00138 00139 public: 00140 /// Construct with a given min/max range and an initial seed (default 0). 00141 urand_frange(double lo, double hi, long s = 0) 00142 : m_generator(s), m_min(lo), m_max(hi) 00143 {} 00144 00145 /// Construct with a range [0.0:1.0[ and an initial seed (default 0). 00146 urand_frange(long s = 0) 00147 : m_generator(s), m_min(0.0), m_max(1.0) 00148 {} 00149 00150 double draw() { return m_generator.fdraw_range(m_min, m_max); } 00151 double operator()() { return draw(); } 00152 }; 00153 00154 static const char __attribute__((used)) vcid_groovx_rutz_rand_h_utc20050626084020[] = "$Id: rand.h 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/rand.h $"; 00155 #endif // !GROOVX_RUTZ_RAND_H_UTC20050626084020_DEFINED