00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00027 class mdp_prng {
00028 private:
00029 float u[98];
00030 float c;
00031 float cd;
00032 float cm;
00033 int ui;
00034 int uj;
00035 public:
00037 inline float plain() {
00038 float luni;
00039 luni = u[ui] - u[uj];
00040 if (luni < 0.0)
00041 luni += 1.0;
00042 u[ui] = luni;
00043 if (--ui == 0)
00044 ui = 97;
00045 if (--uj == 0)
00046 uj = 97;
00047 if ((c -= cd) < 0.0)
00048 c += cm;
00049 if ((luni -= c) < 0.0)
00050 luni += 1.0;
00051 return ((float) luni);
00052 }
00053
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00072
00073 void initialize(mdp_int ijkl) {
00074 int i, j, k, l, ij, kl;
00075 if( (ijkl < 0) || (ijkl > 900000000) )
00076 error("Wrong initialization for random number generator");
00077 ij = ijkl/30082;
00078 kl = ijkl - (30082 * ij);
00079 i = ((ij/177) % 177) + 2;
00080 j = (ij % 177) + 2;
00081 k = ((kl/169) % 178) + 1;
00082 l = kl % 169;
00083 if( (i <= 0) || (i > 178) )
00084 error("Wrong initialization for random number generator");
00085 if( (j <= 0) || (j > 178) )
00086 error("Wrong initialization for random number generator");
00087 if( (k <= 0) || (k > 178) )
00088 error("Wrong initialization for random number generator");
00089 if( (l < 0) || (l > 168) )
00090 error("Wrong initialization for random number generator");
00091 if (i == 1 && j == 1 && k == 1)
00092 error("Wrong initialization for random number generator");
00093 int ii, jj, m;
00094 float s, t;
00095 for (ii = 1; ii <= 97; ii++) {
00096 s = 0.0;
00097 t = 0.5;
00098 for (jj = 1; jj <= 24; jj++) {
00099 m = ((i*j % 179) * k) % 179;
00100 i = j;
00101 j = k;
00102 k = m;
00103 l = (53*l+1) % 169;
00104 if (l*m % 64 >= 32) s += t;
00105 t *= 0.5;
00106 }
00107 u[ii] = s;
00108 }
00109 c = 362436.0 / 16777216.0;
00110 cd = 7654321.0 / 16777216.0;
00111 cm = 16777213.0 / 16777216.0;
00112 ui = 97;
00113 uj = 33;
00114 }
00115 mdp_prng(mdp_int k=0) {
00116 if(k==0) initialize(ME);
00117 }
00119 float gaussian(float sigma=1) {
00120 #ifdef AIX
00121 static int i;
00122 #else
00123 static int i=0;
00124 #endif
00125 static float r;
00126 float x,y;
00127 if(i==0) {
00128 x=(float) sqrt(-2.0*log(plain()));
00129 y=(float) 2.0*Pi*plain();
00130 i=1;
00131 r=sigma*x*((float) cos(y));
00132 return sigma*x*((float) sin(y));
00133 } else {
00134 i=0;
00135 return r;
00136 }
00137 }
00139 double distribution(float (*fp)(float, void *), void *a=0) {
00140 float x,y;
00141 do {
00142 x=plain();
00143 y=plain();
00144 } while ((*fp)(x, a)>=y);
00145 return x;
00146 }
00148 mdp_matrix SU(int n) {
00149 mdp_matrix tmp, small;
00150 register int i,j;
00151 register float alpha, sin_alpha;
00152 register float a0, a1, a2, a3;
00153 register float phi, cos_theta, sin_theta;
00154 if(n==1) {
00155 tmp.dimension(1,1);
00156 alpha=2.0*Pi*this->plain();
00157 tmp(0,0)=mdp_complex(cos(alpha),sin(alpha));
00158 return tmp;
00159 }
00160 tmp=mdp_identity(n);
00161 for(i=0; i<(n-1); i++)
00162 for(j=i+1; j<n; j++) {
00163 alpha=Pi*this->plain();
00164 phi=2.0*Pi*this->plain();
00165 cos_theta=2.0*this->plain()-1.0;
00166 sin_theta=sqrt(1.0-cos_theta*cos_theta);
00167 sin_alpha=sin(alpha);
00168 a0=cos(alpha);
00169 a1=sin_alpha*sin_theta*cos(phi);
00170 a2=sin_alpha*sin_theta*sin(phi);
00171 a3=sin_alpha*cos_theta;
00172 small=mdp_identity(n);
00173 small(i,i)=mdp_complex(a0,a3);
00174 small(i,j)=mdp_complex(a2,a1);
00175 small(j,i)=mdp_complex(-a2,a1);
00176 small(j,j)=mdp_complex(a0,-a3);
00177 tmp=small*tmp;
00178 }
00179 return tmp;
00180 }
00182 void skip(int n) {
00183 for(int i=0; i<n; i++) this->plain();
00184 }
00185 } mdp_random;