DSQSS  1.1
random.cc
説明を見る。
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 }
 全て クラス ネームスペース ファイル 関数 変数 型定義 列挙型の値 フレンド マクロ定義