DSQSS
1.1
|
00001 /* 00002 *================================================================= 00003 * Class Random for random number generation 00004 *================================================================= 00005 * $Id: Random.cc,v 1.1 2000/02/10 16:13:02 kenji Exp $ 00006 * $Log: Random.cc,v $ 00007 * Revision 1.1 2000/02/10 16:13:02 kenji 00008 * Initial revision 00009 * 00010 *================================================================= 00011 * The copyright holder of the following codes is 00012 * 00013 * Kenji HARADA 00014 * Graduate School of Infomatics, Kyoto University, 00015 * Kyoto 606-8501, Japan 00016 * e-mail: harada@acs.i.kyoto-u.ac.jp 00017 * home-page: http://www-fcs.acs.i.kyoto-u.ac.jp/~harada/ 00018 *================================================================= 00019 */ 00020 00021 #include "random.h" 00022 //---- add sakakura 20110322 ---- 00023 #include <stdlib.h> 00024 #include <time.h> 00025 double Random::Dicex(void){ 00026 return (double)rand()/RAND_MAX; 00027 } 00028 void Random::InitRand(){ 00029 srand((unsigned)time(NULL)); 00030 } 00031 //---- add sakakura 20110322 ---- 00032 // 00033 // 00034 double Random::Uniform(void){ 00035 if(navr == 0){ 00036 Rint i; 00037 for(i=0;i<IQQ;i++) 00038 iri[i]^=iri[i+IPQ]; 00039 for(i=IQQ;i<IPP;i++) 00040 iri[i]^=iri[i-IQQ]; 00041 iptr=0; 00042 navr=IPP; 00043 } 00044 navr--; 00045 return runit*iri[iptr++]; 00046 } 00047 //: 一様分布 [0,1) 00048 // 戻り値に 0以上、1未満の乱数(実数値)を返す。 00049 00050 Rint Random::Int(Rint ilimit){ 00051 if(navr == 0){ 00052 Rint i; 00053 for(i=0;i<IQQ;i++) 00054 iri[i]^=iri[i+IPQ]; 00055 for(i=IQQ;i<IPP;i++) 00056 iri[i]^=iri[i-IQQ]; 00057 iptr=0; 00058 navr=IPP; 00059 } 00060 navr--; 00061 return (Rint) (ilimit*runit*iri[iptr++]); 00062 } 00063 00064 Rint Random::Int(void){ 00065 if(navr == 0){ 00066 Rint i; 00067 for(i=0;i<IQQ;i++) 00068 iri[i]^=iri[i+IPQ]; 00069 for(i=IQQ;i<IPP;i++) 00070 iri[i]^=iri[i-IQQ]; 00071 iptr=0; 00072 navr=IPP; 00073 } 00074 navr--; 00075 return (Rint) iri[iptr++]; 00076 } 00077 //: 離散一様分布 (0, 1, .. ,2**nrbit0-1) 00078 // 戻り値に 0以上、2**nrbit0未満の乱数(整数)を返す。 00079 00080 void Random::Perm(Rint N, int* Index){ 00081 for(Rint i=0; i<N; i++) Index[i] = i; 00082 for(Rint i=0; i<N-1; i++){ 00083 Rint x=Index[i]; 00084 Rint ix=i+Int(N-i); 00085 Index[i]=Index[ix]; 00086 Index[ix]=x; 00087 } 00088 /* 00089 Rint i,n,ind; 00090 double rx=runit*N; 00091 for (i=0; i<N; i++) Index[i] = -1; 00092 ind = 0; 00093 while(ind < N) { 00094 n = (Rint) (Int()*rx); 00095 if (Index[n] == -1) { 00096 Index[n] = ind; 00097 ind++; 00098 } 00099 } 00100 */ 00101 } 00102 //: Permutation生成 00103 00104 void Random::Scramble(Rint N, int* Index){ 00105 for(Rint i=0; (i+1)<N; i++){ 00106 Rint x=Index[i]; 00107 Rint ix=i+Int(N-i); 00108 Index[i]=Index[ix]; 00109 Index[ix]=x; 00110 } 00111 } 00112 //: Scramble 00113 00114 void Random::initialize(Rint irand0, Rint nrbit0){ 00115 /* 00116 *----------------------------------------------------------------- 00117 * 00118 * This subroutine calculates the random seed and the effective bit. 00119 * The irand0 is initial seed. 00120 * The nrbit0 is effective bit as 0 <= random number <= 2**nrbit0 - 1. 00121 * (Note. 0<= nrbit0 <= 32) 00122 *----------------------------------------------------------------- 00123 */ 00124 Rint imask; 00125 Rint ix,ih,mj,ii,ij; 00126 Rint i,j; 00127 Rint ia[IPP],ib[IPP]; 00128 00129 nrbit = nrbit0; 00130 imask = 1; 00131 for(i=0;i<nrbit-1;i++) 00132 imask = (imask << 1) + 1; 00133 runit = 1e0/(imask+1e0); 00134 ix = irand0; 00135 for(i=0;i<IPP;i++){ 00136 ix=(ix*1812433253+1) & 0xffffffff; 00137 if(ix & 0x80000000) 00138 ia[i]=1; 00139 else 00140 ia[i]=0; 00141 } 00142 for(j=0;j<IPP;j++){ 00143 ih=((j*32) % IPP); 00144 mj=0; 00145 for(i=0;i<32;i++){ 00146 ii=(ih+i)%IPP; 00147 mj=2*mj+ia[ii]; 00148 ij=(ii+IPQ)%IPP; 00149 ia[ii]^=ia[ij]; 00150 } 00151 ib[j]=mj; 00152 } 00153 for(j=0;j<IPP;j++){ 00154 ih=((j*16)%IPP); 00155 iri[j]=imask & ib[ih]; 00156 for(i=0;i<16;i++){ 00157 ii=(ih+i)%IPP; 00158 ij=(ii+IPQ)%IPP; 00159 ib[ii]^=ib[ij]; 00160 } 00161 } 00162 navr=IPP; 00163 iptr=0; 00164 return; 00165 } 00166 00167 Random::Random(Rint *seed, Rint nrbit0){setSeed(seed,nrbit0);} 00168 Random::Random(Rint irand0, Rint nrbit0){initialize(irand0,nrbit0);} 00169 00170 void Random::setSeed(Rint irand0,Rint nrbit0){initialize(irand0,nrbit0);} 00171 void Random::setSeed(Rint *seed,Rint nrbit0){ 00172 Rint imask; 00173 Rint i; 00174 nrbit = nrbit0; 00175 imask = 1; 00176 for(i=0;i<nrbit-1;i++) 00177 imask = (imask << 1) + 1; 00178 runit = 1e0/(imask+1e0); 00179 for(i=0;i<IPP;i++) 00180 iri[i] = imask & seed[i]; 00181 navr=IPP; 00182 iptr=0; 00183 return; 00184 } 00185 00186 Rint Random::getSeed (Rint *seed){ 00187 Uniform(IPP,seed); 00188 return nrbit; 00189 } 00190 00191 void Random::Uniform(Rint nr,Rint *ir){ 00192 /* 00193 *---------------------------------------------------------------- 00194 * 00195 * This subroutine calculates random number table. 00196 * The nr is length of the table. 00197 * The ir is Rint array for returned table. 00198 * 00199 * The returned value is as follows:0 <= returned value <= 2**nrbit-1. 00200 * 00201 *---------------------------------------------------------------- 00202 */ 00203 Rint i,nrec,n1,iptd; 00204 00205 nrec = nr; 00206 n1 = (navr > nrec ? nrec : navr); 00207 for(i=0;i<n1;i++) 00208 ir[i]=iri[iptr+i]; 00209 iptd=n1; 00210 iptr+=n1; 00211 navr-=n1; 00212 nrec-=n1; 00213 while(nrec > 0){ 00214 for(i=0;i<IQQ;i++) 00215 iri[i]^=iri[i+IPQ]; 00216 for(i=IQQ;i<IPP;i++) 00217 iri[i]^=iri[i-IQQ]; 00218 n1=(IPP > nrec ? nrec : IPP); 00219 for(i=0;i<n1;i++) 00220 ir[iptd+i]=iri[i]; 00221 iptd+=n1; 00222 iptr=n1; 00223 navr=IPP-n1; 00224 nrec-=n1; 00225 } 00226 return; 00227 } 00228 00229 void Random::Uniform(Rint nr,double *rx){ 00230 /* 00231 *---------------------------------------------------------------- 00232 * 00233 * This subroutine calculates random number table. 00234 * The nr is length of the table. 00235 * The rx is double array for returned table. 00236 * 00237 * The returned value is as follows:0 <= returned value < 1. 00238 * 00239 *---------------------------------------------------------------- 00240 */ 00241 Rint i,nrec,n1,iptd; 00242 00243 nrec = nr; 00244 n1 = (navr > nrec ? nrec : navr); 00245 for(i=0;i<n1;i++) 00246 rx[i]=runit*iri[iptr+i]; 00247 iptd=n1; 00248 iptr+=n1; 00249 navr-=n1; 00250 nrec-=n1; 00251 while(nrec > 0){ 00252 for(i=0;i<IQQ;i++) 00253 iri[i]^=iri[i+IPQ]; 00254 for(i=IQQ;i<IPP;i++) 00255 iri[i]^=iri[i-IQQ]; 00256 n1=(IPP > nrec ? nrec : IPP); 00257 for(i=0;i<n1;i++) 00258 rx[iptd+i]=runit*iri[i]; 00259 iptd+=n1; 00260 iptr=n1; 00261 navr=IPP-n1; 00262 nrec-=n1; 00263 } 00264 return; 00265 } 00266 00267 void Random::Int(Rint nr,Rint *ir,Rint ilimit){ 00268 /* 00269 *---------------------------------------------------------------- 00270 * 00271 * This subroutine calculates random number table. 00272 * The nr is length of the table. 00273 * The ir is Rint array for returned table. 00274 * The ilimit is upper bound of returned table. 00275 * 00276 * The returned value is as follows:0 <= returned value < ilimit. 00277 * 00278 *---------------------------------------------------------------- 00279 */ 00280 Rint i,nrec,n1,iptd; 00281 double runitx; 00282 00283 runitx=runit*ilimit; 00284 nrec = nr; 00285 n1 = (navr > nrec ? nrec : navr); 00286 for(i=0;i<n1;i++) 00287 ir[i]=(Rint) (runitx*iri[iptr+i]); 00288 iptd=n1; 00289 iptr+=n1; 00290 navr-=n1; 00291 nrec-=n1; 00292 while(nrec > 0){ 00293 for(i=0;i<IQQ;i++) 00294 iri[i]^=iri[i+IPQ]; 00295 for(i=IQQ;i<IPP;i++) 00296 iri[i]^=iri[i-IQQ]; 00297 n1=(IPP > nrec ? nrec : IPP); 00298 for(i=0;i<n1;i++) 00299 ir[iptd+i]=(Rint)(runitx*iri[i]); 00300 iptd+=n1; 00301 iptr=n1; 00302 navr=IPP-n1; 00303 nrec-=n1; 00304 } 00305 return; 00306 }