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 ]

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