public static double[] SolveQuartic( double a, double b, double c, double d, double e )
{
if ( e == 0.0 )
throw new Exception( "5th coefficient is invalid! You should resolve a cubic polynomial instead !" );
// Adjust coefficients
double a0 = a / e;
double a1 = b / e;
double a2 = c / e;
double a3 = d / e;
// Find a root for the following cubic equation : y^3 - a2 y^2 + (a1 a3 - 4 a0) y + (4 a2 a0 - a1 ^2 - a3^2 a0) = 0
double b0 = 4 * a2 * a0 - a1 * a1 - a3 * a3 * a0;
double b1 = a1 * a3 - 4 * a0;
double b2 = -a2;
double[] Roots = SolveCubic( b0, b1, b2, 1 );
double y = Math.Max( Roots[0], Math.Max( Roots[1], Roots[2] ) );
// Compute R, D & E
double R = 0.25 * a3 * a3 - a2 + y;
if ( R < 0.0 )
return new double[] { double.NaN, double.NaN, double.NaN, double.NaN };
R = Math.Sqrt( R );
double D, E;
if ( R == 0.0 )
{
D = Math.Sqrt( 0.75 * a3 * a3 - 2 * a2 + 2 * Math.Sqrt( y * y - 4 * a0 ) );
E = Math.Sqrt( 0.75 * a3 * a3 - 2 * a2 - 2 * Math.Sqrt( y * y - 4 * a0 ) );
}
else
{
double Rsquare = R * R;
double Rrec = 1.0 / R;
D = Math.Sqrt( 0.75 * a3 * a3 - Rsquare - 2 * a2 + 0.25 * Rrec * (4 * a3 * a2 - 8 * a1 - a3 * a3 * a3) );
E = Math.Sqrt( 0.75 * a3 * a3 - Rsquare - 2 * a2 - 0.25 * Rrec * (4 * a3 * a2 - 8 * a1 - a3 * a3 * a3) );
}
// Compute the 4 roots
double[] Result = new double[]
{
-0.25 * a3 + 0.5 * R + 0.5 * D,
-0.25 * a3 + 0.5 * R - 0.5 * D,
-0.25 * a3 - 0.5 * R + 0.5 * E,
-0.25 * a3 - 0.5 * R - 0.5 * E
};
return Result;
}