/// <summary>
        /// Computes the definite integral within the borders a and b.
        /// </summary>
        /// <param name="a">Left integration border.</param>
        /// <param name="b">Right integration border.</param>
        /// <returns></returns>
        public double Integrate(double a, double b)
        {
            double[] buf = new double[Degree + 2];
            buf[0] = 0; // this value can be arbitrary, in fact

            for (int i = 1; i < buf.Length; i++)
            {
                buf[i] = Coefficients[i - 1] / i;
            }

            Polynomial p = new Polynomial(buf);

            return(p.Evaluate(b) - p.Evaluate(a));
        }
        /// <summary>
        /// Computes the greatest value |p(z_k)|.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public static double MaxValue(Polynomial p, double[] z)
        {
            double buf = 0;

            for (int i = 0; i < z.Length; i++)
            {
                if (Math.Abs(p.Evaluate(z[i])) > buf)
                {
                    buf = Math.Abs(p.Evaluate(z[i]));
                }
            }

            return(buf);
        }
        /// <summary>
        /// Computes the roots of polynomial p via Weierstrass iteration.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static double[] Roots(Polynomial p)
        {
            double tolerance      = 1e-12;
            int    max_iterations = 30;

            Polynomial q = Normalize(p);

            //Polynomial q = p;

            double[] z = new double[q.Degree]; // approx. for roots
            double[] w = new double[q.Degree]; // Weierstraß corrections

            // init z
            for (int k = 0; k < q.Degree; k++)
            {
                //z[k] = (new Complex(.4, .9)) ^ k;
                z[k] = Math.Exp(2 * Math.PI * k / q.Degree);
            }


            for (int iter = 0; iter < max_iterations &&
                 MaxValue(q, z) > tolerance; iter++)
            {
                for (int i = 0; i < 10; i++)
                {
                    for (int k = 0; k < q.Degree; k++)
                    {
                        w[k] = q.Evaluate(z[k]) / WeierNull(z, k);
                    }

                    for (int k = 0; k < q.Degree; k++)
                    {
                        z[k] -= w[k];
                    }
                }
            }

            // clean...
            for (int k = 0; k < q.Degree; k++)
            {
                z[k] = Math.Round(z[k], 12);
            }

            return(z);
        }
        /// <summary>
        /// Computes the definite integral within the borders a and b.
        /// </summary>
        /// <param name="a">Left integration border.</param>
        /// <param name="b">Right integration border.</param>
        /// <returns></returns>
        public double Integrate(double a, double b)
        {
            double[] buf = new double[Degree + 2];
            buf[0] = 0; // this value can be arbitrary, in fact

            for (int i = 1; i < buf.Length; i++)
                buf[i] = Coefficients[i - 1] / i;

            Polynomial p = new Polynomial(buf);

            return (p.Evaluate(b) - p.Evaluate(a));
        }
        /// <summary>
        /// Computes the greatest value |p(z_k)|.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public static double MaxValue(Polynomial p, double[] z)
        {
            double buf = 0;
            for (int i = 0; i < z.Length; i++)
            {
                if (Math.Abs(p.Evaluate(z[i])) > buf)
                    buf = Math.Abs(p.Evaluate(z[i]));
            }

            return buf;
        }