/// <summary> /// Only for polynomials of the degree 2! /// Returns both zero positions of the polynomial, /// if they are real. /// </summary> /// <returns>both zero positions of the polynomial</returns> public double[] ZeroSetN2() { if (Degree != 2) { throw new Exception( "Only for polynomials with degree 2!"); } if (this[2] == 0) { throw new Exception( "Not a quadratic function, first coefficient = 0!"); } //normalize Polynomial nForm; if (this[2] != 1) { nForm = new Polynomial(3); nForm[0] = this[0] / this[2]; nForm[1] = this[1] / this[2]; nForm[2] = 1; } else { nForm = this; // normal form } return(GeneralMath.QuadraticEquation(nForm[1], nForm[0])); }
/// <summary> /// Only for polynomials of the degree 3! /// Finds all zero positions of the polynomial, if they /// are real. /// This method searches one zero position by using /// the Halley method. The polynomial then will be divided /// by polynomial division by the first found zero position. /// The remaining two zero positions will be found by /// solving the remaining quadratic equation. /// </summary> /// <param name="accuracy"> /// Number of correctly computed decimals /// </param> /// <returns> /// List of all three zero positions. /// </returns> public double[] ZeroSetN3(int accuracy) { double allowedError = Math.Pow(10, -accuracy); if (Degree != 3) { throw new Exception("Only for polynomials with degree 3!"); } if (this[3] == 0) { throw new Exception("Not a cubic function, first coefficient = 0!"); } // normalise term Polynomial nForm; if (this[3] != 1) { nForm = new Polynomial(3); nForm[3] = 1; for (int i = 0; i < 3; i++) { nForm[i] = this[i] / this[3]; } } else { nForm = this; // normal form } // check if all zeros are real double reducedP, reducedQ; reducedP = nForm[1] - (Math.Pow(nForm[2], 2) / 3); reducedQ = 2 * Math.Pow(nForm[2], 3) / 27 - nForm[2] * nForm[1] / 3 + nForm[0]; if (Math.Pow(reducedQ / 2, 2) + Math.Pow(reducedP / 3, 3) > 0) { throw new Exception("not all zeroes are real!"); } // // Implementation of the Method of Deiters and Macias-Salinas // double lowerBoundry, upperBoundry, initialValue, firstZero = 0, xInflection, yInflection, auxD; // "D" in Wikipedia: "Kubische Gleichungen" xInflection = -nForm[2] / 3; yInflection = Value(xInflection); if (yInflection == 0) { firstZero = xInflection; } else { auxD = Math.Pow(nForm[2], 2) - 3 * nForm[1]; if (auxD == 0) { firstZero = xInflection - Math.Pow(yInflection, 1.0 / 3); } else { // original: find first zero iterative by halley method, now tangent lowerBoundry = xInflection - (2.0 / 3) * Math.Sqrt(Math.Abs(auxD)); upperBoundry = xInflection + (2.0 / 3) * Math.Sqrt(Math.Abs(auxD)); if (auxD > 0 && yInflection > 0) { initialValue = lowerBoundry; } else if (auxD > 0 && yInflection < 0) { initialValue = upperBoundry; } else { initialValue = xInflection; } firstZero = ZeroHalley(initialValue, accuracy); } } // polynomial division double p, q; double[] sqret = new double[2], ret = new double[3]; p = nForm[2] + firstZero; q = p * firstZero + nForm[1]; ret[0] = firstZero; // find remaining zero positions by solving quadratic equation sqret = GeneralMath.QuadraticEquation(p, q); ret[1] = sqret[0]; ret[2] = sqret[1]; return(ret); }