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

    }
}
相关推荐
昇腾CANN10 分钟前
TileLang-Ascend 算子性能优化方法与实操
开发语言·javascript·性能优化·昇腾·cann
AGV算法笔记17 分钟前
CVPR 2025 最新感知算法解读:GaussianLSS 如何用 Gaussian Splatting 重构 BEV 表示?
算法·重构·自动驾驶·3d视觉·感知算法·多视角视觉
沐知全栈开发21 分钟前
ionic 手势事件详解
开发语言
lsx20240642 分钟前
Bootstrap 按钮
开发语言
神仙别闹1 小时前
基于 Python 实现 BERT 的情感分析模型
开发语言·python·bert
禾叙_1 小时前
【langchain4j】结构化输出(六)
java·开发语言
NQBJT1 小时前
VS Code配置Python人工智能开发环境
开发语言·人工智能·vscode·python
byoass1 小时前
智巢AI知识库深度解析:企业文档管理从大海捞针到精准狙击的进化之路
开发语言·网络·人工智能·安全·c#·云计算
勤劳的进取家1 小时前
数据链路层基础
网络·学习·算法
南境十里·墨染春水1 小时前
C++笔记 STL——set
开发语言·c++·笔记