40 const G4double G4JTPolynomialSolver::base = 2;
49 :
sr(0.), si(0.), u(0.),
v(0.),
50 a(0.),
b(0.),
c(0.), d(0.),
51 a1(0.), a3(0.), a7(0.),
52 e(0.), f(0.),
g(0.), h(0.),
53 szr(0.), szi(0.), lzr(0.), lzi(0.),
65 G4double t=0.0, aa=0.0,
bb=0.0, cc=0.0, factor=1.0;
67 G4double xm=0.0, ff=0.0, df=0.0, dx=0.0;
68 G4int cnt=0, nz=0, i=0, j=0, jj=0, l=0, nm1=0, zerok=0;
73 static const G4double xx = std::sqrt(0.5);
75 static const G4double cosr = std::cos(rot),
82 if (!(op[0] != 0.0)) {
return -1; }
86 while (!(op[n] != 0.0))
93 if (n < 1) {
return -1; }
97 std::vector<G4double> temp(degr+1) ;
98 std::vector<G4double> pt(degr+1) ;
101 qp.assign(degr+1,0) ;
103 qk.assign(degr+1,0) ;
104 svk.assign(degr+1,0) ;
115 zeror[degr-1] = -
p[1]/
p[0];
122 Quadratic(
p[0],
p[1],
p[2],&zeror[degr-2],&zeroi[degr-2],
123 &zeror[degr-1],&zeroi[degr-1]);
135 if (
x > max) { max =
x; }
147 if ( ((sc <= 1.0) && (max >= 10.0))
148 || ((sc > 1.0) && (infin/sc >= max))
149 || ((infin/sc >= max) && (max >= 10)) )
158 {
p[i] = factor*
p[i]; }
166 pt[i] = (std::fabs(
p[i]));
179 if (xm <
x) {
x = xm; }
189 { ff = ff*xm + pt[i]; }
190 if (ff <= 0.0) {
break; }
197 while (std::fabs(dx/
x) > 0.005)
221 zerok = (k[n-1] == 0);
233 k[j] = t*k[j-1]+
p[j];
236 zerok = (std::fabs(k[n-1]) <= std::fabs(
bb)*eta*10.0);
246 zerok = (!(k[n-1] != 0.0));
257 for (cnt = 0;cnt < 20;cnt++)
264 xxx = cosr*xo - sinr*yo;
265 yo = sinr*xo + cosr*yo;
271 ComputeFixedShiftPolynomial(20*(cnt+1),&nz);
311 void G4JTPolynomialSolver::ComputeFixedShiftPolynomial(
G4int l2,
G4int *nz)
317 G4double svu=0.0, svv=0.0, ui=0.0, vi=0.0, xs=0.0;
318 G4double betas=0.25, betav=0.25, oss=sr, ovv=v,
319 ss=0.0, vv=0.0, ts=1.0, tv=1.0;
322 G4int type=0, i=0, j=0, iflag=0, vpass=0, spass=0, vtry=0, stry=0;
328 QuadraticSyntheticDivision(n,&u,&v,
p,qp,&a,&b);
329 ComputeScalarFactors(&type);
334 ComputeNextPolynomial(&type);
335 ComputeScalarFactors(&type);
336 ComputeNewEstimate(type,&ui,&vi);
342 if (k[n-1] != 0.0) { ss = -
p[n]/k[n-1]; }
345 if (j == 0 || type == 3)
356 if (vv != 0.0) { tv = std::fabs((vv-ovv)/vv); }
357 if (ss != 0.0) { ts = std::fabs((ss-oss)/ss); }
361 if (tv < otv) { tvv = tv*otv; }
363 if (ts < ots) { tss = ts*ots; }
366 vpass = (tvv < betav);
367 spass = (tss < betas);
368 if (!(spass || vpass))
392 if ((spass && (!vpass)) || (tss < tvv))
394 RealPolynomialIteration(&xs,nz,&iflag);
395 if (*nz > 0) {
return; }
402 if (iflag == 0) {
goto _restore_variables; }
411 _quadratic_iteration:
415 QuadraticPolynomialIteration(&ui,&vi,nz);
416 if (*nz > 0) {
return; }
427 if (stry || !spass) {
break; }
432 RealPolynomialIteration(&xs,nz,&iflag);
433 if (*nz > 0) {
return; }
440 if (iflag == 0) {
break; }
464 if (vpass && !vtry) {
goto _quadratic_iteration; }
469 QuadraticSyntheticDivision(n,&u,&v,
p,qp,&a,&b);
470 ComputeScalarFactors(&type);
479 void G4JTPolynomialSolver::
491 G4double mp=0.0, ee=0.0, t=0.0, zm=0.0;
492 G4int type=0, i=1, j=0, tried=0;
503 Quadratic(1.0,u,v,&szr,&szi,&lzr,&lzi);
509 if (std::fabs(std::fabs(szr)-std::fabs(lzr)) > 0.01 * std::fabs(lzr))
514 QuadraticSyntheticDivision(n,&u,&v,
p,qp,&a,&b);
515 mp = std::fabs(a-szr*b) + std::fabs(szi*b);
519 zm = std::sqrt(std::fabs(v));
520 ee = 2.0*std::fabs(qp[0]);
524 ee = ee*zm + std::fabs(qp[i]);
526 ee = ee*zm + std::fabs(a+t);
527 ee *= (5.0 *mre + 4.0*are);
528 ee = ee - (5.0*mre+2.0*are)*(std::fabs(a+t)+std::fabs(b)*zm)
529 + 2.0*are*std::fabs(t);
543 if (j > 20) {
return; }
546 if (!(relstp > 0.01 || mp < omp || tried))
551 if (relstp < eta) { relstp = eta; }
552 relstp = std::sqrt(relstp);
555 QuadraticSyntheticDivision(n,&u,&v,
p,qp,&a,&b);
558 ComputeScalarFactors(&type);
559 ComputeNextPolynomial(&type);
569 ComputeScalarFactors(&type);
570 ComputeNextPolynomial(&type);
571 ComputeScalarFactors(&type);
572 ComputeNewEstimate(type,&ui,&vi);
576 if (!(vi != 0.0)) {
return; }
577 relstp = std::fabs((vi-v)/vi);
583 void G4JTPolynomialSolver::
619 ee = (mre/(are+mre))*std::fabs(qp[0]);
622 ee = ee*mx + std::fabs(qp[i]);
628 if (mp <= 20.0*((are+mre)*ee-mre*mp))
639 if (j > 10) {
return; }
642 if (!(std::fabs(t) > 0.001*std::fabs(xs-t) || mp < omp))
664 if (std::fabs(kv) <= std::fabs(k[n-1])*10.0*eta)
678 k[i] = t*qk[i-1] + qp[i];
687 if (std::fabs(kv) > std::fabs(k[n-1]*10.0*eta)) { t = -pv/kv; }
692 void G4JTPolynomialSolver::ComputeScalarFactors(
G4int *type)
702 QuadraticSyntheticDivision(n-1,&u,&v,k,qk,&c,&d);
703 if (std::fabs(c) <= std::fabs(k[n-1]*100.0*eta))
705 if (std::fabs(d) <= std::fabs(k[n-2]*100.0*eta))
712 if (std::fabs(d) < std::fabs(c))
719 a3 = a*e + (h/c+g)*b;
729 a3 = (a+g)*e + h*(b/d);
734 void G4JTPolynomialSolver::ComputeNextPolynomial(
G4int *type)
752 if (*type == 1) { temp = b; }
753 if (std::fabs(a1) <= std::fabs(temp)*eta*10.0)
761 k[i] = a3*qk[i-2] - a7*qp[i-1];
771 k[1] = qp[1] - a7*qp[0];
774 k[i] = a3*qk[i-2] - a7*qp[i-1] + qp[i];
778 void G4JTPolynomialSolver::
784 G4double a4=0.0, a5=0.0, b1=0.0, b2=0.0,
785 c1=0.0,
c2=0.0, c3=0.0, c4=0.0, temp=0.0;
809 b2 = -(k[n-2]+b1*
p[n-1])/
p[n];
814 temp = a5 + b1*a4 - c4;
821 *uu = u - (u*(c3+
c2)+v*(b1*a1+b2*a7))/temp;
822 *vv = v*(1.0+c4/temp);
826 void G4JTPolynomialSolver::
828 std::vector<G4double> &
pp, std::vector<G4double> &qq,
837 *aa = pp[1] - (*bb)*(*uu);
841 cc = pp[i] - (*aa)*(*uu) - (*bb)*(*vv);
884 if (std::fabs(bb) < std::fabs(cc))
890 ee = bb*(bb/std::fabs(cc)) - ee;
891 dd = std::sqrt(std::fabs(ee))*std::sqrt(std::fabs(cc));
895 ee = 1.0 - (aa/
bb)*(cc/bb);
896 dd = std::sqrt(std::fabs(ee))*std::fabs(bb);
902 *ssi = std::fabs(dd/aa);
912 { *ssr = (cc/ *lr)/aa; }
static G4Pow * GetInstance()
static c2_factory< G4double > c2
G4double powN(G4double x, G4int n) const
std::vector< ExP01TrackerHit * > a
const XML_Char int const XML_Char int const XML_Char * base
static constexpr double sr
G4double G4Log(G4double x)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
static const char sss[MAX_N_PAR+2]
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static constexpr double deg
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)