polynomialDiscriminant method

Complex polynomialDiscriminant({
  1. bool optimize = true,
})

The discriminant of a polynomial P(x) is the determinant of the Sylvester matrix of P and P' (where P' is the derivative of P).

By default, the optimize parameter is set to true so that the Sylvester matrix is not computed for polynomials whose degree is 4 or lower. To be more precise:

  • With optimize = true, if the degree of the polynomial is lower than 4, then the Sylvester matrix is not built. The computation of its determinant can be computationally heavy so we can just avoid such complexity by using the simple formulas for lower degree polynomials.

  • With optimize = false, the Sylvester matrix and its determinant are always computed regardless the degree of the polynomial.

You should keep the default value of optimize.

Implementation

Complex polynomialDiscriminant({bool optimize = true}) {
  final quarticOrLower = polynomial is Constant ||
      polynomial is Linear ||
      polynomial is Quadratic ||
      polynomial is Cubic ||
      polynomial is Quartic;

  // In case the optimization flag was 'true' and the degree of the
  // polynomial is <= 4, then go for the easy way.
  if (optimize && quarticOrLower) {
    return polynomial.discriminant();
  } else {
    // The determinant of the Sylvester matrix
    final determinant = matrixDeterminant();

    /*
    * Once we got the determinant, we need to make the last calculation to
    * also determine the sign. The formula is the following:
    *
    *  Disc(A) = (-1)^(n*(n-1)/2) * 1/A[n] * Res(A, A')
    *
    * In the above formula, 'n' is the degree of the polynomial, A(x) is the
    * polynomial and A'(x) is the derivative of A(x).
    *
    * Res(A, A') is the resultant of A(x) and A'(x), which is nothing more
    * than the determinant of the Sylvester matrix.
    */
    final coefficients = polynomial.coefficients;
    final degree = coefficients.length - 1;
    final sign = math.pow(-1, degree * (degree - 1) / 2) as double;
    final denominator = coefficients.first;

    // Returning the determinant with the correct sign
    return Complex.fromReal(sign) / denominator * determinant;
  }
}