Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MJGeneratorPNNLLookup.cc

Go to the documentation of this file.
00001 // This code implementation is the intellectual property of
00002 // the RD44 GEANT4 collaboration.
00003 //
00004 // By copying, distributing or modifying the Program (or any work
00005 // based on the Program) you indicate your acceptance of this statement,
00006 // and all its terms.
00007 //
00008 // $Id: MJGeneratorPNNLLookup.cc,v 1.2 2004/11/09 13:42:39 xliu Exp $
00009 // GEANT4 tag $Name:  $
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   // This constructor sets up an (x,probability)-type lookup table.  X-values
00027   // sampled from this lookup are interpolated on the table of X's.  Note:
00028   // the lookup table is set up to have the same number of entries as the
00029   // input distribution array.  (This is in contrast to the "discrete" lookup
00030   // table type.)
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   // This constructor sets up an integer-indexed, or discrete, lookup table.
00046   // The values sampled from this table type are integer indices  
00047   // 0, 1, 2, ..., num_entries-1.  The lookup table has num_entries+1 entries.
00048 
00049 
00050   fType = kTYPE_DISCRETE_LOOKUP;
00051 
00052   f_pX_table    = NULL;   // not used for this lookup table type
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 {  // kTYPE_DISCRETE_LOOKUP
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 {  // kTYPE_DISCRETE_LOOKUP
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   // This is the version of CreateTable for setting up an interpolated table.
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   cout << "MJGeneratorPNNLLookup: Created continuous-x lookup table from input arrays." 
00191        << endl;
00192   cout << "Number of table entries: " << fNum_entries << endl;
00193   cout << "First input (x,f) entry: " << x_arr[0] << " " << f_arr[0] << endl;
00194   cout << "Last  input (x,f) entry: " << x_arr[fNum_entries-1] << " "
00195                                       << f_arr[fNum_entries-1] << endl;
00196   cout << "First table (x,sum) entry: " << f_pX_table[0] << " " 
00197                                         << f_pSum_table[0] << endl;
00198   cout << "Last  table (x,sum) entry: " << f_pX_table[num_entries-1] << " " 
00199                                         << f_pSum_table[num_entries-1] << endl;
00200   */
00201 }
00202 
00204 void MJGeneratorPNNLLookup::
00205 DoCreateTable(G4int num_entries, G4double* f_arr) {
00206 
00207   // This version of DoCreateTable is for the discrete lookup table type.
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   cout << "MJGeneratorPNNLLookup: Created discrete-index lookup table from input arrays." << endl;
00249   cout << "Number of table entries: " << fNum_entries << endl;
00250   cout << "First input distribution table entry: " 
00251        << f_arr[0] << endl;
00252   cout << "Last  input distribution table entry: " 
00253        << f_arr[fNum_entries-1] << endl;
00254   cout << "First sum table entry: " 
00255        << f_pSum_table[0] << endl;
00256   cout << "Last sum table entry: " 
00257        << f_pSum_table[fNum_entries] << endl;
00258   */
00259 }
00260 
00262 G4double MJGeneratorPNNLLookup::
00263 DoLookupInterp(G4double x_rnd) 
00264 {
00265 
00266   G4int indx = Locate(x_rnd);
00267 
00268   //cout << "DoLookup: x_rnd= " << x_rnd << " indx = " << indx << endl;
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   // Adapted from Numerical Recipes routine LOCATE for searching of
00302   // monotonically-ordered table.
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 }

Generated on Mon Nov 29 16:58:51 2004 for Majorana Simulation by  doxygen 1.3.9.1