random.h
Go to the documentation of this file.00001 #ifndef RANDOM1_H
00002 #define RANDOM1_H
00003
00004
00005
00006
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
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
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
00195 zahl = zahl * (max+1);
00196
00197
00198
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
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
00234 zahl = zahl * (max+1);
00235
00236
00237
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