C#,数值计算——多项式评价函数poly的计算方法与源程序

 

using System;
using System.Text;

namespace Legalsoft.Truffer
{
    ///


    /// operations on polynomials
    ///

    public class Poly
    {
        ///
        /// polynomial c[0]+c[1]x+c[2]x^2+ ... + c[n-2]x^n-2 + c[n-1]x^n-1
        ///

        private double[] c { get; set; }

        ///


        /// Construct polynomial
        ///

        ///
        public Poly(double[] cc)
        {
            this.c = cc;
        }

        public double poly(double x)
        {
            int j;
            double p = c[j = c.Length - 1];
            while (j > 0)
            {
                p = p * x + c[--j];
            }
            return p;
        }

        public String toString()
        {
            StringBuilder sb = new StringBuilder(32);
            int j = c.Length - 1;
            sb.Append(String.Format("%fx^%d", c[j], j));
            j--;
            for (; j != 0; j--)
            {
                sb.Append(String.Format("%+fx^%d", c[j], j));
            }
            sb.Append(String.Format("%+f ", c[0]));
            return sb.ToString().Substring(0);
        }

        ///


        /// Build Polynomial from roots 
        ///

        ///
        ///
        ///
        public static Poly buildFromRoots(Complex[] z)
        {
            for (int i = 0; i < z.Length; i++)
            {
                bool found = false;
                for (int j = 0; j < z.Length; j++)
                {
                    //if (z[i].re == z[j].re && z[i].im == -z[j].im)
                    if (Math.Abs(z[i].re - z[j].re) <= float.Epsilon && Math.Abs(z[i].im - (-z[j].im)) <= float.Epsilon)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    throw new Exception("Roots must be conjugate");
                }
            }

            Complex[] c = new Complex[z.Length + 1];
            c[0] = z[0].neg();
            c[1] = new Complex(1, 0);
            for (int i = 1; i < z.Length; i++)
            {
                Complex d = c[0];
                c[0] = c[0].mul(z[i].neg());
                for (int j = 1; j < i + 1; j++)
                {
                    Complex dd = c[j];
                    c[j] = d.sub(z[i].mul(c[j]));
                    d = dd;
                }
                c[i + 1] = d;
            }
            double[] cc = new double[c.Length];
            for (int i = 0; i < cc.Length; i++)
            {
                cc[i] = c[i].re;
            }
            return new Poly(cc);
        }

        ///


        /// Build Polynomial from roots 
        ///

        ///
        ///
        public static Poly buildFromRoots(double[] z)
        {
            double[] c = new double[z.Length + 1];
            c[0] = -z[0]; c[1] = 1;
            for (int i = 1; i < z.Length; i++)
            {
                double d = c[0];
                c[0] *= -z[i];
                for (int j = 1; j < i + 1; j++)
                {
                    double dd = c[j];
                    c[j] = d - z[i] * c[j];
                    d = dd;
                }
                c[i + 1] = d;
            }

            return new Poly(c);
        }

        ///


        /// Given the coefficients of a polynomial of degree nc as an array c[0..nc] of
        /// size nc+1 (with c[0] being the constant term), and given a value x, this
        /// routine fills an output array pd of size nd+1 with the value of the
        /// polynomial evaluated at x in pd[0], and the first nd derivatives at x in
        /// pd[1..nd].
        ///

        ///
        ///
        ///
        public static void ddpoly(double[] c, double x, double[] pd)
        {
            int nc = c.Length - 1;
            int nd = pd.Length - 1;
            double cnst = 1.0;
            pd[0] = c[nc];
            for (int j = 1; j < nd + 1; j++)
            {
                pd[j] = 0.0;
            }
            for (int i = nc - 1; i >= 0; i--)
            {
                int nnd = (nd < (nc - i) ? nd : nc - i);
                for (int j = nnd; j > 0; j--)
                {
                    pd[j] = pd[j] * x + pd[j - 1];
                }
                pd[0] = pd[0] * x + c[i];
            }
            for (int i = 2; i < nd + 1; i++)
            {
                cnst *= i;
                pd[i] *= cnst;
            }
        }

        ///


        /// Given the coefficients of a polynomial of degree nc as an array c[0..nc] of
        /// size nc+1 (with c[0] being the constant term), and given a value x, this
        /// routine fills an output array pd of size nd+1 with the value of the
        /// polynomial evaluated at x in pd[0], and the first nd derivatives at x in
        /// pd[1..nd].
        ///

        ///
        ///
        ///
        ///
        ///
        public static void poldiv(double[] u, double[] v, double[] q, double[] r)
        {
            int n = u.Length - 1;
            int nv = v.Length - 1;
            //while (nv >= 0 && v[nv] == 0.0)
            while (nv >= 0 && Math.Abs(v[nv]) <= float.Epsilon)
            {
                nv--;
            }
            if (nv < 0)
            {
                throw new Exception("poldiv divide by zero polynomial");
            }

            //r = u;
            r = Globals.CopyFrom(u);
            //q.assign(u.Length, 0.0);
            for (int k = n - nv; k >= 0; k--)
            {
                q[k] = r[nv + k] / v[nv];
                for (int j = nv + k - 1; j >= k; j--)
                {
                    r[j] -= q[k] * v[j - k];
                }
            }
            for (int j = nv; j <= n; j++)
            {
                r[j] = 0.0;
            }
        }

    }
}
 

你可能感兴趣的:(C#数值计算,Numerical,Recipes,c#,开发语言,数值计算,数据结构,算法)