C#,数值计算——多项式计算,Poly的计算方法与源程序

1 文本格式

using System;

using System.Text;

namespace Legalsoft.Truffer

{

/// <summary>

/// operations on polynomials

/// </summary>

public class Poly

{

/// <summary>

/// polynomial c[0]+c[1]x+c[2]x^2+ ... + c[n-2]x^n-2 + c[n-1]x^n-1

/// </summary>

private double[] c { get; set; }

/// <summary>

/// Construct polynomial

/// </summary>

/// <param name="cc"></param>

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);

}

/// <summary>

/// Build Polynomial from roots

/// </summary>

/// <param name="z"></param>

/// <returns></returns>

/// <exception cref="Exception"></exception>

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);

}

/// <summary>

/// Build Polynomial from roots

/// </summary>

/// <param name="z"></param>

/// <returns></returns>

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);

}

/// <summary>

/// 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].

/// </summary>

/// <param name="c"></param>

/// <param name="x"></param>

/// <param name="pd"></param>

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;

}

}

/// <summary>

/// 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].

/// </summary>

/// <param name="u"></param>

/// <param name="v"></param>

/// <param name="q"></param>

/// <param name="r"></param>

/// <exception cref="Exception"></exception>

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;

}

}

}

}

2 代码格式

cs 复制代码
using System;
using System.Text;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// operations on polynomials
    /// </summary>
    public class Poly
    {
        /// <summary>
        /// polynomial c[0]+c[1]x+c[2]x^2+ ... + c[n-2]x^n-2 + c[n-1]x^n-1
        /// </summary>
        private double[] c { get; set; }

        /// <summary>
        /// Construct polynomial
        /// </summary>
        /// <param name="cc"></param>
        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);
        }

        /// <summary>
        /// Build Polynomial from roots 
        /// </summary>
        /// <param name="z"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        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);
        }

        /// <summary>
        /// Build Polynomial from roots 
        /// </summary>
        /// <param name="z"></param>
        /// <returns></returns>
        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);
        }

        /// <summary>
        /// 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].
        /// </summary>
        /// <param name="c"></param>
        /// <param name="x"></param>
        /// <param name="pd"></param>
        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;
            }
        }

        /// <summary>
        /// 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].
        /// </summary>
        /// <param name="u"></param>
        /// <param name="v"></param>
        /// <param name="q"></param>
        /// <param name="r"></param>
        /// <exception cref="Exception"></exception>
        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;
            }
        }

    }
}
相关推荐
limingade2 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py3 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy3 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
jiao000014 小时前
数据结构——队列
c语言·数据结构·算法
C-SDN花园GGbond4 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
迷迭所归处5 小时前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ6 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
leon6256 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab