00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "generators/MJGeneratorPNNLLookup.hh"
00013 #include <iostream.h>
00014 #include <fstream.h>
00015 #include <stdlib.h>
00016
00017 const G4int MJGeneratorPNNLLookup::kTYPE_INTERPOLATED_LOOKUP = 0;
00018 const G4int MJGeneratorPNNLLookup::kTYPE_DISCRETE_LOOKUP = 1;
00019
00020
00022 MJGeneratorPNNLLookup::
00023 MJGeneratorPNNLLookup(G4int num_entries, G4double* x_arr, G4double* f_arr)
00024 {
00025
00026
00027
00028
00029
00030
00031
00032 fType = kTYPE_INTERPOLATED_LOOKUP;
00033
00034 f_pX_table = NULL;
00035 f_pDist_table = NULL;
00036 f_pSum_table = NULL;
00037
00038 DoCreateTable(num_entries, x_arr, f_arr);
00039 }
00040
00042 MJGeneratorPNNLLookup::
00043 MJGeneratorPNNLLookup(G4int num_entries, G4double* f_arr)
00044 {
00045
00046
00047
00048
00049
00050 fType = kTYPE_DISCRETE_LOOKUP;
00051
00052 f_pX_table = NULL;
00053 f_pDist_table = NULL;
00054 f_pSum_table = NULL;
00055
00056 DoCreateTable(num_entries, f_arr);
00057 }
00058
00060 MJGeneratorPNNLLookup::
00061 ~MJGeneratorPNNLLookup()
00062 {
00063
00064 if (f_pX_table)
00065 delete [] f_pX_table;
00066 if (f_pDist_table)
00067 delete [] f_pDist_table;
00068 if (f_pSum_table)
00069 delete [] f_pSum_table;
00070 }
00071
00073 MJGeneratorPNNLLookup::
00074 MJGeneratorPNNLLookup(const MJGeneratorPNNLLookup &Lookup)
00075 {
00076 fType = Lookup.fType;
00077 fNum_entries = Lookup.fNum_entries;
00078 f_pX_table = NULL;
00079 f_pDist_table = NULL;
00080 f_pSum_table = NULL;
00081
00082 if (fType == kTYPE_INTERPOLATED_LOOKUP) {
00083 f_pX_table = new G4double[fNum_entries];
00084 f_pDist_table = new G4double[fNum_entries];
00085 f_pSum_table = new G4double[fNum_entries];
00086
00087 for (G4int i=0; i<fNum_entries; i++) {
00088 f_pX_table[i] = Lookup.f_pX_table[i];
00089 f_pDist_table[i] = Lookup.f_pDist_table[i];
00090 f_pSum_table[i] = Lookup.f_pSum_table[i];
00091 }
00092 }
00093 else {
00094 f_pDist_table = new G4double[fNum_entries];
00095 f_pSum_table = new G4double[fNum_entries+1];
00096
00097 for (G4int i=0; i<fNum_entries; i++) {
00098 f_pDist_table[i] = Lookup.f_pDist_table[i];
00099 f_pSum_table[i] = Lookup.f_pSum_table[i];
00100 }
00101 f_pSum_table[fNum_entries] = Lookup.f_pSum_table[fNum_entries];
00102 }
00103 }
00104
00106 void MJGeneratorPNNLLookup::
00107 operator=(const MJGeneratorPNNLLookup& Lookup)
00108 {
00109 fType = Lookup.fType;
00110 fNum_entries = Lookup.fNum_entries;
00111 f_pX_table = NULL;
00112 f_pDist_table = NULL;
00113 f_pSum_table = NULL;
00114
00115 if (fType == kTYPE_INTERPOLATED_LOOKUP) {
00116 f_pX_table = new G4double[fNum_entries];
00117 f_pDist_table = new G4double[fNum_entries];
00118 f_pSum_table = new G4double[fNum_entries];
00119
00120 for (G4int i=0; i<fNum_entries; i++) {
00121 f_pX_table[i] = Lookup.f_pX_table[i];
00122 f_pDist_table[i] = Lookup.f_pDist_table[i];
00123 f_pSum_table[i] = Lookup.f_pSum_table[i];
00124 }
00125 }
00126 else {
00127 f_pDist_table = new G4double[fNum_entries];
00128 f_pSum_table = new G4double[fNum_entries+1];
00129
00130 for (G4int i=0; i<fNum_entries; i++) {
00131 f_pDist_table[i] = Lookup.f_pDist_table[i];
00132 f_pSum_table[i] = Lookup.f_pSum_table[i];
00133 }
00134 f_pSum_table[fNum_entries] = Lookup.f_pSum_table[fNum_entries];
00135 }
00136 }
00137
00139 void MJGeneratorPNNLLookup::
00140 DoCreateTable(G4int num_entries, G4double* x_arr, G4double* f_arr)
00141 {
00142
00143
00144
00145 if (num_entries <= 0) {
00146 cout << "Error in MJGeneratorPNNLLookup::CreateTable" << endl;
00147 cout << "CANNOT CREATE TABLE WITH NUM_ENTRIES <=0" << endl;
00148 cout << "num_entries = " << num_entries << endl;
00149 cout << "Aborting." << endl;
00150 exit(1);
00151 }
00152
00153 fNum_entries = num_entries;
00154
00155 if (f_pX_table)
00156 delete [] f_pX_table;
00157 if (f_pDist_table)
00158 delete [] f_pDist_table;
00159 if (f_pSum_table)
00160 delete [] f_pSum_table;
00161
00162 f_pX_table = new G4double[fNum_entries];
00163 f_pDist_table = new G4double[fNum_entries];
00164 f_pSum_table = new G4double[fNum_entries];
00165
00166 G4int i, j;
00167
00168 for (i=0; i<fNum_entries; i++) {
00169 f_pX_table[i] = x_arr[i];
00170 f_pDist_table[i] = f_arr[i];
00171 }
00172
00173 f_pSum_table[0] = 0.0;
00174
00175 G4double Sum = 0.0;
00176 G4double dx, Avg;
00177
00178 for (i=1; i<fNum_entries; i++) {
00179 j = i-1;
00180 Avg = (f_arr[i] + f_arr[j])*0.5;
00181 dx = x_arr[i] - x_arr[j];
00182 Sum += dx * Avg;
00183 f_pSum_table[i] = Sum;
00184 }
00185
00186 for (i=0; i<num_entries; i++)
00187 f_pSum_table[i] /= Sum;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 }
00202
00204 void MJGeneratorPNNLLookup::
00205 DoCreateTable(G4int num_entries, G4double* f_arr) {
00206
00207
00208
00209 if (num_entries <= 0) {
00210 cout << "Error in MJGeneratorPNNLLookup::CreateTable" << endl;
00211 cout << "CANNOT CREATE TABLE WITH NUM_ENTRIES <=0" << endl;
00212 cout << "num_entries = " << num_entries << endl;
00213 cout << "Aborting." << endl;
00214 exit(1);
00215 }
00216
00217 fNum_entries = num_entries;
00218
00219 if (f_pDist_table)
00220 delete [] f_pDist_table;
00221 if (f_pSum_table)
00222 delete [] f_pSum_table;
00223
00224 f_pDist_table = new G4double[fNum_entries];
00225 f_pSum_table = new G4double[fNum_entries+1];
00226
00227 G4int i;
00228
00229 for (i=0; i<fNum_entries; i++) {
00230 f_pDist_table[i] = f_arr[i];
00231 }
00232
00233 f_pSum_table[0] = 0.0;
00234
00235 G4double Sum = 0.0;
00236
00237 f_pSum_table[0] = 0.0;
00238
00239 for (i=0; i<fNum_entries; i++) {
00240 Sum += f_pDist_table[i];
00241 f_pSum_table[i+1] = Sum;
00242 }
00243
00244 for (i=1; i<fNum_entries+1; i++)
00245 f_pSum_table[i] /= Sum;
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 }
00260
00262 G4double MJGeneratorPNNLLookup::
00263 DoLookupInterp(G4double x_rnd)
00264 {
00265
00266 G4int indx = Locate(x_rnd);
00267
00268
00269
00270 G4double Xtab[2];
00271 G4double Sum[2];
00272
00273 Xtab[0] = f_pX_table[indx];
00274 Xtab[1] = f_pX_table[indx+1];
00275 Sum[0] = f_pSum_table[indx];
00276 Sum[1] = f_pSum_table[indx+1];
00277
00278 G4double dX_dSum = (Xtab[1] - Xtab[0])/(Sum[1] - Sum[0]);
00279
00280 G4double x_interp = Xtab[0] + (x_rnd - Sum[0])*dX_dSum;
00281
00282 return x_interp;
00283
00284 }
00286 G4int MJGeneratorPNNLLookup::
00287 DoLookupDiscrete(G4double x_rnd)
00288 {
00289
00290 G4int indx = Locate(x_rnd);
00291
00292 return indx;
00293
00294 }
00295
00297 G4int MJGeneratorPNNLLookup::
00298 Locate(G4double x)
00299 {
00300
00301
00302
00303
00304 G4int nmax;
00305
00306 if (fType == kTYPE_INTERPOLATED_LOOKUP)
00307 nmax = fNum_entries;
00308 else
00309 nmax = fNum_entries + 1;
00310
00311 G4int JL = 0;
00312 G4int JU = nmax + 1;
00313 G4int JM;
00314
00315 G4bool b1 = f_pSum_table[nmax-1] > f_pSum_table[0];
00316 G4bool b2;
00317
00318 while ((JU-JL) > 1) {
00319 JM = (JU + JL)/2;
00320 b2 = x > f_pSum_table[JM-1];
00321 if (b1 == b2)
00322 JL = JM;
00323 else
00324 JU = JM;
00325 }
00326
00327 return JL-1;
00328 }