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 #include "ocsRanNumGen.hh"
00031
00032 extern ofstream LogFile;
00033
00034
00035
00064 RanNumGen::RanNumGen(string InFileName)
00065 {
00066
00067 ifstream InFile(InFileName.c_str(),ios::in);
00068
00069 if (!InFile)
00070 {
00071 cerr << "Error: Input file "<< InFileName
00072 << " could not be opened."<< endl;
00073 exit(1);
00074 }
00075
00076
00077 LogFileSeparator();
00078 LogFile << InFileName << endl;
00079
00080 ContinuationFileName = InFileName + ".continue";
00081 RestartFileName = InFileName + ".restart";
00082
00083 int OperationMode = ReadInt("OperationMode"," ",1,3,LOWER_AND_UPPER,&InFile);
00084
00085 switch(OperationMode)
00086 {
00087
00088 case 1:
00089
00090 LogFile << "Initializing RanNumGen using seed provided in "
00091 << InFileName << endl;
00092
00093 idum = ReadLongInt("Seed"," ",1,-1,LOWER_ONLY,&InFile);
00094 idum2=123456789;
00095 iy=0;
00096
00097 idum = -idum;
00098
00099 WriteRanSeqParameters(RestartFileName);
00100
00101
00102
00103 break;
00104
00105 case 2:
00106
00107
00108
00109 LogFile << "Continuing along random sequence using parameters in "
00110 << ContinuationFileName << endl;
00111
00112 ReadRanSeqParameters(ContinuationFileName);
00113 WriteRanSeqParameters(RestartFileName);
00114
00115 break;
00116
00117 case 3:
00118
00119
00120
00121 LogFile << "Restarting random sequence using parameters in "
00122 << RestartFileName << endl;
00123
00124 ReadRanSeqParameters(RestartFileName);
00125
00126 break;
00127
00128 default:
00129
00130 LogFile << "Invalid choice of OperationMode" << endl
00131 << "ABORTING NOW!!" << endl;
00132
00133 exit(1);
00134
00135
00136 }
00137
00138
00139
00140
00141 SaveCurrentState();
00142
00143 }
00144
00145
00146
00147 RanNumGen::~RanNumGen()
00148 {
00149 WriteRanSeqParameters(ContinuationFileName);
00150 }
00151
00152
00153
00154 void RanNumGen::SaveCurrentState(void)
00155 {
00156
00157 idumStart = idum;
00158 idum2Start = idum2;
00159 iyStart = iy;
00160 for(int ii=0;ii<NTAB;ii++)
00161 ivStart[ii]= iv[ii];
00162
00163 }
00164
00165
00166
00167 float RanNumGen::GetRanNum(void)
00168 {
00169
00170
00171
00172 int j;
00173 long k;
00174 float temp;
00175
00176
00177 if(idum <= 0)
00178 {
00179 if (-idum < 1)
00180 idum=1;
00181 else
00182 idum = -idum;
00183
00184
00185 idum2=idum;
00186
00187
00188 for(j=NTAB+7;j>=0;j--)
00189 {
00190 k=idum/IQ1;
00191 idum=IA1*(idum-k*IQ1)-k*IR1;
00192
00193 if (idum < 0)
00194 idum += IM1;
00195
00196 if (j < NTAB)
00197 iv[j] = idum;
00198
00199 }
00200
00201
00202 iy=iv[0];
00203
00204 }
00205
00206
00207 k=(idum)/IQ1;
00208 idum=IA1*(idum-k*IQ1)-k*IR1;
00209
00210 if (idum < 0)
00211 idum += IM1;
00212
00213 k=idum2/IQ2;
00214 idum2=IA2*(idum2-k*IQ2)-k*IR2;
00215
00216 if (idum2 < 0)
00217 idum2 += IM2;
00218
00219 j=iy/NDIV;
00220 iy=iv[j]-idum2;
00221 iv[j] = idum;
00222
00223 if (iy < 1)
00224 iy += IMM1;
00225
00226 if ((temp=AM*iy) > RNMX)
00227 return RNMX;
00228 else return temp;
00229
00230
00231 }
00232
00233
00234
00235
00236 float RanNumGen::GetGaussianDeviate(void)
00237 {
00238
00239
00240
00241
00242 static int iset=0;
00243 static float gset;
00244 float fac,rsq,v1,v2;
00245
00246 if(iset == 0)
00247 {
00248 do {
00249 v1=2.0*GetRanNum()-1.0;
00250 v2=2.0*GetRanNum()-1.0;
00251 rsq=v1*v1+v2*v2;
00252
00253 } while (rsq >= 1.0 || rsq == 0.0);
00254
00255 fac=sqrt(-2.0*log(rsq)/rsq);
00256 gset=v1*fac;
00257 iset=1;
00258 return v2*fac;
00259 }
00260
00261 else
00262 {
00263 iset=0;
00264 return gset;
00265 }
00266
00267 }
00268
00269
00270
00271 void RanNumGen::ReadRanSeqParameters(string InFileName)
00272 {
00273
00274 ifstream InFile(InFileName.c_str(),ios::in);
00275
00276 if (!InFile)
00277 {
00278
00279
00280
00281
00282 idum = -1;
00283 WriteRanSeqParameters(InFileName);
00284 InFile.open(InFileName.c_str(),ios::in);
00285
00286 if (!InFile)
00287 {
00288 LogFile << "ERROR in RanNumGen::ReadRanSeqParameters" << exit
00289 << "ABORTING NOW!";
00290 exit(1);
00291 }
00292 }
00293
00294 InFile >> idum
00295 >> idum2
00296 >> iy;
00297
00298 for(int i=0;i<NTAB;i++)
00299 InFile >> iv[i];
00300
00301 }
00302
00303
00304
00305 void RanNumGen::WriteRanSeqParameters(string OutFileName)
00306 {
00307
00308 ofstream OutFile(OutFileName.c_str(),ios::out);
00309
00310 if (!OutFile)
00311 {
00312 cerr << "Error: " <<OutFileName << " could not be opened."
00313 << endl << flush;
00314 exit(1);
00315 }
00316
00317 OutFile << idum << endl
00318 << idum2 << endl
00319 << iy << endl;
00320
00321 for(int i=0;i<NTAB;i++)
00322 OutFile << iv[i] << endl;
00323
00324
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void RanNumGen::ResetRanNumGen(void)
00336 {
00337 idum = idumStart;
00338 idum2 = idum2Start;
00339 iy = iyStart;
00340 for(int ii=0;ii<NTAB;ii++)
00341 iv[ii]= ivStart[ii];
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 float RanNumGen::GetRanCosineBiased(double alpha,
00368 double *LikelihoodRatio)
00369 {
00370
00371
00372
00373
00374 double ValFunction;
00375 double Z = GetRanNum();
00376
00377
00378
00379 if ( abs(alpha) < 1e-5 )
00380 {
00381
00382 alpha = 1e-5;
00383 }
00384
00385
00386
00387
00388 ValFunction = 1 + 1./alpha * log( exp(-2*alpha)+Z*(1-exp(-2*alpha) ) );
00389
00390
00391 *LikelihoodRatio *= (1-exp(-2*alpha) )/(2*alpha)
00392 *( exp(alpha*(1 - ValFunction)));
00393
00394 return ValFunction;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404 float RanNumGen::GetRanSignBiased(double alpha,
00405 double *LikelihoodRatio)
00406 {
00407
00408
00409
00410
00411 double Z = GetRanNum();
00412 double RandomSign;
00413 double cdfcAtZero;
00414
00415
00416 if ( abs(alpha) < 1e-5 ) {
00417
00418 alpha = 1e-5;
00419 }
00420
00421
00422
00423 RandomSign = sgn( 1 + 1./alpha * log( exp(-2*alpha)
00424 +Z*(1-exp(-2*alpha) ) ) );
00425
00426 cdfcAtZero = ( exp(-alpha)-exp(-2*alpha) )/(1-exp(-2*alpha));
00427
00428
00429
00430 if (RandomSign == -1) {
00431 *LikelihoodRatio *= 0.5/cdfcAtZero;
00432 }
00433 else if (RandomSign == 1) {
00434 *LikelihoodRatio *= 0.5/(1. - cdfcAtZero);
00435 }
00436 else {
00437 cout << "Error: From RanNumGen::GetRanSignBiased()" << endl
00438 << "The sgn(.) function got a serios problem" << endl;
00439 exit(1);
00440 }
00441
00442
00443
00444
00445
00446 return RandomSign;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 float RanNumGen::GetRanCosineBiased(double alpha, double beta,
00465 double *LikelihoodRatio)
00466 {
00467
00468
00469
00470
00471
00472
00473
00474 double ValFunction;
00475 double Z = GetRanNum();
00476 double W = GetRanNum();
00477
00478
00479 if ( abs(alpha) < 1e-5 ) {
00480
00481 alpha = 1e-5;
00482 }
00483
00484
00485 if (beta < -1) {
00486 beta = -1;
00487 }
00488 else if (beta > 1) {
00489 beta = 1;
00490 }
00491
00492
00493 if (W < (1-exp(-alpha*(1+beta)))
00494 /(2-exp(-alpha*(1+beta))-exp(-alpha*(1-beta)) ) ) {
00495
00496 ValFunction = beta + 1./alpha * log( exp(-alpha*(1+beta))
00497 +Z*(1-exp(-alpha*(1+beta)) ) );
00498 }
00499 else {
00500
00501 ValFunction = beta - 1./alpha * log( 1
00502 -Z*(1-exp(-alpha*(1-beta)) ) );
00503 }
00504
00505 *LikelihoodRatio *= 1./(2*alpha)
00506 *(2-exp(-alpha*(1+beta))-exp(-alpha*(1-beta)) )
00507 *( exp(alpha*abs(ValFunction - beta)));
00508
00509 return ValFunction;
00510 }
00511