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

    }
}
相关推荐
ttod_qzstudio2 分钟前
Java 常用语法极简通关(五):类与对象——字段、方法、构造器、this 与 static
java·开发语言·python
罗西的思考16 分钟前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX1 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
萧瑟余晖1 小时前
Java深入解析篇十七之Spring Security
java·开发语言·spring
爱跳舞的烤冷面2 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号2 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽2 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI2 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
北域码匠3 小时前
PID 控制算法完整详解(C# 原生实现,无第三方库)
c#·pid控制·工控开发·闭环控制·自动控制算法·数字pid·增量式pid
离陌在学C#4 小时前
C# 重载与重写:深入理解面向对象编程的核心概念
java·c#