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

1 文本格式

using System;

using System.Text;

namespace Legalsoft.Truffer

{

/// <summary>

/// operations on polynomials

/// </summary>

public class Poly

{

/// <summary>

/// polynomial c0+c1x+c2x^2+ ... + cn-2x^n-2 + cn-1x^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 = cj = 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", cj, j));

j--;

for (; j != 0; j--)

{

sb.Append(String.Format("%+fx^%d", cj, j));

}

sb.Append(String.Format("%+f ", c0));

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 (zi.re == zj.re && zi.im == -zj.im)

if (Math.Abs(zi.re - zj.re) <= float.Epsilon && Math.Abs(zi.im - (-zj.im)) <= float.Epsilon)

{

found = true;

break;

}

}

if (!found)

{

throw new Exception("Roots must be conjugate");

}

}

Complex\[\] c = new Complexz.Length + 1;

c0 = z0.neg();

c1 = new Complex(1, 0);

for (int i = 1; i < z.Length; i++)

{

Complex d = c0;

c0 = c0.mul(zi.neg());

for (int j = 1; j < i + 1; j++)

{

Complex dd = cj;

cj = d.sub(zi.mul(cj));

d = dd;

}

ci + 1 = d;

}

double\[\] cc = new doublec.Length;

for (int i = 0; i < cc.Length; i++)

{

cci = ci.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 doublez.Length + 1;

c0 = -z0; c1 = 1;

for (int i = 1; i < z.Length; i++)

{

double d = c0;

c0 *= -zi;

for (int j = 1; j < i + 1; j++)

{

double dd = cj;

cj = d - zi * cj;

d = dd;

}

ci + 1 = d;

}

return new Poly(c);

}

/// <summary>

/// Given the coefficients of a polynomial of degree nc as an array c0..nc of

/// size nc+1 (with c0 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 pd0, and the first nd derivatives at x in

/// pd1..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;

pd0 = cnc;

for (int j = 1; j < nd + 1; j++)

{

pdj = 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--)

{

pdj = pdj * x + pdj - 1;

}

pd0 = pd0 * x + ci;

}

for (int i = 2; i < nd + 1; i++)

{

cnst *= i;

pdi *= cnst;

}

}

/// <summary>

/// Given the coefficients of a polynomial of degree nc as an array c0..nc of

/// size nc+1 (with c0 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 pd0, and the first nd derivatives at x in

/// pd1..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 && vnv == 0.0)

while (nv >= 0 && Math.Abs(vnv) <= 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--)

{

qk = rnv + k / vnv;

for (int j = nv + k - 1; j >= k; j--)

{

rj -= qk * vj - k;

}

}

for (int j = nv; j <= n; j++)

{

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

    }
}
相关推荐
gCode Teacher 格码致知2 小时前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工2 小时前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留2 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#
ShineWinsu2 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
罗西的思考3 小时前
【Agentic RL】Dressage Staleness 控制深度分析
人工智能·算法·机器学习
quaer3 小时前
弗洛伊德算法--判圈法寻找环的入口O(n) O(1)
数据结构·算法
益莱储中国4 小时前
深度解析:RF 实验室从 5G迈向 6G 的过程中保持技术领先与设备升级的路径
开发语言·php
benchmark_cc5 小时前
Python 量化系统如何设计统一的数据访问接口:从策略解耦到数据层架构
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
高晶5 小时前
无乘法器实现LC二阶滤波器:基于移位运算的快速算法与四种精度推导
算法·设计模式·程序员
ysbfsy5 小时前
大数计算思路
算法