Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/HEPNumerics/include/G4PolynomialSolver.icc

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/include/G4PolynomialSolver.icc (Version 11.3.0) and /global/HEPNumerics/include/G4PolynomialSolver.icc (Version 3.1)


                                                   >>   1 // This code implementation is the intellectual property of
                                                   >>   2 // the GEANT4 collaboration.
  1 //                                                  3 //
  2 // ******************************************* <<   4 // By copying, distributing or modifying the Program (or any work
  3 // * License and Disclaimer                    <<   5 // based on the Program) you indicate your acceptance of this statement,
  4 // *                                           <<   6 // and all its terms.
  5 // * The  Geant4 software  is  copyright of th << 
  6 // * the Geant4 Collaboration.  It is provided << 
  7 // * conditions of the Geant4 Software License << 
  8 // * LICENSE and available at  http://cern.ch/ << 
  9 // * include a list of copyright holders.      << 
 10 // *                                           << 
 11 // * Neither the authors of this software syst << 
 12 // * institutes,nor the agencies providing fin << 
 13 // * work  make  any representation or  warran << 
 14 // * regarding  this  software system or assum << 
 15 // * use.  Please see the license in the file  << 
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                           << 
 18 // * This  code  implementation is the result  << 
 19 // * technical work of the GEANT4 collaboratio << 
 20 // * By using,  copying,  modifying or  distri << 
 21 // * any work based  on the software)  you  ag << 
 22 // * use  in  resulting  scientific  publicati << 
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // ******************************************* << 
 25 //                                                  7 //
 26 // G4PolynomialSolver inline methods implement <<   8 // $Id: G4PolynomialSolver.icc,v 1.5 2001/01/29 13:13:34 gcosmo Exp $
                                                   >>   9 // GEANT4 tag $Name: geant4-03-01 $
                                                   >>  10 // 
                                                   >>  11 // class G4PolynomialSolver
                                                   >>  12 //
                                                   >>  13 // 19.12.00 E.Medernach, First implementation
 27 //                                                 14 //
 28 // Author: E.Medernach, 19.12.2000 - First imp << 
 29 // ------------------------------------------- << 
 30                                                    15 
 31 #define POLEPSILON 1e-12                       <<  16 #define POLEPSILON   1e-12
 32 #define POLINFINITY 9.0E99                     <<  17 #define POLINFINITY  9.0E99
 33 #define ITERATION 12  // 20 But 8 is really en <<  18 #define ITERATION  12 // 20 But 8 is really enough for Newton with a good guess
 34                                                    19 
 35 template <class T, class F>                        20 template <class T, class F>
 36 G4PolynomialSolver<T, F>::G4PolynomialSolver(T <<  21 G4PolynomialSolver<T,F>::G4PolynomialSolver (T* typeF, F func, F deriv,
 37                                              G     22                                              G4double precision)
 38 {                                                  23 {
 39   Precision     = precision;                   <<  24   Precision = precision ;
 40   FunctionClass = typeF;                       <<  25   FunctionClass = typeF ;
 41   Function      = func;                        <<  26   Function = func ;
 42   Derivative    = deriv;                       <<  27   Derivative = deriv ;  
 43 }                                                  28 }
 44                                                    29 
 45 template <class T, class F>                        30 template <class T, class F>
 46 G4PolynomialSolver<T, F>::~G4PolynomialSolver( <<  31 G4PolynomialSolver<T,F>::~G4PolynomialSolver ()
 47 {}                                             <<  32 {
                                                   >>  33 }
 48                                                    34 
 49 template <class T, class F>                        35 template <class T, class F>
 50 G4double G4PolynomialSolver<T, F>::solve(G4dou <<  36 G4double G4PolynomialSolver<T,F>::solve(G4double IntervalMin,
 51                                          G4dou <<  37           G4double IntervalMax)
 52 {                                                  38 {
 53   return Newton(IntervalMin, IntervalMax);     <<  39   return Newton(IntervalMin,IntervalMax);  
 54 }                                                  40 }
 55                                                    41 
                                                   >>  42 
 56 /* If we want to be general this could work fo     43 /* If we want to be general this could work for any
 57    polynomial of order more that 4 if we find      44    polynomial of order more that 4 if we find the (ORDER + 1)
 58    control points                                  45    control points
 59 */                                                 46 */
 60 #define NBBEZIER 5                                 47 #define NBBEZIER 5
 61                                                    48 
 62 template <class T, class F>                        49 template <class T, class F>
 63 G4int G4PolynomialSolver<T, F>::BezierClipping <<  50 G4int
 64                                                <<  51 G4PolynomialSolver<T,F>::BezierClipping(/*T* typeF,F func,F deriv,*/
 65                                                <<  52           G4double *IntervalMin,
                                                   >>  53           G4double *IntervalMax)
 66 {                                                  54 {
 67   /** BezierClipping is a clipping interval Ne     55   /** BezierClipping is a clipping interval Newton method **/
 68   /** It works by clipping the area where the      56   /** It works by clipping the area where the polynomial is **/
 69                                                    57 
 70   G4double P[NBBEZIER][2], D[2];               <<  58   G4double P[NBBEZIER][2],D[2];
 71   G4double NewMin, NewMax;                     <<  59   G4double NewMin,NewMax;
 72                                                    60 
 73   G4int IntervalIsVoid = 1;                        61   G4int IntervalIsVoid = 1;
 74                                                <<  62   
 75   /*** Calculating Control Points  ***/            63   /*** Calculating Control Points  ***/
 76   /* We see the polynomial as a Bezier curve f     64   /* We see the polynomial as a Bezier curve for some control points to find */
 77                                                    65 
 78   /*                                               66   /*
 79     For 5 control points (polynomial of degree     67     For 5 control points (polynomial of degree 4) this is:
 80                                                <<  68     
 81     0     p0 = F((*IntervalMin))                   69     0     p0 = F((*IntervalMin))
 82     1/4   p1 = F((*IntervalMin)) + ((*Interval     70     1/4   p1 = F((*IntervalMin)) + ((*IntervalMax) - (*IntervalMin))/4
 83                  * F'((*IntervalMin))              71                  * F'((*IntervalMin))
 84     2/4   p2 = 1/6 * (16*F(((*IntervalMax) + (     72     2/4   p2 = 1/6 * (16*F(((*IntervalMax) + (*IntervalMin))/2)
 85                       - (p0 + 4*p1 + 4*p3 + p4 <<  73                       - (p0 + 4*p1 + 4*p3 + p4))  
 86     3/4   p3 = F((*IntervalMax)) - ((*Interval     74     3/4   p3 = F((*IntervalMax)) - ((*IntervalMax) - (*IntervalMin))/4
 87                  * F'((*IntervalMax))              75                  * F'((*IntervalMax))
 88     1     p4 = F((*IntervalMax))                   76     1     p4 = F((*IntervalMax))
 89   */                                           <<  77   */  
 90                                                    78 
 91   /* x,y,z,dx,dy,dz are constant during search     79   /* x,y,z,dx,dy,dz are constant during searching */
 92                                                    80 
 93   D[0] = (FunctionClass->*Derivative)(*Interva     81   D[0] = (FunctionClass->*Derivative)(*IntervalMin);
 94                                                <<  82   
 95   P[0][0] = (*IntervalMin);                        83   P[0][0] = (*IntervalMin);
 96   P[0][1] = (FunctionClass->*Function)(*Interv     84   P[0][1] = (FunctionClass->*Function)(*IntervalMin);
                                                   >>  85   
 97                                                    86 
 98   if(std::fabs(P[0][1]) < Precision)           <<  87   if (fabs(P[0][1]) < Precision) {
 99   {                                            << 
100     return 1;                                      88     return 1;
101   }                                                89   }
102                                                <<  90   
103   if(((*IntervalMax) - (*IntervalMin)) < POLEP <<  91   if (((*IntervalMax) - (*IntervalMin)) < POLEPSILON) {
104   {                                            << 
105     return 1;                                      92     return 1;
106   }                                                93   }
107                                                    94 
108   P[1][0] = (*IntervalMin) + ((*IntervalMax) - <<  95   P[1][0] = (*IntervalMin) + ((*IntervalMax) - (*IntervalMin))/4;
109   P[1][1] = P[0][1] + (((*IntervalMax) - (*Int <<  96   P[1][1] = P[0][1] + (((*IntervalMax) - (*IntervalMin))/4.0) * D[0];
110                                                    97 
111   D[1] = (FunctionClass->*Derivative)(*Interva     98   D[1] = (FunctionClass->*Derivative)(*IntervalMax);
112                                                    99 
113   P[4][0] = (*IntervalMax);                       100   P[4][0] = (*IntervalMax);
114   P[4][1] = (FunctionClass->*Function)(*Interv    101   P[4][1] = (FunctionClass->*Function)(*IntervalMax);
                                                   >> 102   
                                                   >> 103   P[3][0] = (*IntervalMax) - ((*IntervalMax) - (*IntervalMin))/4;
                                                   >> 104   P[3][1] = P[4][1] - ((*IntervalMax) - (*IntervalMin))/4 * D[1];
                                                   >> 105 
                                                   >> 106   P[2][0] = ((*IntervalMax) + (*IntervalMin))/2;
                                                   >> 107   P[2][1] = (16*(FunctionClass->*Function)(((*IntervalMax)+(*IntervalMin))/2)
                                                   >> 108              - (P[0][1] + 4*P[1][1] + 4*P[3][1] + P[4][1]))/6 ;
                                                   >> 109 
                                                   >> 110   {
                                                   >> 111     G4double Intersection ;
                                                   >> 112     G4int i,j;
                                                   >> 113   
                                                   >> 114     NewMin = (*IntervalMax) ;
                                                   >> 115     NewMax = (*IntervalMin) ;    
                                                   >> 116 
                                                   >> 117     for (i=0;i<5;i++)
                                                   >> 118       for (j=i+1;j<5;j++)
                                                   >> 119   {
                                                   >> 120     /* there is an intersection only if each have different signs */
                                                   >> 121     if (((P[j][1] > -Precision) && (P[i][1] < Precision)) ||
                                                   >> 122         ((P[j][1] < Precision) && (P[i][1] > -Precision))) {
                                                   >> 123       IntervalIsVoid  = 0;
                                                   >> 124       Intersection = P[j][0] - P[j][1]*((P[i][0] - P[j][0])/
                                                   >> 125                                         (P[i][1] - P[j][1]));
                                                   >> 126       if (Intersection < NewMin) {
                                                   >> 127         NewMin = Intersection;
                                                   >> 128       }
                                                   >> 129       if (Intersection > NewMax) {
                                                   >> 130         NewMax = Intersection;
                                                   >> 131       }
                                                   >> 132     }
                                                   >> 133   }
115                                                   134 
116   P[3][0] = (*IntervalMax) - ((*IntervalMax) - << 135     
117   P[3][1] = P[4][1] - ((*IntervalMax) - (*Inte << 136     if (IntervalIsVoid != 1) {
118                                                << 
119   P[2][0] = ((*IntervalMax) + (*IntervalMin))  << 
120   P[2][1] =                                    << 
121     (16 * (FunctionClass->*Function)(((*Interv << 
122      (P[0][1] + 4 * P[1][1] + 4 * P[3][1] + P[ << 
123     6;                                         << 
124                                                << 
125   {                                            << 
126     G4double Intersection;                     << 
127     G4int i, j;                                << 
128                                                << 
129     NewMin = (*IntervalMax);                   << 
130     NewMax = (*IntervalMin);                   << 
131                                                << 
132     for(i = 0; i < 5; ++i)                     << 
133       for(j = i + 1; j < 5; ++j)               << 
134       {                                        << 
135         /* there is an intersection only if ea << 
136         if(((P[j][1] > -Precision) && (P[i][1] << 
137            ((P[j][1] < Precision) && (P[i][1]  << 
138         {                                      << 
139           IntervalIsVoid = 0;                  << 
140           Intersection =                       << 
141             P[j][0] - P[j][1] * ((P[i][0] - P[ << 
142           if(Intersection < NewMin)            << 
143           {                                    << 
144             NewMin = Intersection;             << 
145           }                                    << 
146           if(Intersection > NewMax)            << 
147           {                                    << 
148             NewMax = Intersection;             << 
149           }                                    << 
150         }                                      << 
151       }                                        << 
152                                                << 
153     if(IntervalIsVoid != 1)                    << 
154     {                                          << 
155       (*IntervalMax) = NewMax;                    137       (*IntervalMax) = NewMax;
156       (*IntervalMin) = NewMin;                    138       (*IntervalMin) = NewMin;
157     }                                             139     }
158   }                                               140   }
159                                                << 141   
160   if(IntervalIsVoid == 1)                      << 142   if (IntervalIsVoid == 1) {
161   {                                            << 
162     return -1;                                    143     return -1;
163   }                                               144   }
164                                                << 145   
165   return 0;                                       146   return 0;
166 }                                                 147 }
167                                                   148 
168 template <class T, class F>                       149 template <class T, class F>
169 G4double G4PolynomialSolver<T, F>::Newton(G4do << 150 G4double G4PolynomialSolver<T,F>::Newton (G4double IntervalMin,
170                                           G4do    151                                           G4double IntervalMax)
171 {                                                 152 {
172   /* So now we have a good guess and an interv    153   /* So now we have a good guess and an interval where
173      if there are an intersection the root mus    154      if there are an intersection the root must be */
174                                                   155 
175   G4double Value    = 0;                       << 156   G4double Value = 0;
176   G4double Gradient = 0;                          157   G4double Gradient = 0;
177   G4double Lambda;                             << 158   G4double Lambda ;
178                                                << 
179   G4int i = 0;                                 << 
180   G4int j = 0;                                 << 
181                                                   159 
                                                   >> 160   G4int i=0;
                                                   >> 161   G4int j=0;
                                                   >> 162   
                                                   >> 163   
182   /* Reduce interval before applying Newton Me    164   /* Reduce interval before applying Newton Method */
183   {                                               165   {
184     G4int NewtonIsSafe;                        << 166     G4int NewtonIsSafe ;
185                                                   167 
186     while((NewtonIsSafe = BezierClipping(&Inte << 168     while ((NewtonIsSafe = BezierClipping(&IntervalMin,&IntervalMax)) == 0) ;
187       ;                                        << 
188                                                   169 
189     if(NewtonIsSafe == -1)                     << 170     if (NewtonIsSafe == -1) {
190     {                                          << 
191       return POLINFINITY;                         171       return POLINFINITY;
192     }                                             172     }
193   }                                               173   }
194                                                   174 
195   Lambda = IntervalMin;                           175   Lambda = IntervalMin;
196   Value  = (FunctionClass->*Function)(Lambda); << 176   Value = (FunctionClass->*Function)(Lambda);
197                                                   177 
198   //  while ((std::fabs(Value) > Precision)) { << 178 
199   while(j != -1)                               << 179   //  while ((fabs(Value) > Precision)) {
200   {                                            << 180   while (j != -1) {
                                                   >> 181     
201     Value = (FunctionClass->*Function)(Lambda)    182     Value = (FunctionClass->*Function)(Lambda);
202                                                   183 
203     Gradient = (FunctionClass->*Derivative)(La    184     Gradient = (FunctionClass->*Derivative)(Lambda);
204                                                   185 
205     Lambda = Lambda - Value / Gradient;        << 186     Lambda = Lambda - Value/Gradient ;
206                                                   187 
207     if(std::fabs(Value) <= Precision)          << 188     if (fabs(Value) <= Precision) {
208     {                                          << 189       j ++;
209       ++j;                                     << 190       if (j == 2) {
210       if(j == 2)                               << 191   j = -1; 
211       {                                        << 192       }      
212         j = -1;                                << 193     } else {
213       }                                        << 194       i ++;
214     }                                          << 195       
215     else                                       << 196       if (i > ITERATION) 
216     {                                          << 197   return POLINFINITY;
217       ++i;                                     << 198     }    
218                                                << 
219       if(i > ITERATION)                        << 
220         return POLINFINITY;                    << 
221     }                                          << 
222   }                                               199   }
223   return Lambda;                               << 200   return Lambda ;
224 }                                                 201 }
225                                                   202