random.h

Go to the documentation of this file.
00001 #ifndef RANDOM1_H
00002 #define RANDOM1_H
00003 
00004 
00005 
00006 
00016 /* note #undef's at end of file */
00017 /*
00018 #define IA 16807
00019 #define IM 2147483647
00020 #define AM (1.0/IM)
00021 #define IQ 127773
00022 #define IR 2836
00023 #define NTAB 32
00024 #define NDIV (1+(IM-1)/NTAB)
00025 #define EPS 1.2e-7
00026 #define RNMX (1.0-EPS)
00027 
00028 
00029 // Long period (> 2.0e18) random number generator of L'Ecuyer with
00030 // Bays-Durham shuffle and added safeguards.  Returns a uniform
00031 // random deviate between 0.0 and 1.0 (exclusive of the endpoints).
00032 
00033 float ran1(long *idum)
00034 {
00035         int j;
00036         long k;
00037         static long iy=0;
00038         static long iv[NTAB];
00039         float temp;
00040 
00041         if (*idum <= 0 || !iy) {
00042                 if (-(*idum) < 1) *idum=1;
00043                 else *idum = -(*idum);
00044                 for (j=NTAB+7;j>=0;j--) {
00045                         k=(*idum)/IQ;
00046                         *idum=IA*(*idum-k*IQ)-IR*k;
00047                         if (*idum < 0) *idum += IM;
00048                         if (j < NTAB) iv[j] = *idum;
00049                 }
00050                 iy=iv[0];
00051         }
00052         k=(*idum)/IQ;
00053         *idum=IA*(*idum-k*IQ)-IR*k;
00054         if (*idum < 0) *idum += IM;
00055         j=iy/NDIV;
00056         iy=iv[j];
00057         iv[j] = *idum;
00058         if ((temp=(float)(AM*iy)) > RNMX) return (float) RNMX;
00059         else return temp;
00060 }
00061 #undef IA
00062 #undef IM
00063 #undef AM
00064 #undef IQ
00065 #undef IR
00066 #undef NTAB
00067 #undef NDIV
00068 #undef EPS
00069 #undef RNMX
00070 */
00071 
00072 
00073 // Long period (> 2.0e18) random number generator of L'Ecuyer with
00074 // Bays-Durham shuffle and added safeguards.  Returns a uniform
00075 // random deviate between 0.0 and 1.0 (exclusive of the endpoints).
00076 
00077 #define IM1 2147483563
00078 #define IM2 2147483399
00079 #define AM (1.0/IM1)
00080 #define IMM1 (IM1-1)
00081 #define IA1 40014
00082 #define IA2 40692
00083 #define IQ1 53668
00084 #define IQ2 52774
00085 #define IR1 12211
00086 #define IR2 3791
00087 #define NTAB 32
00088 #define NDIV (1+IMM1/NTAB)
00089 #define EPS 1.2e-7
00090 #define RNMX (1.0-EPS)
00091 
00092 
00102 double ran2(long *idum)
00103 {
00104         int j;
00105         long k;
00106         static long idum2=123456789;
00107         static long iy=0;
00108         static long iv[NTAB];
00109         double temp;
00110 
00111         if (*idum <= 0)
00112         {
00113                 if (-(*idum) < 1)
00114                 *idum=1;
00115                 else
00116                 *idum = -(*idum);
00117 
00118                 idum2=(*idum);
00119                 for (j=NTAB+7;j>=0;j--)
00120                 {
00121                         k=(*idum)/IQ1;
00122 
00123                         *idum=IA1*(*idum-k*IQ1)-k*IR1;
00124 
00125                         if (*idum < 0) 
00126                                 *idum += IM1;
00127 
00128                         if (j < NTAB) 
00129                                 iv[j] = *idum;
00130                 }
00131                 iy=iv[0];
00132         }
00133 
00134         k=(*idum)/IQ1;
00135         *idum=IA1*(*idum-k*IQ1)-k*IR1;
00136 
00137         if (*idum < 0) 
00138                 *idum += IM1;
00139 
00140         k=idum2/IQ2;
00141         idum2=IA2*(idum2-k*IQ2)-k*IR2;
00142 
00143         if (idum2 < 0) 
00144                 idum2 += IM2;
00145 
00146         j=iy/NDIV;
00147         iy=iv[j]-idum2;
00148         iv[j] = *idum;
00149 
00150         if (iy < 1) 
00151                 iy += IMM1;
00152 
00153         return (temp = AM*iy) > RNMX ? RNMX : temp;
00154 }
00155 
00156 #undef IM1
00157 #undef IM2
00158 #undef AM
00159 #undef IMM1
00160 #undef IA1
00161 #undef IA2
00162 #undef IQ1
00163 #undef IQ2
00164 #undef IR1
00165 #undef IR2
00166 #undef NTAB
00167 #undef NDIV
00168 #undef EPS
00169 #undef RNMX
00170 
00175 inline unsigned short random (long *seed, unsigned short max) 
00176 {
00177         #ifdef DEBUG 
00178                 std::cerr << "----------- " << std::endl;
00179                 std::cerr << "Random call " << std::endl;
00180                 std::cerr << "seed "<<  *seed << std::endl;
00181                 std::cerr << "max "<<  max << std::endl;
00182         #endif 
00183         
00184         //float zahl = 1.0; //Attention: float for ran1, double for ran2 !!!
00185         double zahl = 1.0;
00186         int counter=0;
00187         while (zahl == 1.0)
00188         {
00189                 zahl = ran2(seed);
00190                 counter++;
00191         }
00192 
00193         assert(counter<=1);
00194         // Zahl ist zwischen 0 (eingeschl.) und 1 (ausgeschlossen)
00195         zahl = zahl * (max+1);
00196         // Zahl ist zwischen 0 (eingeschl.) und max+1 (ausgeschlossen)
00197 
00198         //also muss Zahl nur noch abgerundet werden
00199         #ifdef SAFE
00200                 assert((unsigned short)(zahl - 0.0) == (unsigned short)(zahl  ) );
00201                 assert((unsigned short)(zahl  )<=max );
00202         #endif
00203 
00204         #ifdef DEBUG 
00205                 
00206                 std::cerr << "random "<<  (unsigned short)(zahl - 0.0) << std::endl;
00207                 std::cerr << "Random call " << std::endl;
00208                 std::cerr << "----------- " << std::endl;
00209         #endif 
00210         return  (unsigned short) (zahl - 0.0);
00211 }
00212 
00213 
00214 inline uint32_t randomUInt32 (long *seed, uint32_t max) 
00215 {
00216         #ifdef DEBUG 
00217                 std::cerr << "----------- " << std::endl;
00218                 std::cerr << "Random call " << std::endl;
00219                 std::cerr << "seed "<<  *seed << std::endl;
00220                 std::cerr << "max "<<  max << std::endl;
00221         #endif 
00222         
00223         //float zahl = 1.0; //Attention: float for ran1, double for ran2 !!!
00224         double zahl = 1.0;
00225         int counter=0;
00226         while (zahl == 1.0)
00227         {
00228                 zahl = ran2(seed);
00229                 counter++;
00230         }
00231 
00232         assert(counter<=1);
00233         // Zahl ist zwischen 0 (eingeschl.) und 1 (ausgeschlossen)
00234         zahl = zahl * (max+1);
00235         // Zahl ist zwischen 0 (eingeschl.) und max+1 (ausgeschlossen)
00236 
00237         //also muss Zahl nur noch abgerundet werden
00238         #ifdef SAFE
00239                 assert((unsigned short)(zahl - 0.0) == (unsigned short)(zahl  ) );
00240                 assert((unsigned short)(zahl  )<=max );
00241         #endif
00242 
00243         #ifdef DEBUG 
00244                 
00245                 std::cerr << "random "<<  (unsigned short)(zahl - 0.0) << std::endl;
00246                 std::cerr << "Random call " << std::endl;
00247                 std::cerr << "----------- " << std::endl;
00248         #endif 
00249         return  (uint32_t) (zahl - 0.0);
00250 }
00251 
00252 
00253 static long CF_MM_s1 = 1;
00254 static long CF_MM_s2 = 1;
00255 
00256 #define MODMULT(a, b, c, m, s) q = s/a; s = b*(s-a*q)-c*q; if (s < 0) s += m;
00257 
00258 double combinedLCG(void)
00259 {
00260     long q, z;
00261 
00262     MODMULT(53668, 40014, 12211, 2147483563L, CF_MM_s1)
00263     MODMULT(52774, 40692, 3791, 2147483399L, CF_MM_s2)
00264     z = CF_MM_s1 - CF_MM_s2;
00265     if (z < 1)
00266         z += 2147483562;
00267     return z * 4.656613e-10;
00268 }
00269 
00270 void initLCG(long init_s1, long init_s2)
00271 {
00272     CF_MM_s1 = init_s1;
00273     CF_MM_s2 = init_s2;
00274 }
00275 
00276 #endif
Generated on Tue Nov 23 13:10:52 2010 for centerfocus by  doxygen 1.6.3