コード例 #1
0
ファイル: Polynomial.cs プロジェクト: vijirams/TuryUtilCs
        /// <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]));
        }
コード例 #2
0
ファイル: Polynomial.cs プロジェクト: vijirams/TuryUtilCs
        /// <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);
        }