Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/HEPNumerics/src/G4JTPolynomialSolver.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/G4JTPolynomialSolver.cc (Version 11.3.0) and /global/HEPNumerics/src/G4JTPolynomialSolver.cc (Version 10.7.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 // G4JTPolynomialSolver class implementation.      26 // G4JTPolynomialSolver class implementation.
 27 //                                                 27 //
 28 // Author: Oliver Link, 15.02.2005                 28 // Author: Oliver Link, 15.02.2005
 29 //         Translated to C++ and adapted to us     29 //         Translated to C++ and adapted to use STL vectors.
 30 // -------------------------------------------     30 // --------------------------------------------------------------------
 31                                                    31 
 32 #include "G4JTPolynomialSolver.hh"                 32 #include "G4JTPolynomialSolver.hh"
 33 #include "G4Pow.hh"                                33 #include "G4Pow.hh"
 34 #include "G4SystemOfUnits.hh"                      34 #include "G4SystemOfUnits.hh"
 35                                                    35 
 36 const G4double G4JTPolynomialSolver::base   =      36 const G4double G4JTPolynomialSolver::base   = 2;
 37 const G4double G4JTPolynomialSolver::eta    =      37 const G4double G4JTPolynomialSolver::eta    = DBL_EPSILON;
 38 const G4double G4JTPolynomialSolver::infin  =      38 const G4double G4JTPolynomialSolver::infin  = DBL_MAX;
 39 const G4double G4JTPolynomialSolver::smalno =      39 const G4double G4JTPolynomialSolver::smalno = DBL_MIN;
 40 const G4double G4JTPolynomialSolver::are    =      40 const G4double G4JTPolynomialSolver::are    = DBL_EPSILON;
 41 const G4double G4JTPolynomialSolver::mre    =      41 const G4double G4JTPolynomialSolver::mre    = DBL_EPSILON;
 42 const G4double G4JTPolynomialSolver::lo     =      42 const G4double G4JTPolynomialSolver::lo     = DBL_MIN / DBL_EPSILON;
 43                                                    43 
                                                   >>  44 G4JTPolynomialSolver::G4JTPolynomialSolver() {}
                                                   >>  45 
                                                   >>  46 G4JTPolynomialSolver::~G4JTPolynomialSolver() {}
                                                   >>  47 
 44 G4int G4JTPolynomialSolver::FindRoots(G4double     48 G4int G4JTPolynomialSolver::FindRoots(G4double* op, G4int degr, G4double* zeror,
 45                                       G4double     49                                       G4double* zeroi)
 46 {                                                  50 {
 47   G4double t = 0.0, aa = 0.0, bb = 0.0, cc = 0     51   G4double t = 0.0, aa = 0.0, bb = 0.0, cc = 0.0, factor = 1.0;
 48   G4double max = 0.0, min = infin, xxx = 0.0,      52   G4double max = 0.0, min = infin, xxx = 0.0, x = 0.0, sc = 0.0, bnd = 0.0;
 49   G4double xm = 0.0, ff = 0.0, df = 0.0, dx =      53   G4double xm = 0.0, ff = 0.0, df = 0.0, dx = 0.0;
 50   G4int cnt = 0, nz = 0, i = 0, j = 0, jj = 0,     54   G4int cnt = 0, nz = 0, i = 0, j = 0, jj = 0, l = 0, nm1 = 0, zerok = 0;
 51   G4Pow* power = G4Pow::GetInstance();             55   G4Pow* power = G4Pow::GetInstance();
 52                                                    56 
 53   // Initialization of constants for shift rot     57   // Initialization of constants for shift rotation.
 54   //                                               58   //
 55   static const G4double xx   = std::sqrt(0.5);     59   static const G4double xx   = std::sqrt(0.5);
 56   static const G4double rot  = 94.0 * deg;         60   static const G4double rot  = 94.0 * deg;
 57   static const G4double cosr = std::cos(rot),      61   static const G4double cosr = std::cos(rot), sinr = std::sin(rot);
 58   G4double xo = xx, yo = -xx;                      62   G4double xo = xx, yo = -xx;
 59   n = degr;                                        63   n = degr;
 60                                                    64 
 61   //  Algorithm fails if the leading coefficie     65   //  Algorithm fails if the leading coefficient is zero.
 62   //                                               66   //
 63   if(!(op[0] != 0.0))                              67   if(!(op[0] != 0.0))
 64   {                                                68   {
 65     return -1;                                     69     return -1;
 66   }                                                70   }
 67                                                    71 
 68   //  Remove the zeros at the origin, if any.      72   //  Remove the zeros at the origin, if any.
 69   //                                               73   //
 70   while(!(op[n] != 0.0))                           74   while(!(op[n] != 0.0))
 71   {                                                75   {
 72     j        = degr - n;                           76     j        = degr - n;
 73     zeror[j] = 0.0;                                77     zeror[j] = 0.0;
 74     zeroi[j] = 0.0;                                78     zeroi[j] = 0.0;
 75     n--;                                           79     n--;
 76   }                                                80   }
 77   if(n < 1)                                        81   if(n < 1)
 78   {                                                82   {
 79     return -1;                                     83     return -1;
 80   }                                                84   }
 81                                                    85 
 82   // Allocate buffers here                         86   // Allocate buffers here
 83   //                                               87   //
 84   std::vector<G4double> temp(degr + 1);            88   std::vector<G4double> temp(degr + 1);
 85   std::vector<G4double> pt(degr + 1);              89   std::vector<G4double> pt(degr + 1);
 86                                                    90 
 87   p.assign(degr + 1, 0);                           91   p.assign(degr + 1, 0);
 88   qp.assign(degr + 1, 0);                          92   qp.assign(degr + 1, 0);
 89   k.assign(degr + 1, 0);                           93   k.assign(degr + 1, 0);
 90   qk.assign(degr + 1, 0);                          94   qk.assign(degr + 1, 0);
 91   svk.assign(degr + 1, 0);                         95   svk.assign(degr + 1, 0);
 92                                                    96 
 93   // Make a copy of the coefficients.              97   // Make a copy of the coefficients.
 94   //                                               98   //
 95   for(i = 0; i <= n; ++i)                          99   for(i = 0; i <= n; ++i)
 96   {                                               100   {
 97     p[i] = op[i];                                 101     p[i] = op[i];
 98   }                                               102   }
 99                                                   103 
100   do                                              104   do
101   {                                               105   {
102     if(n == 1)  // Start the algorithm for one    106     if(n == 1)  // Start the algorithm for one zero.
103     {                                             107     {
104       zeror[degr - 1] = -p[1] / p[0];             108       zeror[degr - 1] = -p[1] / p[0];
105       zeroi[degr - 1] = 0.0;                      109       zeroi[degr - 1] = 0.0;
106       n -= 1;                                     110       n -= 1;
107       return degr - n;                            111       return degr - n;
108     }                                             112     }
109     if(n == 2)  // Calculate the final zero or    113     if(n == 2)  // Calculate the final zero or pair of zeros.
110     {                                             114     {
111       Quadratic(p[0], p[1], p[2], &zeror[degr     115       Quadratic(p[0], p[1], p[2], &zeror[degr - 2], &zeroi[degr - 2],
112                 &zeror[degr - 1], &zeroi[degr     116                 &zeror[degr - 1], &zeroi[degr - 1]);
113       n -= 2;                                     117       n -= 2;
114       return degr - n;                            118       return degr - n;
115     }                                             119     }
116                                                   120 
117     // Find largest and smallest moduli of coe    121     // Find largest and smallest moduli of coefficients.
118     //                                            122     //
119     max = 0.0;                                    123     max = 0.0;
120     min = infin;                                  124     min = infin;
121     for(i = 0; i <= n; ++i)                       125     for(i = 0; i <= n; ++i)
122     {                                             126     {
123       x = std::fabs(p[i]);                        127       x = std::fabs(p[i]);
124       if(x > max)                                 128       if(x > max)
125       {                                           129       {
126         max = x;                                  130         max = x;
127       }                                           131       }
128       if(x != 0.0 && x < min)                     132       if(x != 0.0 && x < min)
129       {                                           133       {
130         min = x;                                  134         min = x;
131       }                                           135       }
132     }                                             136     }
133                                                   137 
134     // Scale if there are large or very small     138     // Scale if there are large or very small coefficients.
135     // Computes a scale factor to multiply the    139     // Computes a scale factor to multiply the coefficients of the
136     // polynomial. The scaling is done to avoi    140     // polynomial. The scaling is done to avoid overflow and to
137     // avoid undetected underflow interfering     141     // avoid undetected underflow interfering with the convergence
138     // criterion. The factor is a power of the    142     // criterion. The factor is a power of the base.
139     //                                            143     //
140     sc = lo / min;                                144     sc = lo / min;
141                                                   145 
142     if(((sc <= 1.0) && (max >= 10.0)) || ((sc     146     if(((sc <= 1.0) && (max >= 10.0)) || ((sc > 1.0) && (infin / sc >= max)) ||
143        ((infin / sc >= max) && (max >= 10)))      147        ((infin / sc >= max) && (max >= 10)))
144     {                                             148     {
145       if(!(sc != 0.0))                            149       if(!(sc != 0.0))
146       {                                           150       {
147         sc = smalno;                              151         sc = smalno;
148       }                                           152       }
149       l      = (G4int)(G4Log(sc) / G4Log(base)    153       l      = (G4int)(G4Log(sc) / G4Log(base) + 0.5);
150       factor = power->powN(base, l);              154       factor = power->powN(base, l);
151       if(factor != 1.0)                           155       if(factor != 1.0)
152       {                                           156       {
153         for(i = 0; i <= n; ++i)                   157         for(i = 0; i <= n; ++i)
154         {                                         158         {
155           p[i] = factor * p[i];                   159           p[i] = factor * p[i];
156         }  // Scale polynomial.                   160         }  // Scale polynomial.
157       }                                           161       }
158     }                                             162     }
159                                                   163 
160     // Compute lower bound on moduli of roots.    164     // Compute lower bound on moduli of roots.
161     //                                            165     //
162     for(i = 0; i <= n; ++i)                       166     for(i = 0; i <= n; ++i)
163     {                                             167     {
164       pt[i] = (std::fabs(p[i]));                  168       pt[i] = (std::fabs(p[i]));
165     }                                             169     }
166     pt[n] = -pt[n];                               170     pt[n] = -pt[n];
167                                                   171 
168     // Compute upper estimate of bound.           172     // Compute upper estimate of bound.
169     //                                            173     //
170     x = G4Exp((G4Log(-pt[n]) - G4Log(pt[0])) /    174     x = G4Exp((G4Log(-pt[n]) - G4Log(pt[0])) / (G4double) n);
171                                                   175 
172     // If Newton step at the origin is better,    176     // If Newton step at the origin is better, use it.
173     //                                            177     //
174     if(pt[n - 1] != 0.0)                          178     if(pt[n - 1] != 0.0)
175     {                                             179     {
176       xm = -pt[n] / pt[n - 1];                    180       xm = -pt[n] / pt[n - 1];
177       if(xm < x)                                  181       if(xm < x)
178       {                                           182       {
179         x = xm;                                   183         x = xm;
180       }                                           184       }
181     }                                             185     }
182                                                   186 
183     // Chop the interval (0,x) until ff <= 0      187     // Chop the interval (0,x) until ff <= 0
184     //                                            188     //
185     while(true)                                << 189     while(1)
186     {                                             190     {
187       xm = x * 0.1;                               191       xm = x * 0.1;
188       ff = pt[0];                                 192       ff = pt[0];
189       for(i = 1; i <= n; ++i)                     193       for(i = 1; i <= n; ++i)
190       {                                           194       {
191         ff = ff * xm + pt[i];                     195         ff = ff * xm + pt[i];
192       }                                           196       }
193       if(ff <= 0.0)                               197       if(ff <= 0.0)
194       {                                           198       {
195         break;                                    199         break;
196       }                                           200       }
197       x = xm;                                     201       x = xm;
198     }                                             202     }
199     dx = x;                                       203     dx = x;
200                                                   204 
201     // Do Newton interation until x converges     205     // Do Newton interation until x converges to two decimal places.
202     //                                            206     //
203     while(std::fabs(dx / x) > 0.005)              207     while(std::fabs(dx / x) > 0.005)
204     {                                             208     {
205       ff = pt[0];                                 209       ff = pt[0];
206       df = ff;                                    210       df = ff;
207       for(i = 1; i < n; ++i)                      211       for(i = 1; i < n; ++i)
208       {                                           212       {
209         ff = ff * x + pt[i];                      213         ff = ff * x + pt[i];
210         df = df * x + ff;                         214         df = df * x + ff;
211       }                                           215       }
212       ff = ff * x + pt[n];                        216       ff = ff * x + pt[n];
213       dx = ff / df;                               217       dx = ff / df;
214       x -= dx;                                    218       x -= dx;
215     }                                             219     }
216     bnd = x;                                      220     bnd = x;
217                                                   221 
218     // Compute the derivative as the initial k    222     // Compute the derivative as the initial k polynomial
219     // and do 5 steps with no shift.              223     // and do 5 steps with no shift.
220     //                                            224     //
221     nm1 = n - 1;                                  225     nm1 = n - 1;
222     for(i = 1; i < n; ++i)                        226     for(i = 1; i < n; ++i)
223     {                                             227     {
224       k[i] = (G4double)(n - i) * p[i] / (G4dou    228       k[i] = (G4double)(n - i) * p[i] / (G4double) n;
225     }                                             229     }
226     k[0]  = p[0];                                 230     k[0]  = p[0];
227     aa    = p[n];                                 231     aa    = p[n];
228     bb    = p[n - 1];                             232     bb    = p[n - 1];
229     zerok = static_cast<G4int>(k[n - 1] == 0); << 233     zerok = (k[n - 1] == 0);
230     for(jj = 0; jj < 5; ++jj)                     234     for(jj = 0; jj < 5; ++jj)
231     {                                             235     {
232       cc = k[n - 1];                              236       cc = k[n - 1];
233       if(zerok == 0)  // Use a scaled form of  << 237       if(!zerok)  // Use a scaled form of recurrence if k at 0 is nonzero.
234       {                                           238       {
235         // Use a scaled form of recurrence if     239         // Use a scaled form of recurrence if value of k at 0 is nonzero.
236         //                                        240         //
237         t = -aa / cc;                             241         t = -aa / cc;
238         for(i = 0; i < nm1; ++i)                  242         for(i = 0; i < nm1; ++i)
239         {                                         243         {
240           j    = n - i - 1;                       244           j    = n - i - 1;
241           k[j] = t * k[j - 1] + p[j];             245           k[j] = t * k[j - 1] + p[j];
242         }                                         246         }
243         k[0]  = p[0];                             247         k[0]  = p[0];
244         zerok =                                << 248         zerok = (std::fabs(k[n - 1]) <= std::fabs(bb) * eta * 10.0);
245           static_cast<G4int>(std::fabs(k[n - 1 << 
246       }                                           249       }
247       else  // Use unscaled form of recurrence    250       else  // Use unscaled form of recurrence.
248       {                                           251       {
249         for(i = 0; i < nm1; ++i)                  252         for(i = 0; i < nm1; ++i)
250         {                                         253         {
251           j    = n - i - 1;                       254           j    = n - i - 1;
252           k[j] = k[j - 1];                        255           k[j] = k[j - 1];
253         }                                         256         }
254         k[0]  = 0.0;                              257         k[0]  = 0.0;
255         zerok = static_cast<G4int>(!(k[n - 1]  << 258         zerok = (!(k[n - 1] != 0.0));
256       }                                           259       }
257     }                                             260     }
258                                                   261 
259     // Save k for restarts with new shifts.       262     // Save k for restarts with new shifts.
260     //                                            263     //
261     for(i = 0; i < n; ++i)                        264     for(i = 0; i < n; ++i)
262     {                                             265     {
263       temp[i] = k[i];                             266       temp[i] = k[i];
264     }                                             267     }
265                                                   268 
266     // Loop to select the quadratic correspond    269     // Loop to select the quadratic corresponding to each new shift.
267     //                                            270     //
268     for(cnt = 0; cnt < 20; ++cnt)                 271     for(cnt = 0; cnt < 20; ++cnt)
269     {                                             272     {
270       // Quadratic corresponds to a double shi    273       // Quadratic corresponds to a double shift to a
271       // non-real point and its complex conjug    274       // non-real point and its complex conjugate. The point
272       // has modulus bnd and amplitude rotated    275       // has modulus bnd and amplitude rotated by 94 degrees
273       // from the previous shift.                 276       // from the previous shift.
274       //                                          277       //
275       xxx = cosr * xo - sinr * yo;                278       xxx = cosr * xo - sinr * yo;
276       yo  = sinr * xo + cosr * yo;                279       yo  = sinr * xo + cosr * yo;
277       xo  = xxx;                                  280       xo  = xxx;
278       sr  = bnd * xo;                             281       sr  = bnd * xo;
279       si  = bnd * yo;                             282       si  = bnd * yo;
280       u   = -2.0 * sr;                            283       u   = -2.0 * sr;
281       v   = bnd;                                  284       v   = bnd;
282       ComputeFixedShiftPolynomial(20 * (cnt +     285       ComputeFixedShiftPolynomial(20 * (cnt + 1), &nz);
283       if(nz != 0)                                 286       if(nz != 0)
284       {                                           287       {
285         // The second stage jumps directly to     288         // The second stage jumps directly to one of the third
286         // stage iterations and returns here i    289         // stage iterations and returns here if successful.
287         // Deflate the polynomial, store the z    290         // Deflate the polynomial, store the zero or zeros and
288         // return to the main algorithm.          291         // return to the main algorithm.
289         //                                        292         //
290         j        = degr - n;                      293         j        = degr - n;
291         zeror[j] = szr;                           294         zeror[j] = szr;
292         zeroi[j] = szi;                           295         zeroi[j] = szi;
293         n -= nz;                                  296         n -= nz;
294         for(i = 0; i <= n; ++i)                   297         for(i = 0; i <= n; ++i)
295         {                                         298         {
296           p[i] = qp[i];                           299           p[i] = qp[i];
297         }                                         300         }
298         if(nz != 1)                               301         if(nz != 1)
299         {                                         302         {
300           zeror[j + 1] = lzr;                     303           zeror[j + 1] = lzr;
301           zeroi[j + 1] = lzi;                     304           zeroi[j + 1] = lzi;
302         }                                         305         }
303         break;                                    306         break;
304       }                                           307       }
305                                                << 308       else
306       // If the iteration is unsuccessful anot << 
307       // is chosen after restoring k.          << 
308       //                                       << 
309       for(i = 0; i < n; ++i)                   << 
310       {                                           309       {
311         k[i] = temp[i];                        << 310         // If the iteration is unsuccessful another quadratic
                                                   >> 311         // is chosen after restoring k.
                                                   >> 312         //
                                                   >> 313         for(i = 0; i < n; ++i)
                                                   >> 314         {
                                                   >> 315           k[i] = temp[i];
                                                   >> 316         }
312       }                                           317       }
313                                                << 
314     }                                             318     }
315   } while(nz != 0);  // End of initial DO loop    319   } while(nz != 0);  // End of initial DO loop
316                                                   320 
317   // Return with failure if no convergence wit    321   // Return with failure if no convergence with 20 shifts.
318   //                                              322   //
319   return degr - n;                                323   return degr - n;
320 }                                                 324 }
321                                                   325 
322 void G4JTPolynomialSolver::ComputeFixedShiftPo    326 void G4JTPolynomialSolver::ComputeFixedShiftPolynomial(G4int l2, G4int* nz)
323 {                                                 327 {
324   // Computes up to L2 fixed shift k-polynomia    328   // Computes up to L2 fixed shift k-polynomials, testing for convergence
325   // in the linear or quadratic case. Initiate    329   // in the linear or quadratic case. Initiates one of the variable shift
326   // iterations and returns with the number of    330   // iterations and returns with the number of zeros found.
327                                                   331 
328   G4double svu = 0.0, svv = 0.0, ui = 0.0, vi     332   G4double svu = 0.0, svv = 0.0, ui = 0.0, vi = 0.0, xs = 0.0;
329   G4double betas = 0.25, betav = 0.25, oss = s    333   G4double betas = 0.25, betav = 0.25, oss = sr, ovv = v, ss = 0.0, vv = 0.0,
330            ts = 1.0, tv = 1.0;                    334            ts = 1.0, tv = 1.0;
331   G4double ots = 0.0, otv = 0.0;                  335   G4double ots = 0.0, otv = 0.0;
332   G4double tvv = 1.0, tss = 1.0;                  336   G4double tvv = 1.0, tss = 1.0;
333   G4int type = 0, i = 0, j = 0, iflag = 0, vpa    337   G4int type = 0, i = 0, j = 0, iflag = 0, vpass = 0, spass = 0, vtry = 0,
334         stry = 0;                                 338         stry = 0;
335                                                   339 
336   *nz = 0;                                        340   *nz = 0;
337                                                   341 
338   // Evaluate polynomial by synthetic division    342   // Evaluate polynomial by synthetic division.
339   //                                              343   //
340   QuadraticSyntheticDivision(n, &u, &v, p, qp,    344   QuadraticSyntheticDivision(n, &u, &v, p, qp, &a, &b);
341   ComputeScalarFactors(&type);                    345   ComputeScalarFactors(&type);
342   for(j = 0; j < l2; ++j)                         346   for(j = 0; j < l2; ++j)
343   {                                               347   {
344     // Calculate next k polynomial and estimat    348     // Calculate next k polynomial and estimate v.
345     //                                            349     //
346     ComputeNextPolynomial(&type);                 350     ComputeNextPolynomial(&type);
347     ComputeScalarFactors(&type);                  351     ComputeScalarFactors(&type);
348     ComputeNewEstimate(type, &ui, &vi);           352     ComputeNewEstimate(type, &ui, &vi);
349     vv = vi;                                      353     vv = vi;
350                                                   354 
351     // Estimate xs.                               355     // Estimate xs.
352     //                                            356     //
353     ss = 0.0;                                     357     ss = 0.0;
354     if(k[n - 1] != 0.0)                           358     if(k[n - 1] != 0.0)
355     {                                             359     {
356       ss = -p[n] / k[n - 1];                      360       ss = -p[n] / k[n - 1];
357     }                                             361     }
358     tv = 1.0;                                     362     tv = 1.0;
359     ts = 1.0;                                     363     ts = 1.0;
360     if(j == 0 || type == 3)                       364     if(j == 0 || type == 3)
361     {                                             365     {
362       ovv = vv;                                   366       ovv = vv;
363       oss = ss;                                   367       oss = ss;
364       otv = tv;                                   368       otv = tv;
365       ots = ts;                                   369       ots = ts;
366       continue;                                   370       continue;
367     }                                             371     }
368                                                   372 
369     // Compute relative measures of convergenc    373     // Compute relative measures of convergence of xs and v sequences.
370     //                                            374     //
371     if(vv != 0.0)                                 375     if(vv != 0.0)
372     {                                             376     {
373       tv = std::fabs((vv - ovv) / vv);            377       tv = std::fabs((vv - ovv) / vv);
374     }                                             378     }
375     if(ss != 0.0)                                 379     if(ss != 0.0)
376     {                                             380     {
377       ts = std::fabs((ss - oss) / ss);            381       ts = std::fabs((ss - oss) / ss);
378     }                                             382     }
379                                                   383 
380     // If decreasing, multiply two most recent    384     // If decreasing, multiply two most recent convergence measures.
381     tvv = 1.0;                                    385     tvv = 1.0;
382     if(tv < otv)                                  386     if(tv < otv)
383     {                                             387     {
384       tvv = tv * otv;                             388       tvv = tv * otv;
385     }                                             389     }
386     tss = 1.0;                                    390     tss = 1.0;
387     if(ts < ots)                                  391     if(ts < ots)
388     {                                             392     {
389       tss = ts * ots;                             393       tss = ts * ots;
390     }                                             394     }
391                                                   395 
392     // Compare with convergence criteria.         396     // Compare with convergence criteria.
393     vpass = static_cast<G4int>(tvv < betav);   << 397     vpass = (tvv < betav);
394     spass = static_cast<G4int>(tss < betas);   << 398     spass = (tss < betas);
395     if(!((spass != 0) || (vpass != 0)))        << 399     if(!(spass || vpass))
396     {                                             400     {
397       ovv = vv;                                   401       ovv = vv;
398       oss = ss;                                   402       oss = ss;
399       otv = tv;                                   403       otv = tv;
400       ots = ts;                                   404       ots = ts;
401       continue;                                   405       continue;
402     }                                             406     }
403                                                   407 
404     // At least one sequence has passed the co    408     // At least one sequence has passed the convergence test.
405     // Store variables before iterating.          409     // Store variables before iterating.
406     //                                            410     //
407     svu = u;                                      411     svu = u;
408     svv = v;                                      412     svv = v;
409     for(i = 0; i < n; ++i)                        413     for(i = 0; i < n; ++i)
410     {                                             414     {
411       svk[i] = k[i];                              415       svk[i] = k[i];
412     }                                             416     }
413     xs = ss;                                      417     xs = ss;
414                                                   418 
415     // Choose iteration according to the faste    419     // Choose iteration according to the fastest converging sequence.
416     //                                            420     //
417     vtry = 0;                                     421     vtry = 0;
418     stry = 0;                                     422     stry = 0;
419     if(((spass != 0) && (vpass == 0)) || (tss  << 423     if((spass && (!vpass)) || (tss < tvv))
420     {                                             424     {
421       RealPolynomialIteration(&xs, nz, &iflag)    425       RealPolynomialIteration(&xs, nz, &iflag);
422       if(*nz > 0)                                 426       if(*nz > 0)
423       {                                           427       {
424         return;                                   428         return;
425       }                                           429       }
426                                                   430 
427       // Linear iteration has failed. Flag tha    431       // Linear iteration has failed. Flag that it has been
428       // tried and decrease the convergence cr    432       // tried and decrease the convergence criterion.
429       //                                          433       //
430       stry = 1;                                   434       stry = 1;
431       betas *= 0.25;                              435       betas *= 0.25;
432       if(iflag == 0)                              436       if(iflag == 0)
433       {                                           437       {
434         goto _restore_variables;                  438         goto _restore_variables;
435       }                                           439       }
436                                                   440 
437       // If linear iteration signals an almost    441       // If linear iteration signals an almost double real
438       // zero attempt quadratic iteration.        442       // zero attempt quadratic iteration.
439       //                                          443       //
440       ui = -(xs + xs);                            444       ui = -(xs + xs);
441       vi = xs * xs;                               445       vi = xs * xs;
442     }                                             446     }
443                                                   447 
444   _quadratic_iteration:                           448   _quadratic_iteration:
445                                                   449 
446     do                                            450     do
447     {                                             451     {
448       QuadraticPolynomialIteration(&ui, &vi, n    452       QuadraticPolynomialIteration(&ui, &vi, nz);
449       if(*nz > 0)                                 453       if(*nz > 0)
450       {                                           454       {
451         return;                                   455         return;
452       }                                           456       }
453                                                   457 
454       // Quadratic iteration has failed. Flag     458       // Quadratic iteration has failed. Flag that it has
455       // been tried and decrease the convergen    459       // been tried and decrease the convergence criterion.
456       //                                          460       //
457       vtry = 1;                                   461       vtry = 1;
458       betav *= 0.25;                              462       betav *= 0.25;
459                                                   463 
460       // Try linear iteration if it has not be    464       // Try linear iteration if it has not been tried and
461       // the S sequence is converging.            465       // the S sequence is converging.
462       //                                          466       //
463       if((stry != 0) || (spass == 0))          << 467       if(stry || !spass)
464       {                                           468       {
465         break;                                    469         break;
466       }                                           470       }
467       for(i = 0; i < n; ++i)                      471       for(i = 0; i < n; ++i)
468       {                                           472       {
469         k[i] = svk[i];                            473         k[i] = svk[i];
470       }                                           474       }
471       RealPolynomialIteration(&xs, nz, &iflag)    475       RealPolynomialIteration(&xs, nz, &iflag);
472       if(*nz > 0)                                 476       if(*nz > 0)
473       {                                           477       {
474         return;                                   478         return;
475       }                                           479       }
476                                                   480 
477       // Linear iteration has failed. Flag tha    481       // Linear iteration has failed. Flag that it has been
478       // tried and decrease the convergence cr    482       // tried and decrease the convergence criterion.
479       //                                          483       //
480       stry = 1;                                   484       stry = 1;
481       betas *= 0.25;                              485       betas *= 0.25;
482       if(iflag == 0)                              486       if(iflag == 0)
483       {                                           487       {
484         break;                                    488         break;
485       }                                           489       }
486                                                   490 
487       // If linear iteration signals an almost    491       // If linear iteration signals an almost double real
488       // zero attempt quadratic iteration.        492       // zero attempt quadratic iteration.
489       //                                          493       //
490       ui = -(xs + xs);                            494       ui = -(xs + xs);
491       vi = xs * xs;                               495       vi = xs * xs;
492     } while(iflag != 0);                          496     } while(iflag != 0);
493                                                   497 
494     // Restore variables.                         498     // Restore variables.
495                                                   499 
496   _restore_variables:                             500   _restore_variables:
497                                                   501 
498     u = svu;                                      502     u = svu;
499     v = svv;                                      503     v = svv;
500     for(i = 0; i < n; ++i)                        504     for(i = 0; i < n; ++i)
501     {                                             505     {
502       k[i] = svk[i];                              506       k[i] = svk[i];
503     }                                             507     }
504                                                   508 
505     // Try quadratic iteration if it has not b    509     // Try quadratic iteration if it has not been tried
506     // and the V sequence is converging.          510     // and the V sequence is converging.
507     //                                            511     //
508     if((vpass != 0) && (vtry == 0))            << 512     if(vpass && !vtry)
509     {                                             513     {
510       goto _quadratic_iteration;                  514       goto _quadratic_iteration;
511     }                                             515     }
512                                                   516 
513     // Recompute QP and scalar values to conti    517     // Recompute QP and scalar values to continue the
514     // second stage.                              518     // second stage.
515     //                                            519     //
516     QuadraticSyntheticDivision(n, &u, &v, p, q    520     QuadraticSyntheticDivision(n, &u, &v, p, qp, &a, &b);
517     ComputeScalarFactors(&type);                  521     ComputeScalarFactors(&type);
518                                                   522 
519     ovv = vv;                                     523     ovv = vv;
520     oss = ss;                                     524     oss = ss;
521     otv = tv;                                     525     otv = tv;
522     ots = ts;                                     526     ots = ts;
523   }                                               527   }
524 }                                                 528 }
525                                                   529 
526 void G4JTPolynomialSolver::QuadraticPolynomial    530 void G4JTPolynomialSolver::QuadraticPolynomialIteration(G4double* uu,
527                                                   531                                                         G4double* vv, G4int* nz)
528 {                                                 532 {
529   // Variable-shift k-polynomial iteration for    533   // Variable-shift k-polynomial iteration for a
530   // quadratic factor converges only if the ze    534   // quadratic factor converges only if the zeros are
531   // equimodular or nearly so.                    535   // equimodular or nearly so.
532   // uu, vv - coefficients of starting quadrat    536   // uu, vv - coefficients of starting quadratic.
533   // nz - number of zeros found.                  537   // nz - number of zeros found.
534   //                                              538   //
535   G4double ui = 0.0, vi = 0.0;                    539   G4double ui = 0.0, vi = 0.0;
536   G4double omp    = 0.0;                          540   G4double omp    = 0.0;
537   G4double relstp = 0.0;                          541   G4double relstp = 0.0;
538   G4double mp = 0.0, ee = 0.0, t = 0.0, zm = 0    542   G4double mp = 0.0, ee = 0.0, t = 0.0, zm = 0.0;
539   G4int type = 0, i = 1, j = 0, tried = 0;        543   G4int type = 0, i = 1, j = 0, tried = 0;
540                                                   544 
541   *nz   = 0;                                      545   *nz   = 0;
542   tried = 0;                                      546   tried = 0;
543   u     = *uu;                                    547   u     = *uu;
544   v     = *vv;                                    548   v     = *vv;
545                                                   549 
546   // Main loop.                                   550   // Main loop.
547                                                   551 
548   while(true)                                  << 552   while(1)
549   {                                               553   {
550     Quadratic(1.0, u, v, &szr, &szi, &lzr, &lz    554     Quadratic(1.0, u, v, &szr, &szi, &lzr, &lzi);
551                                                   555 
552     // Return if roots of the quadratic are re    556     // Return if roots of the quadratic are real and not
553     // close to multiple or nearly equal and o    557     // close to multiple or nearly equal and of opposite
554     // sign.                                      558     // sign.
555     //                                            559     //
556     if(std::fabs(std::fabs(szr) - std::fabs(lz    560     if(std::fabs(std::fabs(szr) - std::fabs(lzr)) > 0.01 * std::fabs(lzr))
557     {                                             561     {
558       return;                                     562       return;
559     }                                             563     }
560                                                   564 
561     // Evaluate polynomial by quadratic synthe    565     // Evaluate polynomial by quadratic synthetic division.
562     //                                            566     //
563     QuadraticSyntheticDivision(n, &u, &v, p, q    567     QuadraticSyntheticDivision(n, &u, &v, p, qp, &a, &b);
564     mp = std::fabs(a - szr * b) + std::fabs(sz    568     mp = std::fabs(a - szr * b) + std::fabs(szi * b);
565                                                   569 
566     // Compute a rigorous bound on the roundin    570     // Compute a rigorous bound on the rounding error in evaluating p.
567     //                                            571     //
568     zm = std::sqrt(std::fabs(v));                 572     zm = std::sqrt(std::fabs(v));
569     ee = 2.0 * std::fabs(qp[0]);                  573     ee = 2.0 * std::fabs(qp[0]);
570     t  = -szr * b;                                574     t  = -szr * b;
571     for(i = 1; i < n; ++i)                        575     for(i = 1; i < n; ++i)
572     {                                             576     {
573       ee = ee * zm + std::fabs(qp[i]);            577       ee = ee * zm + std::fabs(qp[i]);
574     }                                             578     }
575     ee = ee * zm + std::fabs(a + t);              579     ee = ee * zm + std::fabs(a + t);
576     ee *= (5.0 * mre + 4.0 * are);                580     ee *= (5.0 * mre + 4.0 * are);
577     ee = ee - (5.0 * mre + 2.0 * are) * (std::    581     ee = ee - (5.0 * mre + 2.0 * are) * (std::fabs(a + t) + std::fabs(b) * zm) +
578          2.0 * are * std::fabs(t);                582          2.0 * are * std::fabs(t);
579                                                   583 
580     // Iteration has converged sufficiently if    584     // Iteration has converged sufficiently if the
581     // polynomial value is less than 20 times     585     // polynomial value is less than 20 times this bound.
582     //                                            586     //
583     if(mp <= 20.0 * ee)                           587     if(mp <= 20.0 * ee)
584     {                                             588     {
585       *nz = 2;                                    589       *nz = 2;
586       return;                                     590       return;
587     }                                             591     }
588     j++;                                          592     j++;
589                                                   593 
590     // Stop iteration after 20 steps.             594     // Stop iteration after 20 steps.
591     //                                            595     //
592     if(j > 20)                                    596     if(j > 20)
593     {                                             597     {
594       return;                                     598       return;
595     }                                             599     }
596     if(j >= 2)                                    600     if(j >= 2)
597     {                                             601     {
598       if(!(relstp > 0.01 || mp < omp || (tried << 602       if(!(relstp > 0.01 || mp < omp || tried))
599       {                                           603       {
600         // A cluster appears to be stalling th    604         // A cluster appears to be stalling the convergence.
601         // Five fixed shift steps are taken wi    605         // Five fixed shift steps are taken with a u,v close to the cluster.
602         //                                        606         //
603         if(relstp < eta)                          607         if(relstp < eta)
604         {                                         608         {
605           relstp = eta;                           609           relstp = eta;
606         }                                         610         }
607         relstp = std::sqrt(relstp);               611         relstp = std::sqrt(relstp);
608         u      = u - u * relstp;                  612         u      = u - u * relstp;
609         v      = v + v * relstp;                  613         v      = v + v * relstp;
610         QuadraticSyntheticDivision(n, &u, &v,     614         QuadraticSyntheticDivision(n, &u, &v, p, qp, &a, &b);
611         for(i = 0; i < 5; ++i)                    615         for(i = 0; i < 5; ++i)
612         {                                         616         {
613           ComputeScalarFactors(&type);            617           ComputeScalarFactors(&type);
614           ComputeNextPolynomial(&type);           618           ComputeNextPolynomial(&type);
615         }                                         619         }
616         tried = 1;                                620         tried = 1;
617         j     = 0;                                621         j     = 0;
618       }                                           622       }
619     }                                             623     }
620     omp = mp;                                     624     omp = mp;
621                                                   625 
622     // Calculate next k polynomial and new u a    626     // Calculate next k polynomial and new u and v.
623     //                                            627     //
624     ComputeScalarFactors(&type);                  628     ComputeScalarFactors(&type);
625     ComputeNextPolynomial(&type);                 629     ComputeNextPolynomial(&type);
626     ComputeScalarFactors(&type);                  630     ComputeScalarFactors(&type);
627     ComputeNewEstimate(type, &ui, &vi);           631     ComputeNewEstimate(type, &ui, &vi);
628                                                   632 
629     // If vi is zero the iteration is not conv    633     // If vi is zero the iteration is not converging.
630     //                                            634     //
631     if(!(vi != 0.0))                              635     if(!(vi != 0.0))
632     {                                             636     {
633       return;                                     637       return;
634     }                                             638     }
635     relstp = std::fabs((vi - v) / vi);            639     relstp = std::fabs((vi - v) / vi);
636     u      = ui;                                  640     u      = ui;
637     v      = vi;                                  641     v      = vi;
638   }                                               642   }
639 }                                                 643 }
640                                                   644 
641 void G4JTPolynomialSolver::RealPolynomialItera    645 void G4JTPolynomialSolver::RealPolynomialIteration(G4double* sss, G4int* nz,
642                                                   646                                                    G4int* iflag)
643 {                                                 647 {
644   // Variable-shift H polynomial iteration for    648   // Variable-shift H polynomial iteration for a real zero.
645   // sss - starting iterate                       649   // sss - starting iterate
646   // nz  - number of zeros found                  650   // nz  - number of zeros found
647   // iflag - flag to indicate a pair of zeros     651   // iflag - flag to indicate a pair of zeros near real axis.
648                                                   652 
649   G4double t   = 0.;                              653   G4double t   = 0.;
650   G4double omp = 0.;                              654   G4double omp = 0.;
651   G4double pv = 0.0, kv = 0.0, xs = *sss;         655   G4double pv = 0.0, kv = 0.0, xs = *sss;
652   G4double mx = 0.0, mp = 0.0, ee = 0.0;          656   G4double mx = 0.0, mp = 0.0, ee = 0.0;
653   G4int i = 1, j = 0;                             657   G4int i = 1, j = 0;
654                                                   658 
655   *nz    = 0;                                     659   *nz    = 0;
656   *iflag = 0;                                     660   *iflag = 0;
657                                                   661 
658   // Main loop                                    662   // Main loop
659   //                                              663   //
660   while(true)                                  << 664   while(1)
661   {                                               665   {
662     pv = p[0];                                    666     pv = p[0];
663                                                   667 
664     // Evaluate p at xs.                          668     // Evaluate p at xs.
665     //                                            669     //
666     qp[0] = pv;                                   670     qp[0] = pv;
667     for(i = 1; i <= n; ++i)                       671     for(i = 1; i <= n; ++i)
668     {                                             672     {
669       pv    = pv * xs + p[i];                     673       pv    = pv * xs + p[i];
670       qp[i] = pv;                                 674       qp[i] = pv;
671     }                                             675     }
672     mp = std::fabs(pv);                           676     mp = std::fabs(pv);
673                                                   677 
674     // Compute a rigorous bound on the error i    678     // Compute a rigorous bound on the error in evaluating p.
675     //                                            679     //
676     mx = std::fabs(xs);                           680     mx = std::fabs(xs);
677     ee = (mre / (are + mre)) * std::fabs(qp[0]    681     ee = (mre / (are + mre)) * std::fabs(qp[0]);
678     for(i = 1; i <= n; ++i)                       682     for(i = 1; i <= n; ++i)
679     {                                             683     {
680       ee = ee * mx + std::fabs(qp[i]);            684       ee = ee * mx + std::fabs(qp[i]);
681     }                                             685     }
682                                                   686 
683     // Iteration has converged sufficiently if    687     // Iteration has converged sufficiently if the polynomial
684     // value is less than 20 times this bound.    688     // value is less than 20 times this bound.
685     //                                            689     //
686     if(mp <= 20.0 * ((are + mre) * ee - mre *     690     if(mp <= 20.0 * ((are + mre) * ee - mre * mp))
687     {                                             691     {
688       *nz = 1;                                    692       *nz = 1;
689       szr = xs;                                   693       szr = xs;
690       szi = 0.0;                                  694       szi = 0.0;
691       return;                                     695       return;
692     }                                             696     }
693     j++;                                          697     j++;
694                                                   698 
695     // Stop iteration after 10 steps.             699     // Stop iteration after 10 steps.
696     //                                            700     //
697     if(j > 10)                                    701     if(j > 10)
698     {                                             702     {
699       return;                                     703       return;
700     }                                             704     }
701     if(j >= 2)                                    705     if(j >= 2)
702     {                                             706     {
703       if(!(std::fabs(t) > 0.001 * std::fabs(xs    707       if(!(std::fabs(t) > 0.001 * std::fabs(xs - t) || mp < omp))
704       {                                           708       {
705         // A cluster of zeros near the real ax    709         // A cluster of zeros near the real axis has been encountered.
706         // Return with iflag set to initiate a    710         // Return with iflag set to initiate a quadratic iteration.
707         //                                        711         //
708         *iflag = 1;                               712         *iflag = 1;
709         *sss   = xs;                              713         *sss   = xs;
710         return;                                   714         return;
711       }  // Return if the polynomial value has    715       }  // Return if the polynomial value has increased significantly.
712     }                                             716     }
713                                                   717 
714     omp = mp;                                     718     omp = mp;
715                                                   719 
716     //  Compute t, the next polynomial, and th    720     //  Compute t, the next polynomial, and the new iterate.
717     //                                            721     //
718     kv    = k[0];                                 722     kv    = k[0];
719     qk[0] = kv;                                   723     qk[0] = kv;
720     for(i = 1; i < n; ++i)                        724     for(i = 1; i < n; ++i)
721     {                                             725     {
722       kv    = kv * xs + k[i];                     726       kv    = kv * xs + k[i];
723       qk[i] = kv;                                 727       qk[i] = kv;
724     }                                             728     }
725     if(std::fabs(kv) <= std::fabs(k[n - 1]) *     729     if(std::fabs(kv) <= std::fabs(k[n - 1]) * 10.0 * eta)  // Use unscaled form.
726     {                                             730     {
727       k[0] = 0.0;                                 731       k[0] = 0.0;
728       for(i = 1; i < n; ++i)                      732       for(i = 1; i < n; ++i)
729       {                                           733       {
730         k[i] = qk[i - 1];                         734         k[i] = qk[i - 1];
731       }                                           735       }
732     }                                             736     }
733     else  // Use the scaled form of the recurr    737     else  // Use the scaled form of the recurrence if k at xs is nonzero.
734     {                                             738     {
735       t    = -pv / kv;                            739       t    = -pv / kv;
736       k[0] = qp[0];                               740       k[0] = qp[0];
737       for(i = 1; i < n; ++i)                      741       for(i = 1; i < n; ++i)
738       {                                           742       {
739         k[i] = t * qk[i - 1] + qp[i];             743         k[i] = t * qk[i - 1] + qp[i];
740       }                                           744       }
741     }                                             745     }
742     kv = k[0];                                    746     kv = k[0];
743     for(i = 1; i < n; ++i)                        747     for(i = 1; i < n; ++i)
744     {                                             748     {
745       kv = kv * xs + k[i];                        749       kv = kv * xs + k[i];
746     }                                             750     }
747     t = 0.0;                                      751     t = 0.0;
748     if(std::fabs(kv) > std::fabs(k[n - 1] * 10    752     if(std::fabs(kv) > std::fabs(k[n - 1] * 10.0 * eta))
749     {                                             753     {
750       t = -pv / kv;                               754       t = -pv / kv;
751     }                                             755     }
752     xs += t;                                      756     xs += t;
753   }                                               757   }
754 }                                                 758 }
755                                                   759 
756 void G4JTPolynomialSolver::ComputeScalarFactor    760 void G4JTPolynomialSolver::ComputeScalarFactors(G4int* type)
757 {                                                 761 {
758   // This function calculates scalar quantitie    762   // This function calculates scalar quantities used to
759   // compute the next k polynomial and new est    763   // compute the next k polynomial and new estimates of
760   // the quadratic coefficients.                  764   // the quadratic coefficients.
761   // type - integer variable set here indicati    765   // type - integer variable set here indicating how the
762   // calculations are normalized to avoid over    766   // calculations are normalized to avoid overflow.
763                                                   767 
764   //  Synthetic division of k by the quadratic    768   //  Synthetic division of k by the quadratic 1,u,v
765   //                                              769   //
766   QuadraticSyntheticDivision(n - 1, &u, &v, k,    770   QuadraticSyntheticDivision(n - 1, &u, &v, k, qk, &c, &d);
767   if(std::fabs(c) <= std::fabs(k[n - 1] * 100.    771   if(std::fabs(c) <= std::fabs(k[n - 1] * 100.0 * eta))
768   {                                               772   {
769     if(std::fabs(d) <= std::fabs(k[n - 2] * 10    773     if(std::fabs(d) <= std::fabs(k[n - 2] * 100.0 * eta))
770     {                                             774     {
771       *type = 3;  // Type=3 indicates the quad    775       *type = 3;  // Type=3 indicates the quadratic is almost a factor of k.
772       return;                                     776       return;
773     }                                             777     }
774   }                                               778   }
775                                                   779 
776   if(std::fabs(d) < std::fabs(c))                 780   if(std::fabs(d) < std::fabs(c))
777   {                                               781   {
778     *type = 1;  // Type=1 indicates that all f    782     *type = 1;  // Type=1 indicates that all formulas are divided by c.
779     e     = a / c;                                783     e     = a / c;
780     f     = d / c;                                784     f     = d / c;
781     g     = u * e;                                785     g     = u * e;
782     h     = v * b;                                786     h     = v * b;
783     a3    = a * e + (h / c + g) * b;              787     a3    = a * e + (h / c + g) * b;
784     a1    = b - a * (d / c);                      788     a1    = b - a * (d / c);
785     a7    = a + g * d + h * f;                    789     a7    = a + g * d + h * f;
786     return;                                       790     return;
787   }                                               791   }
788   *type = 2;  // Type=2 indicates that all for    792   *type = 2;  // Type=2 indicates that all formulas are divided by d.
789   e     = a / d;                                  793   e     = a / d;
790   f     = c / d;                                  794   f     = c / d;
791   g     = u * b;                                  795   g     = u * b;
792   h     = v * b;                                  796   h     = v * b;
793   a3    = (a + g) * e + h * (b / d);              797   a3    = (a + g) * e + h * (b / d);
794   a1    = b * f - a;                              798   a1    = b * f - a;
795   a7    = (f + u) * a + h;                        799   a7    = (f + u) * a + h;
796 }                                                 800 }
797                                                   801 
798 void G4JTPolynomialSolver::ComputeNextPolynomi    802 void G4JTPolynomialSolver::ComputeNextPolynomial(G4int* type)
799 {                                                 803 {
800   // Computes the next k polynomials using sca    804   // Computes the next k polynomials using scalars
801   // computed in ComputeScalarFactors.            805   // computed in ComputeScalarFactors.
802                                                   806 
803   G4int i = 2;                                    807   G4int i = 2;
804                                                   808 
805   if(*type == 3)  // Use unscaled form of the     809   if(*type == 3)  // Use unscaled form of the recurrence if type is 3.
806   {                                               810   {
807     k[0] = 0.0;                                   811     k[0] = 0.0;
808     k[1] = 0.0;                                   812     k[1] = 0.0;
809     for(i = 2; i < n; ++i)                        813     for(i = 2; i < n; ++i)
810     {                                             814     {
811       k[i] = qk[i - 2];                           815       k[i] = qk[i - 2];
812     }                                             816     }
813     return;                                       817     return;
814   }                                               818   }
815   G4double temp = a;                              819   G4double temp = a;
816   if(*type == 1)                                  820   if(*type == 1)
817   {                                               821   {
818     temp = b;                                     822     temp = b;
819   }                                               823   }
820   if(std::fabs(a1) <= std::fabs(temp) * eta *     824   if(std::fabs(a1) <= std::fabs(temp) * eta * 10.0)
821   {                                               825   {
822     // If a1 is nearly zero then use a special    826     // If a1 is nearly zero then use a special form of the recurrence.
823     //                                            827     //
824     k[0] = 0.0;                                   828     k[0] = 0.0;
825     k[1] = -a7 * qp[0];                           829     k[1] = -a7 * qp[0];
826     for(i = 2; i < n; ++i)                        830     for(i = 2; i < n; ++i)
827     {                                             831     {
828       k[i] = a3 * qk[i - 2] - a7 * qp[i - 1];     832       k[i] = a3 * qk[i - 2] - a7 * qp[i - 1];
829     }                                             833     }
830     return;                                       834     return;
831   }                                               835   }
832                                                   836 
833   // Use scaled form of the recurrence.           837   // Use scaled form of the recurrence.
834   //                                              838   //
835   a7 /= a1;                                       839   a7 /= a1;
836   a3 /= a1;                                       840   a3 /= a1;
837   k[0] = qp[0];                                   841   k[0] = qp[0];
838   k[1] = qp[1] - a7 * qp[0];                      842   k[1] = qp[1] - a7 * qp[0];
839   for(i = 2; i < n; ++i)                          843   for(i = 2; i < n; ++i)
840   {                                               844   {
841     k[i] = a3 * qk[i - 2] - a7 * qp[i - 1] + q    845     k[i] = a3 * qk[i - 2] - a7 * qp[i - 1] + qp[i];
842   }                                               846   }
843 }                                                 847 }
844                                                   848 
845 void G4JTPolynomialSolver::ComputeNewEstimate(    849 void G4JTPolynomialSolver::ComputeNewEstimate(G4int type, G4double* uu,
846                                                   850                                               G4double* vv)
847 {                                                 851 {
848   // Compute new estimates of the quadratic co    852   // Compute new estimates of the quadratic coefficients
849   // using the scalars computed in calcsc.        853   // using the scalars computed in calcsc.
850                                                   854 
851   G4double a4 = 0.0, a5 = 0.0, b1 = 0.0, b2 =     855   G4double a4 = 0.0, a5 = 0.0, b1 = 0.0, b2 = 0.0, c1 = 0.0, c2 = 0.0, c3 = 0.0,
852            c4 = 0.0, temp = 0.0;                  856            c4 = 0.0, temp = 0.0;
853                                                   857 
854   // Use formulas appropriate to setting of ty    858   // Use formulas appropriate to setting of type.
855   //                                              859   //
856   if(type == 3)  //  If type=3 the quadratic i    860   if(type == 3)  //  If type=3 the quadratic is zeroed.
857   {                                               861   {
858     *uu = 0.0;                                    862     *uu = 0.0;
859     *vv = 0.0;                                    863     *vv = 0.0;
860     return;                                       864     return;
861   }                                               865   }
862   if(type == 2)                                   866   if(type == 2)
863   {                                               867   {
864     a4 = (a + g) * f + h;                         868     a4 = (a + g) * f + h;
865     a5 = (f + u) * c + v * d;                     869     a5 = (f + u) * c + v * d;
866   }                                               870   }
867   else                                            871   else
868   {                                               872   {
869     a4 = a + u * b + h * f;                       873     a4 = a + u * b + h * f;
870     a5 = c + (u + v * f) * d;                     874     a5 = c + (u + v * f) * d;
871   }                                               875   }
872                                                   876 
873   //  Evaluate new quadratic coefficients.        877   //  Evaluate new quadratic coefficients.
874   //                                              878   //
875   b1   = -k[n - 1] / p[n];                        879   b1   = -k[n - 1] / p[n];
876   b2   = -(k[n - 2] + b1 * p[n - 1]) / p[n];      880   b2   = -(k[n - 2] + b1 * p[n - 1]) / p[n];
877   c1   = v * b2 * a1;                             881   c1   = v * b2 * a1;
878   c2   = b1 * a7;                                 882   c2   = b1 * a7;
879   c3   = b1 * b1 * a3;                            883   c3   = b1 * b1 * a3;
880   c4   = c1 - c2 - c3;                            884   c4   = c1 - c2 - c3;
881   temp = a5 + b1 * a4 - c4;                       885   temp = a5 + b1 * a4 - c4;
882   if(!(temp != 0.0))                              886   if(!(temp != 0.0))
883   {                                               887   {
884     *uu = 0.0;                                    888     *uu = 0.0;
885     *vv = 0.0;                                    889     *vv = 0.0;
886     return;                                       890     return;
887   }                                               891   }
888   *uu = u - (u * (c3 + c2) + v * (b1 * a1 + b2    892   *uu = u - (u * (c3 + c2) + v * (b1 * a1 + b2 * a7)) / temp;
889   *vv = v * (1.0 + c4 / temp);                    893   *vv = v * (1.0 + c4 / temp);
890   return;                                         894   return;
891 }                                                 895 }
892                                                   896 
893 void G4JTPolynomialSolver::QuadraticSyntheticD    897 void G4JTPolynomialSolver::QuadraticSyntheticDivision(
894   G4int nn, G4double* uu, G4double* vv, std::v    898   G4int nn, G4double* uu, G4double* vv, std::vector<G4double>& pp,
895   std::vector<G4double>& qq, G4double* aa, G4d    899   std::vector<G4double>& qq, G4double* aa, G4double* bb)
896 {                                                 900 {
897   // Divides pp by the quadratic 1,uu,vv placi    901   // Divides pp by the quadratic 1,uu,vv placing the quotient
898   // in qq and the remainder in aa,bb.            902   // in qq and the remainder in aa,bb.
899                                                   903 
900   G4double cc = 0.0;                              904   G4double cc = 0.0;
901   *bb         = pp[0];                            905   *bb         = pp[0];
902   qq[0]       = *bb;                              906   qq[0]       = *bb;
903   *aa         = pp[1] - (*bb) * (*uu);            907   *aa         = pp[1] - (*bb) * (*uu);
904   qq[1]       = *aa;                              908   qq[1]       = *aa;
905   for(G4int i = 2; i <= nn; ++i)                  909   for(G4int i = 2; i <= nn; ++i)
906   {                                               910   {
907     cc    = pp[i] - (*aa) * (*uu) - (*bb) * (*    911     cc    = pp[i] - (*aa) * (*uu) - (*bb) * (*vv);
908     qq[i] = cc;                                   912     qq[i] = cc;
909     *bb   = *aa;                                  913     *bb   = *aa;
910     *aa   = cc;                                   914     *aa   = cc;
911   }                                               915   }
912 }                                                 916 }
913                                                   917 
914 void G4JTPolynomialSolver::Quadratic(G4double     918 void G4JTPolynomialSolver::Quadratic(G4double aa, G4double b1, G4double cc,
915                                      G4double*    919                                      G4double* ssr, G4double* ssi, G4double* lr,
916                                      G4double*    920                                      G4double* li)
917 {                                                 921 {
918   // Calculate the zeros of the quadratic aa*z    922   // Calculate the zeros of the quadratic aa*z^2 + b1*z + cc.
919   // The quadratic formula, modified to avoid     923   // The quadratic formula, modified to avoid overflow, is used
920   // to find the larger zero if the zeros are     924   // to find the larger zero if the zeros are real and both
921   // are complex. The smaller real zero is fou    925   // are complex. The smaller real zero is found directly from
922   // the product of the zeros c/a.                926   // the product of the zeros c/a.
923                                                   927 
924   G4double bb = 0.0, dd = 0.0, ee = 0.0;          928   G4double bb = 0.0, dd = 0.0, ee = 0.0;
925                                                   929 
926   if(!(aa != 0.0))  // less than two roots        930   if(!(aa != 0.0))  // less than two roots
927   {                                               931   {
928     if(b1 != 0.0)                                 932     if(b1 != 0.0)
929     {                                             933     {
930       *ssr = -cc / b1;                            934       *ssr = -cc / b1;
931     }                                             935     }
932     else                                          936     else
933     {                                             937     {
934       *ssr = 0.0;                                 938       *ssr = 0.0;
935     }                                             939     }
936     *lr  = 0.0;                                   940     *lr  = 0.0;
937     *ssi = 0.0;                                   941     *ssi = 0.0;
938     *li  = 0.0;                                   942     *li  = 0.0;
939     return;                                       943     return;
940   }                                               944   }
941   if(!(cc != 0.0))  // one real root, one zero    945   if(!(cc != 0.0))  // one real root, one zero root
942   {                                               946   {
943     *ssr = 0.0;                                   947     *ssr = 0.0;
944     *lr  = -b1 / aa;                              948     *lr  = -b1 / aa;
945     *ssi = 0.0;                                   949     *ssi = 0.0;
946     *li  = 0.0;                                   950     *li  = 0.0;
947     return;                                       951     return;
948   }                                               952   }
949                                                   953 
950   // Compute discriminant avoiding overflow.      954   // Compute discriminant avoiding overflow.
951   //                                              955   //
952   bb = b1 / 2.0;                                  956   bb = b1 / 2.0;
953   if(std::fabs(bb) < std::fabs(cc))               957   if(std::fabs(bb) < std::fabs(cc))
954   {                                               958   {
955     if(cc < 0.0)                                  959     if(cc < 0.0)
956     {                                             960     {
957       ee = -aa;                                   961       ee = -aa;
958     }                                             962     }
959     else                                          963     else
960     {                                             964     {
961       ee = aa;                                    965       ee = aa;
962     }                                             966     }
963     ee = bb * (bb / std::fabs(cc)) - ee;          967     ee = bb * (bb / std::fabs(cc)) - ee;
964     dd = std::sqrt(std::fabs(ee)) * std::sqrt(    968     dd = std::sqrt(std::fabs(ee)) * std::sqrt(std::fabs(cc));
965   }                                               969   }
966   else                                            970   else
967   {                                               971   {
968     ee = 1.0 - (aa / bb) * (cc / bb);             972     ee = 1.0 - (aa / bb) * (cc / bb);
969     dd = std::sqrt(std::fabs(ee)) * std::fabs(    973     dd = std::sqrt(std::fabs(ee)) * std::fabs(bb);
970   }                                               974   }
971   if(ee < 0.0)  // complex conjugate zeros        975   if(ee < 0.0)  // complex conjugate zeros
972   {                                               976   {
973     *ssr = -bb / aa;                              977     *ssr = -bb / aa;
974     *lr  = *ssr;                                  978     *lr  = *ssr;
975     *ssi = std::fabs(dd / aa);                    979     *ssi = std::fabs(dd / aa);
976     *li  = -(*ssi);                               980     *li  = -(*ssi);
977   }                                               981   }
978   else                                            982   else
979   {                                               983   {
980     if(bb >= 0.0)  // real zeros.                 984     if(bb >= 0.0)  // real zeros.
981     {                                             985     {
982       dd = -dd;                                   986       dd = -dd;
983     }                                             987     }
984     *lr  = (-bb + dd) / aa;                       988     *lr  = (-bb + dd) / aa;
985     *ssr = 0.0;                                   989     *ssr = 0.0;
986     if(*lr != 0.0)                                990     if(*lr != 0.0)
987     {                                             991     {
988       *ssr = (cc / *lr) / aa;                     992       *ssr = (cc / *lr) / aa;
989     }                                             993     }
990     *ssi = 0.0;                                   994     *ssi = 0.0;
991     *li  = 0.0;                                   995     *li  = 0.0;
992   }                                               996   }
993 }                                                 997 }
994                                                   998