符号计算是来自Neville算法的多项式

时间:2014-10-30 17:23:28

标签: algorithm numerical-methods polynomials

我正在研究Neville的算法,该算法依赖于计算多项式插值。您可以在http://en.wikipedia.org/wiki/Neville%27s_algorithm找到更多相关信息。在某些时候计算多项式对我来说不是问题。它有很多来源。我的问题依赖于我不想在某个时刻计算多项式,我想得到这种形式的多项式:a_0 + a_1x + ... + a_nx^n。我不知道如何开始。你能给我一些提示吗?

2 个答案:

答案 0 :(得分:2)

Neville算法的变体允许人们计算一些常数(不是多项式系数),以便与可以在任何点评估插值多项式的另一个函数一起使用。后一种功能可以直接区分。下面的C代码是我使用的,我相信它可以正常工作。但是我怀疑你可能会对多项式插值的工作方式感到失望,除非你输入它的数据确实来自多项式。如果您可以在许多点轻松地对数据进行采样,那么最好通过对数据进行最小二乘拟合来找到多项式(表示为chebyshev多项式的总和)。

// fill C (allocated if null) with params for interpolating polynomial
// use params with interp_poly_eval
// !! these are NOT polynomial coefficients. 

double* interp_poly( Int deg, const double* x, const double* y, double* restrict C)
{
double* c = C ?: calloc( deg+1, sizeof *c);
Int i, j;
    memcpy( c, y, (deg+1)*sizeof *y);
    for (i=1; i<=deg; i++) 
    {   for (j=deg; j>=i; j--)
        {   c[j] = (c[j]-c[j-1]) / (x[j]-x[j-i]);
        }
    }
    return c;
}


double  interp_poly_eval( Int deg, const double* c, const double* x, double X)
{
double  p = c[deg];
Int i = deg;
    while( --i >= 0)
    {   p = c[i] + (X-x[i])*p;
    }
    return p;
}

// as above but also returns derivative of the polynomial through pdp
double  interp_poly_eval_d( Int deg, const double* c, const double* x, double X, double* pdp)
{
double  p = c[deg];
double  dp = 0.0;
Int i = deg;
    while( --i >= 0)
    {   dp = (X-x[i])*dp + p;
        p = c[i] + (X-x[i])*p;
    }   
    *pdp = dp;
    return p;
}

答案 1 :(得分:1)

您需要具有可以表示单变量(超过一个变量)多项式的类/数据结构。然后使用Neville算法本身很容易计算实际多项式(即其系数)而不仅仅是单个点,即

  P[0,0] = y[0]   ; constant
  P[1,1] = y[1]   ; constant

然后递归

  P[a,b] = P[a,b-1] * x[b]/C + P[a,b-1] * -X/C + P[a+1,b] * -x[a]/C + P[a+1,b] * X/C

其中X是多项式“x”(即一次单项式),C是常数X [b] -X [a]。

当您像往常一样遵循算法中的递归时,这将为您提供实际的多项式。

注意,上面所有的算术都是多项式的,即P [a,b-1] * x [b] / C表示多项式P [a,b-1]乘以常数x [b] / C(第b点的x坐标除以C)。

如果您想获得精确的结果,请使用任意精度的有理算术包(例如GMP for C / C ++)。或者,使用浮点数进行计算,但最终可能会出现影响您的舍入误差。