Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/de_excitation/multifragmentation/include/G4Solver.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 template <class Function>
 27 G4bool G4Solver<Function>::Bisection(Function & theFunction)
 28 {
 29     // Check the interval before start
 30     if (a > b || std::abs(a-b) <= tolerance) 
 31     {
 32   G4cerr << "G4Solver::Bisection: The interval must be properly set." << G4endl;
 33   return false;
 34     }
 35     G4double fa = theFunction(a);
 36     G4double fb = theFunction(b);
 37     if (fa*fb > 0.0) 
 38     {
 39   G4cerr << "G4Solver::Bisection: The interval must include a root." << G4endl;
 40   return false;
 41     }
 42     
 43     G4double eps=tolerance*(b-a);
 44     
 45     
 46     // Finding the root
 47     for (G4int i = 0; i < MaxIter; i++) 
 48     {
 49   G4double c = (a+b)/2.0;
 50   if ((b-a) < eps) 
 51   {
 52       root = c;
 53       return true;
 54   }
 55   G4double fc = theFunction(c);
 56   if (fc == 0.0) 
 57   {
 58       root = c;
 59       return true;
 60   }
 61   if (fa*fc < 0.0) 
 62   {
 63       a=c;
 64       fa=fc;
 65   } 
 66   else 
 67   {
 68       b=c;
 69       fb=fc;
 70   }
 71     }
 72     G4cerr << "G4Solver::Bisection: Exceeded maximum number of iterations without convergence." << G4endl;
 73     return false;
 74 }
 75 
 76 
 77 template <class Function>
 78 G4bool G4Solver<Function>::RegulaFalsi(Function & theFunction)
 79 {
 80     // Check the interval before start
 81     if (a > b || std::abs(a-b) <= tolerance) 
 82     {
 83   G4cerr << "G4Solver::RegulaFalsi: The interval must be properly set." << G4endl;
 84   return false;
 85     }
 86     G4double fa = theFunction(a);
 87     G4double fb = theFunction(b);
 88     if (fa*fb > 0.0) 
 89     {
 90   G4cerr << "G4Solver::RegulaFalsi: The interval must include a root." << G4endl;
 91   return false;
 92     }
 93     
 94     G4double eps=tolerance*(b-a);
 95   
 96   
 97     // Finding the root
 98     for (G4int i = 0; i < MaxIter; i++) 
 99     {
100   G4double c = (a*fb-b*fa)/(fb-fa);
101   G4double delta = std::min(std::abs(c-a),std::abs(b-c));
102   if (delta < eps) 
103   {
104       root = c;
105       return true;
106   }
107   G4double fc = theFunction(c);
108   if (fc == 0.0) 
109   {
110       root = c;
111       return true;
112   }
113   if (fa*fc < 0.0) 
114   {
115       b=c;
116       fb=fc;
117   } 
118   else 
119   {
120       a=c;
121       fa=fc;
122   }
123     }
124     G4cerr << "G4Solver::Bisection: Exceeded maximum number of iterations without convergence." << G4endl;
125     return false;
126 
127 } 
128 
129 template <class Function>
130 G4bool G4Solver<Function>::Brent(Function & theFunction)
131 {
132     
133     const G4double precision = 3.0e-8;
134     
135     // Check the interval before start
136     if (a > b || std::abs(a-b) <= tolerance) 
137     {
138   G4cerr << "G4Solver::Brent: The interval must be properly set." << G4endl;
139   return false;
140     }
141     G4double fa = theFunction(a);
142     G4double fb = theFunction(b);
143     if (fa*fb > 0.0) 
144     {
145   G4cerr << "G4Solver::Brent: The interval must include a root." << G4endl;
146   return false;
147     }
148     
149     G4double c = b;
150     G4double fc = fb;
151     G4double d = 0.0;
152     G4double e = 0.0;
153     
154     for (G4int i=0; i < MaxIter; i++) 
155     {
156   // Rename a,b,c and adjust bounding interval d
157   if (fb*fc > 0.0) 
158   {
159       c = a;
160       fc = fa;
161       d = b - a;
162       e = d;
163   }
164   if (std::abs(fc) < std::abs(fb)) 
165   {
166       a = b;
167       b = c;
168       c = a;
169       fa = fb;
170       fb = fc;
171       fc = fa;
172   }
173   G4double Tol1 = 2.0*precision*std::abs(b) + 0.5*tolerance;
174   G4double xm = 0.5*(c-b);
175   if (std::abs(xm) <= Tol1 || fb == 0.0) 
176   {
177       root = b;
178       return true;
179   }
180   // Inverse quadratic interpolation
181   if (std::abs(e) >= Tol1 && std::abs(fa) > std::abs(fb)) 
182   {
183       G4double ss = fb/fa;
184       G4double p = 0.0;
185       G4double q = 0.0;
186       if (a == c) 
187       {
188     p = 2.0*xm*ss;
189     q = 1.0 - ss;
190       } 
191       else 
192       {
193     q = fa/fc;
194     G4double r = fb/fc;
195     p = ss*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
196     q = (q-1.0)*(r-1.0)*(ss-1.0);
197       }
198       // Check bounds
199       if (p > 0.0) q = -q;
200       p = std::abs(p);
201       G4double min1 = 3.0*xm*q-std::abs(Tol1*q);
202       G4double min2 = std::abs(e*q);
203       if (2.0*p < std::min(min1,min2)) 
204       {
205     // Interpolation
206     e = d;
207     d = p/q;
208       } 
209       else 
210       {
211     // Bisection
212     d = xm;
213     e = d;
214       }
215   } 
216   else 
217   {
218       // Bounds decreasing too slowly, use bisection
219       d = xm;
220       e = d;
221   }
222   // Move last guess to a 
223   a = b;
224   fa = fb;
225   if (std::abs(d) > Tol1) b += d;
226   else 
227   {
228       if (xm >= 0.0) b += std::abs(Tol1);
229       else b -= std::abs(Tol1);
230   }
231   fb = theFunction(b);
232     }
233     G4cerr << "G4Solver::Brent: Number of iterations exceeded." << G4endl;
234     return false;
235 }
236 
237 
238 
239 template <class Function>
240 G4bool G4Solver<Function>::Crenshaw(Function & theFunction)
241 {
242     // Check the interval before start
243     if (a > b || std::abs(a-b) <= tolerance) 
244     {
245   G4cerr << "G4Solver::Crenshaw: The interval must be properly set." << G4endl;
246   return false;
247     }
248 
249     G4double fa = theFunction(a);
250     if (fa == 0.0) 
251     {
252   root = a;
253   return true;
254     }
255 
256     G4double Mlast = a;
257 
258     G4double fb = theFunction(b);
259     if (fb == 0.0)
260     {
261   root = b;
262   return true;
263     }
264 
265     if (fa*fb > 0.0) 
266     {
267   G4cerr << "G4Solver::Crenshaw: The interval must include a root." << G4endl;
268   return false;
269     }
270 
271     
272     for (G4int i=0; i < MaxIter; i++) 
273       {
274   G4double c = 0.5 * (b + a);
275   G4double fc = theFunction(c);
276   if (fc == 0.0 || std::abs(c - a) < tolerance) 
277     {
278       root = c;
279       return true;
280     }
281 
282   if (fc * fa  > 0.0)
283     {
284       G4double tmp = a;
285       a = b;
286       b = tmp;
287       tmp = fa;
288       fa = fb;
289       fb = tmp;
290     }
291   
292   G4double fc0 = fc - fa;
293   G4double fb1 = fb - fc;
294   G4double fb0 = fb - fa;
295   if (fb * fb0 < 2.0 * fc * fc0)
296     {
297       b = c;
298       fb = fc;
299     }
300   else 
301     {
302       G4double B = (c - a) / fc0;
303       G4double C = (fc0 - fb1) / (fb1 * fb0);
304       G4double M = a - B * fa * (1.0 - C * fc);
305       G4double fM = theFunction(M);
306       if (fM == 0.0 || std::abs(M - Mlast) < tolerance)
307         {
308     root = M;
309     return true;
310         }
311       Mlast = M;
312       if (fM * fa < 0.0)
313         {
314     b = M;
315     fb = fM;
316         }
317       else 
318       {
319     a = M;
320     fa = fM;
321     b = c;
322     fb = fc;
323       }
324   }
325     }
326     return false;
327 }
328 
329 
330 
331 
332 template <class Function>   
333 void G4Solver<Function>::SetIntervalLimits(const G4double Limit1, const G4double Limit2)
334 {
335     if (std::abs(Limit1-Limit2) <= tolerance) 
336     {
337   G4cerr << "G4Solver::SetIntervalLimits: Interval must be wider than tolerance." << G4endl;
338   return;
339     }
340     if (Limit1 < Limit2) 
341     {
342   a = Limit1;
343   b = Limit2;
344     } 
345     else 
346     {
347   a = Limit2;
348   b = Limit1;
349     }
350     return;
351 }
352 
353