int QuarticEquation::Solve(double *const roots) const { double r1, r2, r3, r4; int nr12, nr34; double a3 = d3/d4; double a2 = d2/d4; double a1 = d1/d4; double a0 = d0/d4; double au2 = -a2; double au1 = (a1*a3 - 4.0*a0) ; double au0 = 4.0*a0*a2 - a1*a1 - a0*a3*a3; double x1, x2, x3; int nr; solve_cubic_equation(1.0, au2, au1, au0, x1, x2, x3, nr); double u1; if (nr==1) { u1 = x1; } else { u1 = (x1>x3) ? x1 : x3; } double R2 = 0.25*a3*a3 + u1 - a2; double R = (R2>0.0) ? sqrt(R2) : 0.0; double D2, E2; if (R != 0.0) { double foo1 = 0.75*a3*a3 - R2 - 2.0*a2; double foo2 = 0.25*(4.0*a3*a2 - 8.0*a1 - a3*a3*a3) / R; D2 = foo1 + foo2; E2 = foo1 - foo2; } else { double foo1 = 0.75*a3*a3 - 2.0*a2; double foo2 = 2.0 * sqrt(u1*u1 - 4.0*a0); D2 = foo1 + foo2; E2 = foo1 - foo2; } if (D2 >= 0.0) { double D = sqrt(D2); r1 = -0.25*a3 + 0.5*R - 0.5*D; r2 = -0.25*a3 + 0.5*R + 0.5*D; nr12 = 2; } else { r1 = r2 = -0.25*a3 + 0.5*R; nr12 = 0; } if (E2 >= 0.0) { double E = sqrt(E2); r3 = -0.25*a3 - 0.5*R - 0.5*E; r4 = -0.25*a3 - 0.5*R + 0.5*E; nr34 = 2; } else { r3 = r4 = -0.25*a3 - 0.5*R; nr34 = 0; } int i=0; if (nr12 != 0) { roots[i++] = r1; roots[i++] = r2; } if (nr34 != 0) { roots[i++] = r3; roots[i++] = r4; } return nr12 + nr34; }
int quartic_equation_solve_exact(double *r1, double *r2, double *r3, double *r4, int *nr12, int *nr34,double d0,double d1,double d2, double d3, double d4) { double a3 = d3/d4; double a2 = d2/d4; double a1 = d1/d4; double a0 = d0/d4; double au2 = -a2; double au1 = (a1*a3 - 4.0*a0) ; double au0 = 4.0*a0*a2 - a1*a1 - a0*a3*a3; double x1, x2, x3; int nr = solve_cubic_equation(1.0, au2, au1, au0, &x1, &x2, &x3); double u1; if (nr==1) u1 = x1; else u1 = (x1>x3) ? x1 : x3; double R2 = 0.25*a3*a3 + u1 - a2; double R = (R2>0.0) ? sqrt(R2) : 0.0; double D2, E2; if (R != 0.0) { double foo1 = 0.75*a3*a3 - R2 - 2.0*a2; double foo2 = 0.25*(4.0*a3*a2 - 8.0*a1 - a3*a3*a3) / R; D2 = foo1 + foo2; E2 = foo1 - foo2; } else { double foo1 = 0.75*a3*a3 - 2.0*a2; double foo2 = 2.0 * sqrt(u1*u1 - 4.0*a0); D2 = foo1 + foo2; E2 = foo1 - foo2; } if (D2 >= 0.0) { double D = sqrt(D2); *r1 = -0.25*a3 + 0.5*R - 0.5*D; *r2 = -0.25*a3 + 0.5*R + 0.5*D; *nr12 = 2; } else { *r1 = *r2 = -0.25*a3 + 0.5*R; *nr12 = 0; } if (E2 >= 0.0) { double E = sqrt(E2); *r3 = -0.25*a3 - 0.5*R - 0.5*E; *r4 = -0.25*a3 - 0.5*R + 0.5*E; *nr34 = 2; } else { *r3 = *r4 = -0.25*a3 - 0.5*R; *nr34 = 0; } return *nr12 + *nr34; }