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

    }
}
相关推荐
浮生如梦_36 分钟前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
△曉風殘月〆39 分钟前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown4 小时前
【数据结构】选择排序
数据结构·算法·排序算法
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet