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 9.2.p1)


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