00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "JamesRandom.h"
00037
00038 HepJamesRandom::HepJamesRandom(long seed)
00039 {
00040 setSeed(seed,0);
00041 setSeeds(&theSeed,0);
00042 }
00043
00044 HepJamesRandom::~HepJamesRandom() {}
00045
00046 HepJamesRandom::HepJamesRandom(const HepJamesRandom &p)
00047 {
00048 HepInt ipos, jpos;
00049 if ((this != &p) && (&p)) {
00050 theSeed = p.getSeed();
00051 setSeeds(&theSeed,0);
00052 for (HepInt i=0; i<97; ++i)
00053 u[i] = p.u[i];
00054 c = p.c; cd = p.cd; cm = p.cm;
00055 jpos = HepInt(p.pj97-p.u);
00056 ipos = (64+jpos)%97;
00057 pi97 = &u[ipos]; pj97 = &u[jpos];
00058 }
00059 }
00060
00061 HepJamesRandom & HepJamesRandom::operator = (const HepJamesRandom &p)
00062 {
00063 HepInt ipos, jpos;
00064 if ((this != &p) && (&p)) {
00065 theSeed = p.getSeed();
00066 setSeeds(&theSeed,0);
00067 for (HepInt i=0; i<97; ++i)
00068 u[i] = p.u[i];
00069 c = p.c; cd = p.cd; cm = p.cm;
00070 jpos = HepInt(p.pj97-p.u);
00071 ipos = (64+jpos)%97;
00072 pi97 = &u[ipos]; pj97 = &u[jpos];
00073 }
00074 return *this;
00075 }
00076
00077 void HepJamesRandom::saveStatus() const
00078 {
00079 ofstream outFile("JamesRand.conf", ios::out ) ;
00080
00081 if (!outFile.bad()) {
00082 HepInt pos = HepInt(pj97-u);
00083 outFile << theSeed << endl;
00084 for (HepInt i=0; i<97; ++i)
00085 outFile << u[i] << " ";
00086 outFile << endl;
00087 outFile << c << " " << cd << " " << cm << endl;
00088 outFile << pos << endl;
00089 }
00090 }
00091
00092 void HepJamesRandom::restoreStatus()
00093 {
00094 HepInt ipos, jpos;
00095 ifstream inFile("JamesRand.conf", ios::in);
00096
00097 if (!inFile.bad() && !inFile.eof()) {
00098 inFile >> theSeed;
00099 for (HepInt i=0; i<97; ++i)
00100 inFile >> u[i];
00101 inFile >> c; inFile >> cd; inFile >> cm;
00102 inFile >> jpos;
00103 ipos = (64+jpos)%97;
00104 pi97 = &u[ipos];
00105 pj97 = &u[jpos];
00106 }
00107 }
00108
00109 void HepJamesRandom::showStatus() const
00110 {
00111 cout << endl;
00112 cout << "----- HepJamesRandom engine status -----" << endl;
00113 cout << " Initial seed = " << theSeed << endl;
00114 cout << " u[] = ";
00115 for (HepInt i=0; i<97; ++i)
00116 cout << u[i] << " ";
00117 cout << endl;
00118 cout << " c = " << c << ", cd = " << cd << ", cm = " << cm << endl;
00119 cout << " pi97 = " << pi97 << ", *pi97 = " << *pi97 << endl;
00120 cout << " pj97 = " << pj97 << ", *pj97 = " << *pj97 << endl;
00121 cout << "----------------------------------------" << endl;
00122 }
00123
00124 void HepJamesRandom::setSeed(long seed, HepInt)
00125 {
00126
00127
00128 HepInt m, n;
00129 HepFloat s, t;
00130 long mm;
00131
00132 long ij = seed/30082;
00133 long kl = seed - 30082*ij;
00134 long i = (ij/177) % 177 + 2;
00135 long j = ij % 177 + 2;
00136 long k = (kl/169) % 178 + 1;
00137 long l = kl % 169;
00138
00139 theSeed = seed;
00140
00141 for ( n = 1 ; n < 98 ; n++ ) {
00142 s = 0.0;
00143 t = 0.5;
00144 for ( m = 1 ; m < 25 ; m++) {
00145 mm = ( ( (i*j) % 179 ) * k ) % 179;
00146 i = j;
00147 j = k;
00148 k = mm;
00149 l = ( 53 * l + 1 ) % 169;
00150 if ( (l*mm % 64 ) >= 32 )
00151 s += t;
00152 t *= 0.5;
00153 }
00154 u[n-1] = s;
00155 }
00156 c = 362436.0 / 16777216.0;
00157 cd = 7654321.0 / 16777216.0;
00158 cm = 16777213.0 / 16777216.0;
00159 pi97 = &u[96];
00160 pj97 = &u[32];
00161 }
00162
00163 void HepJamesRandom::setSeeds(const long* seeds, HepInt)
00164 {
00165 setSeed(seeds ? *seeds : 19780503, 0);
00166 theSeeds = seeds;
00167 }
00168
00169 HepDouble HepJamesRandom::flat()
00170 {
00171 register HepDouble uni;
00172
00173 do {
00174 uni = *pi97 - *pj97;
00175 if ( uni < 0.0 ) uni++;
00176 *pi97 = uni;
00177
00178 if (pi97 == u) pi97 += 96;
00179 else pi97--;
00180
00181 if (pj97 == u) pj97 += 96;
00182 else pj97--;
00183
00184 c -= cd;
00185 if (c < 0.0) c += cm;
00186
00187 uni -= c;
00188 if (uni < 0.0) uni += 1.0;
00189 } while ( uni <= 0.0 || uni >= 1.0 );
00190
00191 return uni;
00192 }
00193
00194 void HepJamesRandom::flatArray(const HepInt size, HepDouble* vect)
00195 {
00196 register HepDouble uni;
00197 register HepInt i;
00198
00199 for (i=0; i<size; ++i) {
00200 do {
00201 uni = *pi97 - *pj97;
00202 if ( uni < 0.0 ) uni++;
00203 *pi97 = uni;
00204
00205 if (pi97 == u) pi97 += 96;
00206 else pi97--;
00207
00208 if (pj97 == u) pj97 += 96;
00209 else pj97--;
00210
00211 c -= cd;
00212 if (c < 0.0) c += cm;
00213
00214 uni -= c;
00215 if (uni < 0.0) uni += 1.0;
00216 } while ( uni <= 0.0 || uni >= 1.0 );
00217 vect[i] = uni;
00218 }
00219 }
00220
00221 void
00222 #ifndef ST_NO_TEMPLATE_DEF_ARGS
00223 HepJamesRandom::flatArray(vector<HepDouble>& vec)
00224 #else
00225 HepJamesRandom::flatArray(vector<HepDouble,allocator<HepDouble> >& vec)
00226 #endif
00227 {
00228 HepDouble uni;
00229
00230 for (unsigned int i=0; i<vec.size(); ++i) {
00231 do {
00232 uni = *pi97 - *pj97;
00233 if ( uni < 0.0 ) uni++;
00234 *pi97 = uni;
00235
00236 if (pi97 == u) pi97 += 96;
00237 else pi97--;
00238
00239 if (pj97 == u) pj97 += 96;
00240 else pj97--;
00241
00242 c -= cd;
00243 if (c < 0.0) c += cm;
00244
00245 uni -= c;
00246 if (uni < 0.0) uni += 1.0;
00247 } while ( uni <= 0.0 || uni >= 1.0 );
00248 vec[i] = uni;
00249 }
00250 }