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 #include "DRand48Engine.h"
00032
00033 #ifdef WIN32
00034
00035
00036
00037 # include <limits.h>
00038 # include <sys/types.h>
00039 # include <wtypes.h>
00040 # include <string.h>
00041
00042
00043 struct drand48_data libc_drand48_data;
00044
00045 int drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer)
00046 {
00047 ULONGLONG X, a, result;
00048
00049
00050 if (!buffer->init)
00051 {
00052 #if (USHRT_MAX == 0xffffU)
00053 buffer->a[2] = 0x5;
00054 buffer->a[1] = 0xdeec;
00055 buffer->a[0] = 0xe66d;
00056 #else
00057 buffer->a[2] = 0x5deecUL;
00058 buffer->a[1] = 0xe66d0000UL;
00059 buffer->a[0] = 0;
00060 #endif
00061 buffer->c = 0xb;
00062 buffer->init = 1;
00063 }
00064
00065
00066
00067
00068
00069 if (sizeof (unsigned short int) == 2)
00070 {
00071 X = (ULONGLONG)xsubi[2] << 32 | (ULONGLONG)xsubi[1] << 16 | xsubi[0];
00072 a = ((ULONGLONG)buffer->a[2] << 32 | (ULONGLONG)buffer->a[1] << 16
00073 | buffer->a[0]);
00074
00075 result = X * a + buffer->c;
00076
00077 xsubi[0] = (unsigned short int) (result & 0xffff);
00078 xsubi[1] = (unsigned short int) ((result >> 16) & 0xffff);
00079 xsubi[2] = (unsigned short int) ((result >> 32) & 0xffff);
00080 }
00081 else
00082 {
00083 X = (ULONGLONG)xsubi[2] << 16 | xsubi[1] >> 16;
00084 a = (ULONGLONG)buffer->a[2] << 16 | buffer->a[1] >> 16;
00085
00086 result = X * a + buffer->c;
00087
00088 xsubi[0] = (unsigned short int) (result >> 16 & 0xffffffffl);
00089 xsubi[1] = (unsigned short int) (result << 16 & 0xffff0000l);
00090 }
00091
00092 return 0;
00093 }
00094
00095 int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer)
00096 {
00097
00098 memcpy (buffer->old_X, buffer->X, sizeof (buffer->X));
00099
00100
00101 memcpy (buffer->X, seed16v, sizeof (buffer->X));
00102
00103 return 0;
00104 }
00105
00106 unsigned short int * seed48 (unsigned short int seed16v[3])
00107 {
00108 (void) seed48_r (seed16v, &libc_drand48_data);
00109
00110 return libc_drand48_data.old_X;
00111 }
00112
00113 int srand48_r (long seedval, struct drand48_data *buffer)
00114 {
00115
00116 if (sizeof (long) > 4)
00117 seedval &= 0xffffffffl;
00118
00119 #if (USHRT_MAX == 0xffffU)
00120 buffer->X[2] = (unsigned short int) (seedval >> 16);
00121 buffer->X[1] = (unsigned short int) (seedval & 0xffffl);
00122 buffer->X[0] = 0x330e;
00123 #else
00124 buffer->X[2] = seedval;
00125 buffer->X[1] = 0x330e0000UL;
00126 buffer->X[0] = 0;
00127 #endif
00128
00129 return 0;
00130 }
00131
00132 void srand48 (long seedval)
00133 {
00134 (void) srand48_r (seedval, &libc_drand48_data);
00135 }
00136
00137 int erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result)
00138 {
00139
00140 if (drand48_iterate (xsubi, buffer) < 0)
00141 return -1;
00142
00143
00144
00145
00146 #if USHRT_MAX == 65535
00147 *result = ((double) xsubi[2] / ((ULONGLONG)1 << 48) +
00148 (double) xsubi[1] / ((ULONGLONG)1 << 32) +
00149 (double) xsubi[0] / ((ULONGLONG)1 << 16));
00150 #else
00151 # error Unsupported size of short int
00152 #endif
00153
00154 return 0;
00155 }
00156
00157 double drand48 ()
00158 {
00159 double result;
00160
00161 (void) erand48_r (libc_drand48_data.X, &libc_drand48_data, &result);
00162
00163 return result;
00164 }
00165
00166
00167
00168 #endif
00169
00170 DRand48Engine::DRand48Engine(long seed)
00171 {
00172 setSeed(seed,0);
00173 setSeeds(&theSeed,0);
00174 }
00175
00176 DRand48Engine::~DRand48Engine() {}
00177
00178 DRand48Engine::DRand48Engine(const DRand48Engine &p)
00179 {
00180
00181
00182
00183
00184 if ((this != &p) && (&p)) {
00185 p.saveStatus();
00186 restoreStatus();
00187 setSeeds(&theSeed,0);
00188 }
00189 }
00190
00191 DRand48Engine & DRand48Engine::operator = (const DRand48Engine &p)
00192 {
00193
00194
00195
00196
00197 if ((this != &p) && (&p)) {
00198 p.saveStatus();
00199 restoreStatus();
00200 setSeeds(&theSeed,0);
00201 }
00202 return *this;
00203 }
00204
00205 void DRand48Engine::setSeed(long seed, HepInt)
00206 {
00207 srand48( seed );
00208 theSeed = seed;
00209 }
00210
00211 void DRand48Engine::setSeeds(const long* seeds, HepInt)
00212 {
00213 setSeed(seeds ? *seeds : 19780503, 0);
00214 theSeeds = seeds;
00215 }
00216
00217 void DRand48Engine::saveStatus() const
00218 {
00219 ofstream outFile("DRand48.conf", ios::out ) ;
00220
00221 unsigned short dummy[] = { 0, 0, 0 };
00222 unsigned short* cseed = seed48(dummy);
00223
00224 if (!outFile.bad()) {
00225 outFile << theSeed << endl;
00226 for (HepInt i=0; i<3; ++i) {
00227 outFile << cseed[i] << endl;
00228 dummy[i] = cseed[i];
00229 }
00230 seed48(dummy);
00231 }
00232 }
00233
00234 void DRand48Engine::restoreStatus()
00235 {
00236 ifstream inFile("DRand48.conf", ios::in);
00237 unsigned short cseed[3];
00238
00239 if (!inFile.bad() && !inFile.eof()) {
00240 inFile >> theSeed;
00241 for (HepInt i=0; i<3; ++i)
00242 inFile >> cseed[i];
00243 seed48(cseed);
00244 }
00245 }
00246
00247 void DRand48Engine::showStatus() const
00248 {
00249 unsigned short dummy[] = { 0, 0, 0 };
00250 unsigned short* cseed = seed48(dummy);
00251 cout << endl;
00252 cout << "-------- DRand48 engine status ---------" << endl;
00253 cout << " Initial seed = " << theSeed << endl;
00254 cout << " Current seeds = " << cseed[0] << ", ";
00255 cout << cseed[1] << ", ";
00256 cout << cseed[2] << endl;
00257 cout << "----------------------------------------" << endl;
00258 for (HepInt i=0; i<3; ++i)
00259 dummy[i] = cseed[i];
00260 seed48(dummy);
00261 }
00262
00263 HepDouble DRand48Engine::flat()
00264 {
00265 register HepDouble num = 0.;
00266
00267 while (num == 0.)
00268 num = drand48();
00269 return num;
00270 }
00271
00272 void DRand48Engine::flatArray(const HepInt size, HepDouble* vect)
00273 {
00274 register HepInt i;
00275
00276 for (i=0; i<size; ++i)
00277 vect[i]=flat();
00278 }
00279
00280 void
00281 #ifndef ST_NO_TEMPLATE_DEF_ARGS
00282 DRand48Engine::flatArray(vector<HepDouble>& vec)
00283 #else
00284 DRand48Engine::flatArray(vector<HepDouble,allocator<HepDouble> >& vec)
00285 #endif
00286 {
00287 for (unsigned int i=0; i<vec.size(); ++i)
00288 vec[i]=flat();
00289 }