00001 #ifndef RAND_H
00002 #define RAND_H
00003
00004 #include <cmath>
00005 #include <cstdlib>
00006
00007 const int BIGPRIME = 899999963;
00008
00009 class Rand {
00010 double c,cd,cm,u[97];
00011 int i97,j97 ;
00012 bool outputReady;
00013 double output;
00014
00015 public:
00016 Rand(int seed=1) {
00017 ranmarin(abs(seed%BIGPRIME));
00018 outputReady=false;
00019 }
00020
00021
00022
00023
00024
00025
00026
00027
00028 void seed(int seed) {
00029 ranmarin(abs(seed%BIGPRIME));
00030 outputReady=false;
00031 }
00032
00033 double uniform()
00034 {
00035 double uni;
00036
00037 uni=u[i97]-u[j97];
00038 if (uni<0.0) uni+=1.0;
00039 u[i97]=uni;
00040 if (--i97<0) i97=96;
00041 if (--j97<0) j97=96;
00042 c-=cd;
00043 if (c<0.0) c+=cm;
00044 uni-=c;
00045 if (uni<0.0) uni+=1.0;
00046 return(uni);
00047 }
00048
00049
00050 int discrete(int min, int max)
00051 {
00052 int ret= (int)(floor(uniform()*(max+1-min)+min));
00053
00054 return ret;
00055 }
00056
00057
00058 double gaussian(double sd)
00059 {
00060 double x,y,r,z;
00061 if(outputReady)
00062 {
00063 outputReady = false;
00064 return output*sd;
00065 }
00066
00067 do
00068 {
00069 x=(uniform()*2.0)-1.0;
00070 y=(uniform()*2.0)-1.0;
00071 r=x*x+y*y;
00072 } while (r>=1.0);
00073
00074 z=sqrt(-2.0*log(r)/r);
00075 output = x*z;
00076 outputReady=true;
00077 return y*z*sd;
00078 }
00079
00080 private:
00081 void ranmarin(int ijkl)
00082 {
00083 int i,ii,j,jj,k,l,m ;
00084 double s,t ;
00085
00086 int ij=ijkl/30082;
00087 int kl=ijkl-30082*ij;
00088
00089 i=((ij/177)%177)+2 ;
00090 j=(ij%177)+2 ;
00091 k=((kl/169)%178)+1 ;
00092 l=kl%169 ;
00093 for (ii=0;ii<97;ii++) {
00094 s=0.0 ;
00095 t=0.5 ;
00096 for (jj=0;jj<24;jj++) {
00097 m=(((i*j)%179)*k)%179 ;
00098 i=j;
00099 j=k;
00100 k=m;
00101 l=(53*l+1)%169;
00102 if (((l*m)%64)>=32) s+=t;
00103 t*=0.5;
00104 }
00105 u[ii]=s;
00106 }
00107 c=362436.0/16777216.0;
00108 cd=7654321.0/16777216.0;
00109 cm=16777213.0/16777216.0;
00110 i97=96;
00111 j97=32;
00112 }
00113
00114 };
00115
00116 #endif