Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/HEPNumerics/src/G4DataInterpolation.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /global/HEPNumerics/src/G4DataInterpolation.cc (Version 11.3.0) and /global/HEPNumerics/src/G4DataInterpolation.cc (Version 5.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
 26 // G4DataInterpolation class implementation    << 
 27 //                                                 23 //
 28 // Author: V.Grichine, 03.04.1997              <<  24 // $Id: G4DataInterpolation.cc,v 1.4 2001/07/11 10:00:41 gunter Exp $
 29 // ------------------------------------------- <<  25 // GEANT4 tag $Name: geant4-05-01 $
 30                                                <<  26 //
 31 #include "G4DataInterpolation.hh"                  27 #include "G4DataInterpolation.hh"
 32                                                    28 
 33 ////////////////////////////////////////////// << 
 34 //                                             << 
 35 // Constructor for initializing of fArgument,  << 
 36 // data members                                << 
 37                                                    29 
 38 G4DataInterpolation::G4DataInterpolation(G4dou <<  30 // Constructor for initializing of fArgument, fFunction and fNumber data members
 39                                          G4int <<  31 
 40   : fArgument(new G4double[number])            <<  32 G4DataInterpolation::G4DataInterpolation( G4double pX[], 
 41   , fFunction(new G4double[number])            <<  33                                     G4double pY[], 
 42   , fNumber(number)                            <<  34                         G4int number    ):
                                                   >>  35   fSecondDerivative (0)
 43 {                                                  36 {
 44   for(G4int i = 0; i < fNumber; ++i)           <<  37    G4int i ;
 45   {                                            <<  38    fNumber = number ;
 46     fArgument[i] = pX[i];                      <<  39    fArgument = new G4double[fNumber] ;
 47     fFunction[i] = pY[i];                      <<  40    fFunction = new G4double[fNumber] ;
 48   }                                            <<  41    for(i=0;i<fNumber;i++)
 49 }                                              <<  42    {
                                                   >>  43       fArgument[i] = pX[i] ;
                                                   >>  44       fFunction[i] = pY[i] ;
                                                   >>  45    }
                                                   >>  46 } 
 50                                                    47 
 51 ////////////////////////////////////////////// <<  48 // Constructor for cubic spline interpolation. It creates the array 
 52 //                                             << 
 53 // Constructor for cubic spline interpolation. << 
 54 // fSecondDerivative[0,...fNumber-1] which is      49 // fSecondDerivative[0,...fNumber-1] which is used in this interpolation by
 55 // the function                                <<  50 // the function 
 56                                                    51 
 57 G4DataInterpolation::G4DataInterpolation(G4dou <<  52 
 58                                          G4int <<  53 G4DataInterpolation::G4DataInterpolation( G4double pX[], 
 59                                          G4dou <<  54                                     G4double pY[], 
 60   : fArgument(new G4double[number])            <<  55                         G4int number,
 61   , fFunction(new G4double[number])            <<  56                   G4double pFirstDerStart,
 62   , fSecondDerivative(new G4double[number])    <<  57                   G4double pFirstDerFinish  ) 
 63   , fNumber(number)                            << 
 64 {                                                  58 {
 65   G4int i    = 0;                              <<  59    G4int i, k ;
 66   G4double p = 0.0, qn = 0.0, sig = 0.0, un =  <<  60    G4double p, qn, sig, un ;
 67   const G4double maxDerivative = 0.99e30;      <<  61    const G4double maxDerivative = 0.99e30 ;
 68   auto u                  = new G4double[fNumb <<  62    fNumber = number ;
 69                                                <<  63    fArgument = new G4double[fNumber] ;
 70   for(i = 0; i < fNumber; ++i)                 <<  64    fFunction = new G4double[fNumber] ;
 71   {                                            <<  65    fSecondDerivative = new G4double[fNumber] ;
 72     fArgument[i] = pX[i];                      <<  66    G4double* u = new G4double[fNumber - 1] ;
 73     fFunction[i] = pY[i];                      <<  67 
 74   }                                            <<  68    for(i=0;i<fNumber;i++)
 75   if(pFirstDerStart > maxDerivative)           <<  69    {
 76   {                                            <<  70       fArgument[i] = pX[i] ;
 77     fSecondDerivative[0] = 0.0;                <<  71       fFunction[i] = pY[i] ;
 78     u[0]                 = 0.0;                <<  72    }
 79   }                                            <<  73    if(pFirstDerStart > maxDerivative)
 80   else                                         <<  74    {
 81   {                                            <<  75       fSecondDerivative[0] = 0.0 ;
 82     fSecondDerivative[0] = -0.5;               <<  76       u[0] = 0.0 ;
 83     u[0]                 = (3.0 / (fArgument[1 <<  77    }
 84            ((fFunction[1] - fFunction[0]) / (f <<  78    else
 85             pFirstDerStart);                   <<  79    {
 86   }                                            <<  80       fSecondDerivative[0] = -0.5 ;
 87                                                <<  81       u[0] = (3.0/(fArgument[1]-fArgument[0]))*
 88   // Decomposition loop for tridiagonal algori <<  82        ((fFunction[1]-fFunction[0])/(fArgument[1]-fArgument[0]) -
 89   // and u[i] are used for temporary storage o <<  83                                                              pFirstDerStart) ;
 90                                                <<  84    }
 91   for(i = 1; i < fNumber - 1; ++i)             <<  85    
 92   {                                            <<  86    // Decomposition loop for tridiagonal algorithm. fSecondDerivative[i] and u[i]
 93     sig =                                      <<  87    // are used for temporary storage of the decomposed factors.
 94       (fArgument[i] - fArgument[i - 1]) / (fAr <<  88    
 95     p                    = sig * fSecondDeriva <<  89    for(i=1;i<fNumber-1;i++)
 96     fSecondDerivative[i] = (sig - 1.0) / p;    <<  90    {
 97     u[i] =                                     <<  91       sig = (fArgument[i]-fArgument[i-1])/(fArgument[i+1]-fArgument[i-1]) ;
 98       (fFunction[i + 1] - fFunction[i]) / (fAr <<  92       p = sig*fSecondDerivative[i-1] + 2.0 ;
 99       (fFunction[i] - fFunction[i - 1]) / (fAr <<  93       fSecondDerivative[i] = (sig - 1.0)/p ;
100     u[i] =                                     <<  94       u[i] = (fFunction[i+1]-fFunction[i])/(fArgument[i+1]-fArgument[i]) -
101       (6.0 * u[i] / (fArgument[i + 1] - fArgum <<  95        (fFunction[i]-fFunction[i-1])/(fArgument[i]-fArgument[i-1]) ;
102   }                                            <<  96       u[i] =(6.0*u[i]/(fArgument[i+1]-fArgument[i-1]) - sig*u[i-1])/p ;
103   if(pFirstDerFinish > maxDerivative)          <<  97    }
104   {                                            <<  98    if(pFirstDerFinish > maxDerivative)
105     qn = 0.0;                                  <<  99    {
106     un = 0.0;                                  << 100       qn = 0.0 ;
107   }                                            << 101       un = 0.0 ;
108   else                                         << 102    }
109   {                                            << 103    else
110     qn = 0.5;                                  << 104    {
111     un =                                       << 105       qn = 0.5 ;
112       (3.0 / (fArgument[fNumber - 1] - fArgume << 106       un =(3.0/(fArgument[fNumber-1]-fArgument[fNumber-2]))*(pFirstDerFinish -
113       (pFirstDerFinish - (fFunction[fNumber -  << 107      (fFunction[fNumber-1]-fFunction[fNumber-2])/
114                            (fArgument[fNumber  << 108      (fArgument[fNumber-1]-fArgument[fNumber-2])) ;
115   }                                            << 109    }
116   fSecondDerivative[fNumber - 1] =             << 110    fSecondDerivative[fNumber-1] = (un - qn*u[fNumber-2])/
117     (un - qn * u[fNumber - 2]) / (qn * fSecond << 111                                   (qn*fSecondDerivative[fNumber-2] + 1.0) ;
118                                                << 112    
119   // The backsubstitution loop for the triagon << 113    // The backsubstitution loop for the triagonal algorithm of solving a linear
120   // a linear system of equations.             << 114    // system of equations.
121                                                << 115    
122   for(G4int k = fNumber - 2; k >= 0; --k)      << 116    for(k=fNumber-2;k>=0;k--)
123   {                                            << 117    {
124     fSecondDerivative[k] =                     << 118       fSecondDerivative[k] = fSecondDerivative[k]*fSecondDerivative[k+1] + u[k] ;
125       fSecondDerivative[k] * fSecondDerivative << 119    }
126   }                                            << 120    delete[] u ;
127   delete[] u;                                  << 121 } 
128 }                                              << 
129                                                   122 
130 ////////////////////////////////////////////// << 123 // ----------------------------------------------------------------------------
131 //                                                124 //
132 // Destructor deletes dynamically created arra    125 // Destructor deletes dynamically created arrays for data members: fArgument,
133 // fFunction and fSecondDerivative, all have d    126 // fFunction and fSecondDerivative, all have dimension of fNumber
134                                                << 127       
135 G4DataInterpolation::~G4DataInterpolation()       128 G4DataInterpolation::~G4DataInterpolation()
136 {                                                 129 {
137   delete[] fArgument;                          << 130    delete[] fArgument ;
138   delete[] fFunction;                          << 131    delete[] fFunction ;
139   delete[] fSecondDerivative;                  << 132    if(fSecondDerivative) delete[] fSecondDerivative ;
140 }                                                 133 }
141                                                   134 
142 ////////////////////////////////////////////// << 135 // ------------------------------------------------------------------------
143 //                                                136 //
144 // This function returns the value P(pX), wher << 137 // This function returns the value P(pX), where P(x) is polynom of fNumber-1 degree
145 // degree such that P(fArgument[i]) = fFunctio << 138 // such that P(fArgument[i]) = fFunction[i], for i = 0, ..., fNumber-1  . This is
146 // This is Lagrange's form of interpolation an << 139 // Lagrange's form of interpolation and it is based on Neville's algorithm
147 // algorithm                                   << 140 
148                                                << 141 G4double 
149 G4double G4DataInterpolation::PolynomInterpola << 142 G4DataInterpolation::PolynomInterpolation(G4double pX,
150                                                << 143                                     G4double& deltaY ) const
151 {                                                 144 {
152   G4int i = 0, j = 1, k = 0;                   << 145    G4int i, m, k = 0 ;
153   G4double mult = 0.0, difi = 0.0, deltaLow =  << 146    G4double mult, diff, difi, deltaLow, deltaUp, cd, y ;
154            y    = 0.0;                         << 147    G4double* c = new G4double[fNumber] ;
155   auto c   = new G4double[fNumber];            << 148    G4double* d = new G4double[fNumber] ;
156   auto d   = new G4double[fNumber];            << 149    diff = fabs(pX-fArgument[0]) ;
157   G4double diff = std::fabs(pX - fArgument[0]) << 150    for(i=1;i<fNumber;i++)
158   for(i = 0; i < fNumber; ++i)                 << 151    {
159   {                                            << 152       difi = fabs(pX-fArgument[i]) ;
160     difi = std::fabs(pX - fArgument[i]);       << 153       if(difi <diff)
161     if(difi < diff)                            << 154       {
162     {                                          << 155    k = i ;
163       k    = i;                                << 156    diff = difi ;
164       diff = difi;                             << 157       }
165     }                                          << 158       c[i] = fFunction[i] ;
166     c[i] = fFunction[i];                       << 159       d[i] = fFunction[i] ;   
167     d[i] = fFunction[i];                       << 160    }
168   }                                            << 161    y = fFunction[k--] ;     
169   y = fFunction[k--];                          << 162    for(m=1;m<fNumber;m++)
170   for(j = 1; j < fNumber; ++j)                 << 163    {
171   {                                            << 164       for(i=0;i<fNumber-m;i++)
172     for(i = 0; i < fNumber - j; ++i)           << 165       {
173     {                                          << 166    deltaLow = fArgument[i] - pX ;
174       deltaLow = fArgument[i] - pX;            << 167    deltaUp = fArgument[i+m] - pX ;
175       deltaUp  = fArgument[i + j] - pX;        << 168    cd = c[i+1] - d[i] ;
176       cd       = c[i + 1] - d[i];              << 169    mult = deltaLow - deltaUp ;
177       mult     = deltaLow - deltaUp;           << 170    if(mult == 0.0)
178       if(!(mult != 0.0))                       << 171    {
179       {                                        << 172       G4Exception
180         G4Exception("G4DataInterpolation::Poly << 173       ("Coincident nodes in G4DataInterpolation::PolynomInterpolation") ;
181                     FatalException, "Coinciden << 174    }
182       }                                        << 175    mult  = cd/mult ;
183       mult = cd / mult;                        << 176    d[i] = deltaUp*mult ;
184       d[i] = deltaUp * mult;                   << 177    c[i] = deltaLow*mult ;
185       c[i] = deltaLow * mult;                  << 178       }
186     }                                          << 179       y += (deltaY = (2*k < (fNumber - m -1) ? c[k+1] : d[k--] )) ;
187     y += (deltaY = (2 * k < (fNumber - j - 1)  << 180    }
188   }                                            << 181    delete[] c ;
189   delete[] c;                                  << 182    delete[] d ;
190   delete[] d;                                  << 183    
191                                                << 184    return y ;
192   return y;                                    << 
193 }                                                 185 }
194                                                   186 
195 ////////////////////////////////////////////// << 187 // -----------------------------------------------------------
196 //                                                188 //
197 // Given arrays fArgument[0,..,fNumber-1] and  << 189 // Given arrays fArgument[0,..,fNumber-1] and fFunction[0,..,fNumber-1] , this
198 // function calculates an array of coefficient    190 // function calculates an array of coefficients. The coefficients don't provide
199 // usually (fNumber>10) better accuracy for po << 191 // usually (fNumber>10) better accuracy for polynom interpolation, as compared with
200 // with PolynomInterpolation function. They co << 192 // PolynomInterpolation function. They could be used instead for derivate 
201 // calculations and some other applications.      193 // calculations and some other applications.
202                                                   194 
203 void G4DataInterpolation::PolIntCoefficient(G4 << 195 void 
                                                   >> 196 G4DataInterpolation::PolIntCoefficient( G4double cof[]) const 
204 {                                                 197 {
205   G4int i = 0, j = 0;                          << 198    G4int i, j ;
206   G4double factor;                             << 199    G4double factor, reducedY, mult ;
207   G4double reducedY = 0.0, mult = 1.0;         << 200    G4double* tempArgument = new G4double[fNumber] ;
208   auto tempArgument = new G4double[fNumber];   << 201    
209                                                << 202    for(i=0;i<fNumber;i++)
210   for(i = 0; i < fNumber; ++i)                 << 203    {
211   {                                            << 204       tempArgument[i] = cof[i] = 0.0 ;
212     tempArgument[i] = cof[i] = 0.0;            << 205    }
213   }                                            << 206    tempArgument[fNumber-1] = -fArgument[0] ;
214   tempArgument[fNumber - 1] = -fArgument[0];   << 207    
215                                                << 208    for(i=1;i<fNumber;i++)
216   for(i = 1; i < fNumber; ++i)                 << 209    {
217   {                                            << 210       for(j=fNumber-1-i;j<fNumber-1;j++)
218     for(j = fNumber - 1 - i; j < fNumber - 1;  << 211       {
219     {                                          << 212    tempArgument[j] -= fArgument[i]*tempArgument[j+1] ;
220       tempArgument[j] -= fArgument[i] * tempAr << 213       }
221     }                                          << 214       tempArgument[fNumber-1] -= fArgument[i] ;
222     tempArgument[fNumber - 1] -= fArgument[i]; << 215    }
223   }                                            << 216    for(i=0;i<fNumber;i++)
224   for(i = 0; i < fNumber; ++i)                 << 217    {
225   {                                            << 218       factor = fNumber ;
226     factor = fNumber;                          << 219       for(j=fNumber-1;j>=1;j--)
227     for(j = fNumber - 1; j >= 1; --j)          << 220       {
228     {                                          << 221    factor = j*tempArgument[j] + factor*fArgument[i] ;
229       factor = j * tempArgument[j] + factor *  << 222       }
230     }                                          << 223       reducedY = fFunction[i]/factor ;
231     reducedY = fFunction[i] / factor;          << 224       mult = 1.0 ;
232     mult     = 1.0;                            << 225       for(j=fNumber-1;j>=0;j--)
233     for(j = fNumber - 1; j >= 0; --j)          << 226       {
234     {                                          << 227    cof[j] += mult*reducedY ;
235       cof[j] += mult * reducedY;               << 228    mult = tempArgument[j] + mult*fArgument[i] ;
236       mult = tempArgument[j] + mult * fArgumen << 229       }
237     }                                          << 230    }
238   }                                            << 231    delete[] tempArgument ;
239   delete[] tempArgument;                       << 
240 }                                                 232 }
241                                                   233 
242 ////////////////////////////////////////////// << 
243 //                                             << 
244 // The function returns diagonal rational func << 
245 // algorithm of Neville type) Pn(x)/Qm(x) wher << 
246 // Tests showed the method is not stable and h << 
247 // with polynomial interpolation ?!            << 
248                                                   234 
249 G4double G4DataInterpolation::RationalPolInter << 
250                                                << 
251 {                                              << 
252   G4int i = 0, j = 1, k = 0;                   << 
253   const G4double tolerance = 1.6e-24;          << 
254   G4double mult = 0.0, difi = 0.0, cd = 0.0, y << 
255   auto c   = new G4double[fNumber];            << 
256   auto d   = new G4double[fNumber];            << 
257   G4double diff = std::fabs(pX - fArgument[0]) << 
258   for(i = 0; i < fNumber; ++i)                 << 
259   {                                            << 
260     difi = std::fabs(pX - fArgument[i]);       << 
261     if(!(difi != 0.0))                         << 
262     {                                          << 
263       y      = fFunction[i];                   << 
264       deltaY = 0.0;                            << 
265       delete[] c;                              << 
266       delete[] d;                              << 
267       return y;                                << 
268     }                                          << 
269     if(difi < diff)                            << 
270     {                                          << 
271       k    = i;                                << 
272       diff = difi;                             << 
273     }                                          << 
274     c[i] = fFunction[i];                       << 
275     d[i] = fFunction[i] + tolerance;  // to pr << 
276   }                                            << 
277   y = fFunction[k--];                          << 
278   for(j = 1; j < fNumber; ++j)                 << 
279   {                                            << 
280     for(i = 0; i < fNumber - j; ++i)           << 
281     {                                          << 
282       cd   = c[i + 1] - d[i];                  << 
283       difi = fArgument[i + j] - pX;            << 
284       cof  = (fArgument[i] - pX) * d[i] / difi << 
285       mult = cof - c[i + 1];                   << 
286       if(!(mult != 0.0))  // function to be in << 
287       {                                        << 
288         G4Exception("G4DataInterpolation::Rati << 
289                     FatalException, "Coinciden << 
290       }                                        << 
291       mult = cd / mult;                        << 
292       d[i] = c[i + 1] * mult;                  << 
293       c[i] = cof * mult;                       << 
294     }                                          << 
295     y += (deltaY = (2 * k < (fNumber - j - 1)  << 
296   }                                            << 
297   delete[] c;                                  << 
298   delete[] d;                                  << 
299                                                   235 
300   return y;                                    << 236 // ----------------------------------------------------------------
301 }                                              << 
302                                                   237 
303 ////////////////////////////////////////////// << 238 // The function returns diagonal rational function (Bulirsch and Stoer algorithm
304 //                                             << 239 // of Neville type) Pn(x)/Qm(x) where P and Q are polynoms.
305 // Cubic spline interpolation in point pX for  << 240 // Tests showed the method is not stable and hasn't advantage if compared with
306 // fArgument, fFunction. The constructor, whic << 241 // polynomial interpolation ?!
307 // must be called before. The function works o << 
308 // are in random values of pX.                 << 
309                                                   242 
310 G4double G4DataInterpolation::CubicSplineInter << 243 
                                                   >> 244 G4double
                                                   >> 245 G4DataInterpolation::RationalPolInterpolation(G4double pX,
                                                   >> 246                                         G4double& deltaY ) const 
311 {                                                 247 {
312   G4int kLow = 0, kHigh = fNumber - 1, k = 0;  << 248    G4int i, m, k = 0 ;
                                                   >> 249    const G4double tolerance = 1.6e-24 ;
                                                   >> 250    G4double mult, difi, diff, cd, y, cof ;
                                                   >> 251    G4double* c = new G4double[fNumber] ;
                                                   >> 252    G4double* d = new G4double[fNumber] ;
                                                   >> 253    diff = fabs(pX-fArgument[0]) ;
                                                   >> 254    for(i=0;i<fNumber;i++)
                                                   >> 255    {
                                                   >> 256       difi = fabs(pX-fArgument[i]) ;
                                                   >> 257       if(difi == 0.0)
                                                   >> 258       {
                                                   >> 259    y = fFunction[i] ;
                                                   >> 260    deltaY = 0.0 ;
                                                   >> 261          delete[] c ;
                                                   >> 262          delete[] d ;
                                                   >> 263    return y ;
                                                   >> 264       }
                                                   >> 265       else if(difi < diff)
                                                   >> 266       {
                                                   >> 267    k = i ;
                                                   >> 268    diff = difi ;
                                                   >> 269       }
                                                   >> 270       c[i] = fFunction[i] ;
                                                   >> 271       d[i] = fFunction[i] + tolerance ;   // to prevent rare zero/zero cases
                                                   >> 272    }
                                                   >> 273    y = fFunction[k--] ;    
                                                   >> 274    for(m=1;m<fNumber;m++)
                                                   >> 275    {
                                                   >> 276       for(i=0;i<fNumber-m;i++)
                                                   >> 277       {
                                                   >> 278    cd  = c[i+1] - d[i] ;
                                                   >> 279    difi  = fArgument[i+m] - pX ;
                                                   >> 280    cof  = (fArgument[i] - pX)*d[i]/difi ;
                                                   >> 281    mult = cof - c[i+1] ;
                                                   >> 282    if(mult == 0.0)    // function to be interpolated has pole at pX
                                                   >> 283    {
                                                   >> 284       G4Exception("Error in G4DataInterpolation::RationalPolInterpolation") ;
                                                   >> 285    }
                                                   >> 286    mult  = cd/mult ;
                                                   >> 287    d[i] = c[i+1]*mult ;
                                                   >> 288    c[i] = cof*mult ;
                                                   >> 289       }
                                                   >> 290       y += (deltaY = (2*k < (fNumber - m - 1) ? c[k+1] : d[k--] )) ;
                                                   >> 291    }
                                                   >> 292    delete[] c ;
                                                   >> 293    delete[] d ;
                                                   >> 294    
                                                   >> 295    return y ;
                                                   >> 296 }
                                                   >> 297 
                                                   >> 298 // --------------------------------------------------------------------------
313                                                   299 
314   // Searching in the table by means of bisect << 300 // Cubic spline interpolation in point pX for function given by the table:
315   // fArgument must be monotonic, either incre << 301 // fArgument, fFunction. The constructor, which creates fSecondDerivative, must be
                                                   >> 302 // called before. The function works optimal, if sequential calls are in random
                                                   >> 303 // values of pX.
316                                                   304 
317   while((kHigh - kLow) > 1)                    << 305 G4double 
318   {                                            << 306 G4DataInterpolation::CubicSplineInterpolation(G4double pX) const 
319     k = (kHigh + kLow) >> 1;  // compute midpo << 307 {
320     if(fArgument[k] > pX)                      << 308    G4int kLow, kHigh, k ;
321     {                                          << 309    G4double deltaHL, a, b ;
322       kHigh = k;                               << 310    
323     }                                          << 311    // Searching in the table by means of bisection method. 
324     else                                       << 312    // fArgument must be monotonic, either increasing or decreasing
325     {                                          << 313    
326       kLow = k;                                << 314    kLow = 0 ;
327     }                                          << 315    kHigh = fNumber - 1 ;
328   }  // kLow and kHigh now bracket the input v << 316    while((kHigh - kLow) > 1)
329   G4double deltaHL = fArgument[kHigh] - fArgum << 317    {
330   if(!(deltaHL != 0.0))                        << 318       k = (kHigh + kLow) >> 1 ; // compute midpoint 'bisection'
331   {                                            << 319       if(fArgument[k] > pX)
332     G4Exception("G4DataInterpolation::CubicSpl << 320       {
333                 FatalException, "Bad fArgument << 321    kHigh = k ;
334   }                                            << 322       }
335   G4double a = (fArgument[kHigh] - pX) / delta << 323       else
336   G4double b = (pX - fArgument[kLow]) / deltaH << 324       {
337                                                << 325    kLow = k ;
338   // Final evaluation of cubic spline polynomi << 326       }
339                                                << 327    }        // kLow and kHigh now bracket the input value of pX
340   return a * fFunction[kLow] + b * fFunction[k << 328    deltaHL = fArgument[kHigh] - fArgument[kLow] ;
341          ((a * a * a - a) * fSecondDerivative[ << 329    if(deltaHL == 0.0)
342           (b * b * b - b) * fSecondDerivative[ << 330    {
343            deltaHL * deltaHL / 6.0;            << 331       G4Exception(
                                                   >> 332       "Bad fArgument input in G4DataInterpolation::CubicSplineInterpolation") ;
                                                   >> 333    }
                                                   >> 334    a = (fArgument[kHigh] - pX)/deltaHL ;
                                                   >> 335    b = (pX - fArgument[kLow])/deltaHL ;
                                                   >> 336    
                                                   >> 337    // Final evaluation of cubic spline polynomial for return
                                                   >> 338    
                                                   >> 339    return a*fFunction[kLow] + b*fFunction[kHigh] + 
                                                   >> 340           ((a*a*a - a)*fSecondDerivative[kLow] +
                                                   >> 341            (b*b*b - b)*fSecondDerivative[kHigh])*deltaHL*deltaHL/6.0  ;
344 }                                                 342 }
345                                                   343 
346 ////////////////////////////////////////////// << 344 // ---------------------------------------------------------------------
347 //                                                345 //
348 // Return cubic spline interpolation in the po    346 // Return cubic spline interpolation in the point pX which is located between
349 // fArgument[index] and fArgument[index+1]. It << 347 // fArgument[index] and fArgument[index+1]. It is usually called in sequence of
350 // of known from external analysis values of i << 348 // known from external analysis values of index.
                                                   >> 349 
351                                                   350 
352 G4double G4DataInterpolation::FastCubicSpline( << 351 G4double 
                                                   >> 352 G4DataInterpolation::FastCubicSpline(G4double pX, 
                                                   >> 353              G4int index) const 
353 {                                                 354 {
354   G4double delta = fArgument[index + 1] - fArg << 355    G4double delta, a, b ;
355   if(!(delta != 0.0))                          << 356    delta = fArgument[index+1] - fArgument[index] ;
356   {                                            << 357    if(delta == 0.0)
357     G4Exception("G4DataInterpolation::FastCubi << 358    {
358                 FatalException, "Bad fArgument << 359       G4Exception("Bad fArgument input in G4DataInterpolation::FastCubicSpline") ;
359   }                                            << 360    }
360   G4double a = (fArgument[index + 1] - pX) / d << 361    a = (fArgument[index+1] - pX)/delta ;
361   G4double b = (pX - fArgument[index]) / delta << 362    b = (pX - fArgument[index])/delta ;
362                                                << 363    
363   // Final evaluation of cubic spline polynomi << 364    // Final evaluation of cubic spline polynomial for return
364                                                << 365    
365   return a * fFunction[index] + b * fFunction[ << 366    return a*fFunction[index] + b*fFunction[index+1] + 
366          ((a * a * a - a) * fSecondDerivative[ << 367           ((a*a*a - a)*fSecondDerivative[index] +
367           (b * b * b - b) * fSecondDerivative[ << 368            (b*b*b - b)*fSecondDerivative[index+1])*delta*delta/6.0  ;
368            delta * delta / 6.0;                << 
369 }                                                 369 }
370                                                   370 
371 ////////////////////////////////////////////// << 371 // ---------------------------------------------------------------------------
372 //                                                372 //
373 // Given argument pX, returns index k, so that << 373 // Given argument pX, returns index k, so that pX bracketed by fArgument[k] and
374 // and fArgument[k+1]                          << 374 // fArgument[k+1]
375                                                   375 
376 G4int G4DataInterpolation::LocateArgument(G4do << 376 G4int 
                                                   >> 377 G4DataInterpolation::LocateArgument(G4double pX) const 
377 {                                                 378 {
378   G4int kLow = -1, kHigh = fNumber, k = 0;     << 379    G4int kLow, kHigh, k ; 
379   G4bool ascend = (fArgument[fNumber - 1] >= f << 380    G4bool ascend ;
380   while((kHigh - kLow) > 1)                    << 381    kLow = -1 ;
381   {                                            << 382    kHigh = fNumber ;
382     k = (kHigh + kLow) >> 1;  // compute midpo << 383    ascend = (fArgument[fNumber-1] >= fArgument[0]) ;
383     if((pX >= fArgument[k]) == ascend)         << 384    while((kHigh - kLow) > 1)
384     {                                          << 385    {
385       kLow = k;                                << 386       k = (kHigh + kLow) >> 1 ; // compute midpoint 'bisection'
386     }                                          << 387       if(pX >= fArgument[k] == ascend)
387     else                                       << 388       {
388     {                                          << 389    kLow = k ;
389       kHigh = k;                               << 390       }
390     }                                          << 391       else
391   }                                            << 392       {
392   if(!(pX != fArgument[0]))                    << 393    kHigh = k ;
393   {                                            << 394       }
394     return 1;                                  << 395    }
395   }                                            << 396    if(pX == fArgument[0])
396   if(!(pX != fArgument[fNumber - 1]))          << 397    {
397   {                                            << 398       return 1 ;
398     return fNumber - 2;                        << 399    }
399   }                                            << 400    else if(pX == fArgument[fNumber-1]) 
400                                                << 401    {
401   return kLow;                                 << 402       return fNumber - 2 ;
402                                                << 403    }
                                                   >> 404    else  return kLow ;
403 }                                                 405 }
404                                                   406 
405 ////////////////////////////////////////////// << 407 // ------------------------------------------------------------------------
406 //                                                408 //
407 // Given a value pX, returns a value 'index' s << 409 // Given a value pX, returns a value 'index' such that pX is between fArgument[index]
408 // fArgument[index] and fArgument[index+1]. fA << 410 // and fArgument[index+1]. fArgument MUST BE MONOTONIC, either increasing or
409 // either increasing or decreasing. If index = << 411 // decreasing. If index = -1 or fNumber, this indicates that pX is out of range.
410 // that pX is out of range. The value index on << 412 // The value index on input is taken as the initial approximation for index on
411 // approximation for index on output.          << 413 // output.
                                                   >> 414 
412                                                   415 
413 void G4DataInterpolation::CorrelatedSearch(G4d << 416 void 
                                                   >> 417 G4DataInterpolation::CorrelatedSearch( G4double pX,
                                                   >> 418                                  G4int& index ) const 
414 {                                                 419 {
415   G4int kHigh = 0, k = 0, Increment = 0;       << 420    G4int kHigh, k, Increment ;
416   // ascend = true for ascending order of tabl << 421    // ascend = true for ascending order of table, false otherwise
417   G4bool ascend = (fArgument[fNumber - 1] >= f << 422    G4bool ascend = (fArgument[fNumber-1] >= fArgument[0]) ;
418   if(index < 0 || index > fNumber - 1)         << 423    if(index < 0 || index > fNumber-1)
419   {                                            << 424    {
420     index = -1;                                << 425       index = -1 ;
421     kHigh = fNumber;                           << 426       kHigh = fNumber ;
422   }                                            << 427    }
423   else                                         << 428    else
424   {                                            << 429    {
425     Increment = 1;  //   What value would be t << 430       Increment = 1 ;   //   What value would be the best ?
426     if((pX >= fArgument[index]) == ascend)     << 431       if((pX >= fArgument[index]) == ascend)
427     {                                          << 432       {
428       if(index == fNumber - 1)                 << 433    if(index == fNumber -1)
429       {                                        << 434    {
430         index = fNumber;                       << 435       index = fNumber ;
431         return;                                << 436       return ;
432       }                                        << 437    }
433       kHigh = index + 1;                       << 438    kHigh = index + 1 ;
434       while((pX >= fArgument[kHigh]) == ascend << 439    while((pX >= fArgument[kHigh]) == ascend)
435       {                                        << 440    {
436         index = kHigh;                         << 441       index = kHigh ;
437         Increment += Increment;  // double the << 442       Increment += Increment ;      // double the Increment
438         kHigh = index + Increment;             << 443       kHigh = index + Increment ;
439         if(kHigh > (fNumber - 1))              << 444       if(kHigh > (fNumber - 1))
440         {                                      << 445       {
441           kHigh = fNumber;                     << 446          kHigh = fNumber ;
442           break;                               << 447          break ;
443         }                                      << 448       }
444       }                                        << 449    }
445     }                                          << 450       }
446     else                                       << 451       else
447     {                                          << 452       {
448       if(index == 0)                           << 453    if(index == 0)
449       {                                        << 454    {
450         index = -1;                            << 455       index = -1 ;
451         return;                                << 456       return ;
452       }                                        << 457    }
453       kHigh = --index;                         << 458          kHigh = index-- ;
454       while((pX < fArgument[index]) == ascend) << 459          while((pX < fArgument[index]) == ascend)
455       {                                        << 460          {
456         kHigh = index;                         << 461       kHigh = index ;
457         Increment <<= 1;  // double the Increm << 462       Increment <<= 1 ;      // double the Increment
458         if(Increment >= kHigh)                 << 463       if(Increment >= kHigh)
459         {                                      << 464       {
460           index = -1;                          << 465          index = -1 ;
461           break;                               << 466          break ;
462         }                                      << 467       }
463                                                << 468       else
464         index = kHigh - Increment;             << 469       {
465                                                << 470          index = kHigh - Increment ;
466       }                                        << 471       }
467     }  // Value bracketed                      << 472          }
468   }                                            << 473       }        // Value bracketed
469   // final bisection searching                 << 474    }
470                                                << 475    // final bisection searching
471   while((kHigh - index) != 1)                  << 476 
472   {                                            << 477    while((kHigh - index) != 1)
473     k = (kHigh + index) >> 1;                  << 478    {
474     if((pX >= fArgument[k]) == ascend)         << 479       k = (kHigh + index) >> 1 ;
475     {                                          << 480       if((pX >= fArgument[k]) == ascend)
476       index = k;                               << 481       {
477     }                                          << 482    index = k ;
478     else                                       << 483       }
479     {                                          << 484       else
480       kHigh = k;                               << 485       {
481     }                                          << 486    kHigh = k ;
482   }                                            << 487       }
483   if(!(pX != fArgument[fNumber - 1]))          << 488    }
484   {                                            << 489    if(pX == fArgument[fNumber-1])
485     index = fNumber - 2;                       << 490    {
486   }                                            << 491       index = fNumber - 2 ;
487   if(!(pX != fArgument[0]))                    << 492    }
488   {                                            << 493    if(pX == fArgument[0])
489     index = 0;                                 << 494    {
490   }                                            << 495       index = 0 ;
491   return;                                      << 496    }
                                                   >> 497    return ;
492 }                                                 498 }
493                                                << 
494 //                                             << 
495 //                                             << 
496 ////////////////////////////////////////////// << 
497                                                   499