16 int QuarticNewton(
double b,
double c,
double d,
double e,
double *z);
18 double CheckSolution(
double b,
double c,
double d,
double e,
double x);
19 double ResolventCubic(
double b,
double c,
double d,
double e,
double x );
30 #define swap(x,y) f = x; x = y; y = f;
31 #define SWAP(x,y) {double _t; _t = x; x = y; y = _t;}
61 double a2, a1, a0, u[4];
63 static double three_256 = 3.0/256.0;
64 static double one_64 = 1.0/64.0;
75 g = d + b2*b*0.125 - b*c*0.5;
76 h = e - b2*b2*three_256 + 0.0625*b2*c - 0.25*b*d;
79 a1 = (f*f - 4.0*h)*0.0625;
90 z[0] = z[2] = - p -
s;
91 z[1] = z[3] = + p -
s;
101 z[0] = - p - q + r -
s;
102 z[1] = p - q - r -
s;
103 z[2] = - p + q - r -
s;
104 z[3] = p + q + r -
s;
117 if (z[1] < z[0]) {
swap(z[1],z[0]);}
118 else if (z[1] > z[3]) {
swap(z[1],z[3]);}
124 }
else if (z[2] < z[1]){
126 }
else if (z[2] > z[3]){
147 for (n = 0; n < 4; n++){
148 s = e + z[
n]*(d + z[
n]*(c + z[
n]*(b + z[
n])));
153 if (fabs(s) > 1.e-6) {
165 print (
"QuarticSolveNew() has failed\n");
168 for (n = 0; n < 4; n++){
169 if (znew[n] != znew[n]) {
170 print (
"! QuarticSolve(): nan in root %d\n",n);
178 if (fabs(z[0]-znew[0]) > 1.e-3 || fabs(z[3]-znew[3]) > 1.e-3){
182 printf (
"! Different solutions\n");
191 print (
"\n Now improving with Newton\n");
236 double i, i2,
j,
k, m,
n, p;
237 static double one_3 = 1.0/3.0, one_27=1.0/27.0;
248 f = c*(1.0 - 1.e-16) - b2*one_3;
249 g = b*(2.0*b2 - 9.0*
c)*one_27 + d;
282 k = (k < -1.0 ? -1.0:
k);
283 k = (k > 1.0 ? 1.0:
k);
288 n = sqrt(3.0)*sin(k);
291 z[0] = -j*(m +
n) + p;
292 z[1] = -j*(m -
n) + p;
345 double scrh, p,
q, del, del0, del1, Q, S,
Y;
346 double sqp, sqm, phi, sq_del0;
348 double den, bnorm, dnorm;
350 const double one_third = 1.0/3.0;
385 b = -3.97367591434748e+00;
386 c = 5.92126911218894e+00;
387 d = -3.92150958389634e+00;
388 e = 9.73916387216783e-01;
398 double b2 = b*b, c2=c*
c, bd=b*d;
400 del0 = c2 - 3.0*bd + 12.0*e;
401 del1 = c*(2.0*c2 - 9.0*bd) + 27.0*(b2*e + d*d) - 72.0*c*e;
402 del = (4.0*del0*del0*del0 - del1*del1)/27.0;
403 D = 64.0*e - 16.0*c2 + 16.0*b2*c - 16.0*bd - 3.0*b2*b2;
406 Y = 0.25*b2 + 2.0*d/(b+1.e-40) - c;
408 den = 1.0 + fabs(b) + fabs(c) + fabs(d);
414 print (
"QuarticSolve(): del = %12.6e, del0 = %12.6e D = %12.6e, P = %12.6e, Y = %12.6e\n",
428 double zero = 1.e-12;
429 double zero2 = zero*zero;
430 double zero3 = zero2*zero;
433 if (fabs(del) < zero3 && fabs(del0) < zero && fabs(D) < zero2){
435 z[0] = z[1] = z[2] = z[3] = -0.25*b;
436 }
else if (bnorm < 1.e-12 && dnorm < 1.e-12){
438 double a2 = 1.0, b2 =
c, c2 = e;
442 x[0] =
MAX(0.0, x[0]);
443 x[1] =
MAX(0.0, x[1]);
445 if (x[0] < 0.0 || x[1] < 0.0){
446 print (
"QuarticSolve(): case B: cannot continue\n");
447 print (
"x = %12.6e, %12.6e\n",x[0],x[1]);
455 }
else if (fabs(Y) < 1.e-14){
456 if (
debug_print)
print (
"Case C: QuarticSolve(): No need for resolvent cubic\n");
458 double a2, b2, c2, del2;
462 del2 = d*d/(b*b) - e;
463 del2 =
MAX(0.0, del2);
465 print (
"! QuarticSolve(): case C: cannot continue, del2 = %12.6e\n",del2);
469 c2 = d/b + sqrt(del2);
474 c2 = d/b - sqrt(del2);
482 print (
"- QuarticSolve(): case 4: 4 distinct roots, no degeneracy\n");
483 print (
" del0 = %12.6e, del1 = %12.6e\n",del0, del1);
486 del0 =
MAX(del0,0.0);
487 sq_del0 = sqrt(del0);
488 scrh = 0.5*del1/(fabs(del0)*sq_del0);
491 scrh =
MAX(scrh,-1.0);
492 scrh =
MIN(scrh, 1.0);
493 phi = acos(scrh)*one_third;
495 q = 0.125*b*b*b - 0.5*b*c + d;
497 scrh = -2.0*(p - sq_del0*cos(phi))*one_third;
499 scrh =
MAX(scrh,0.0);
501 print (
"! Quartic(): canont compute S, scrh = %12.6e\n",scrh);
508 if (fabs(S) < 1.e-12){
509 print (
"! Quartic(): S = %12.6e <= 0 \n",S);
513 scrh = -4.0*S*S - 2.0*p - q/S;
514 scrh =
MAX(0.0, scrh);
517 scrh = -4.0*S*S - 2.0*p + q/S;
518 scrh =
MAX(0.0, scrh);
525 z[0] = -0.25*b - S - 0.5*sqp;
526 z[1] = -0.25*b - S + 0.5*sqp;
527 z[2] = -0.25*b + S - 0.5*sqm;
528 z[3] = -0.25*b + S + 0.5*sqm;
532 print (
"! QuarticSolve: not correct (0)\n");
583 double x, dx, f, df, d2f;
584 double tolx = 1.e-12, tolf = 1.e-18;
588 for (k = 0; k < max_iter; k++){
589 f = e + x*(d + x*(c + x*(b + x)));
590 df = d + x*(2.0*c + x*(3.0*b + 4.0*x));
591 d2f = 2.0*c + x*(6.0*b + 12.0*x);
593 dx = f*df/(df*df - f*d2f);
599 if (fabs(dx) < tolx || fabs(f) < tolf) {
603 print (
"QuarticNewton: k = %d, x = %f, dx = %12.6e, f = %8.3e\n",k,x, dx,f);
604 print (
"QuarticNewton, root found in # %d iterations\n",k);
609 print (
"! QuarticNewton: too many steps\n");
621 print (
"! f(x) = %18.12e + x*(%18.12e + x*(%18.12e ",
623 print (
" + x*(%18.12e + x*%18.12e)))\n", b, 1.0);
625 print (
"b = %18.14e;\n",b);
626 print (
"c = %18.14e;\n",c);
627 print (
"d = %18.14e;\n",d);
628 print (
"e = %18.14e;\n",e);
631 double c3 = c*c + b*d - 4.0*e;
632 double d3 = -(b*c*d - b*b*e - d*d);
634 print (
"! Resolvent cubic:\n");
635 print (
"! g(x) = %18.12e + x*(%18.12e + x*(%18.12e + x))\n", d3, c3, b3);
645 double f,
fp, fm, fmax;
646 f = e + x*(d + x*(c + x*(b + x)));
649 fp = e + x*(d + x*(c + x*(b + x)));
652 fm = e + x*(d + x*(c + x*(b + x)));
664 print (
"z = %f %f %f %f\n",z[0],z[1],z[2],z[3]);
672 c3 = c*c + b*d - 4.0*e;
673 d3 = -(b*c*d - b*b*e - d*d);
674 f = d3 + x*(c3 + x*(b3 + x));
692 if (del < 0.0)
return 1;
699 sb = (b > 0.0 ? 1.0:-1.0);
700 q = -0.5*(b + sb*sqrt(del));
int QuarticSolve(double b, double c, double d, double e, double *z)
int CubicSolve(double b, double c, double d, double z[])
int QuarticNewton(double b, double c, double d, double e, double *z)
double CheckSolution(double b, double c, double d, double e, double x)
void PrintSolution(double *z)
double ResolventCubic(double b, double c, double d, double e, double x)
void print(const char *fmt,...)
int QuarticSolveNew(double b, double c, double d, double e, double *z)
int QuadraticSolve(double a, double b, double c, double *x)
#define QUIT_PLUTO(e_code)
void QuarticPrintCoeffs(double b, double c, double d, double e)