我正在研究依赖于计算多项式插值的内维尔算法。有关它的更多信息,您可以在http://en.wikipedia.org/wiki/Neville%27s_algorithm找到。在某些时候计算多项式对我来说不是问题。有很多关于它的来源。我的问题依赖于我不想在某些时候计算多项式,我想以这种形式获得多项式a_0 + a_1x + ... + a_nx^n
:我不知道如何开始。你能给我一些建议吗?
问问题
457 次
2 回答
2
Neville 算法的一种变体允许计算一些常数(不是多项式系数),以便与另一个函数一起使用,该函数可以在任何点评估插值多项式。后一种功能很容易区分。下面的 C 代码是我使用的,我相信它可以正常工作。但是,我怀疑您可能会对多项式插值的效果感到失望,除非您提供的数据确实来自多项式。如果您可以轻松地在许多点对数据进行采样,那么最好通过对数据进行最小二乘拟合来找到多项式(表示为切比雪夫多项式之和)。
// 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;
}
于 2014-10-31T12:32:09.527 回答
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)。
如果你想得到一个精确的结果,请使用任意精度的有理算术包(例如 C/C++ 的 GMP)。或者,使用浮点数进行计算,但最终可能会出现影响您的舍入错误。
于 2014-12-13T19:37:53.397 回答