如何使用gsl_interp获得多项式插值系数?

时间:2014-11-18 11:53:53

标签: c++ interpolation gsl

所以我有下面的代码。它完美地计算了多项式的所有y点(并打印出来用gnuplot绘制),但是如何得到结果多项式(在这种情况下为1-x²)?

void twoDegreePoly() {
    int n = 3;
    double x[n],y[n];
    printf ("#m=0,S=16\n");
    for (int i=0; i<n ;i++) {
        x[i] = ((double)2*i)/2 -1;
        y[i] = f(x[i]);
        printf ("%g %g\n", x[i], y[i]);
    }
    printf ("#m=1,S=0\n");

    gsl_interp_accel *acc = gsl_interp_accel_alloc ();
    const gsl_interp_type *t = gsl_interp_polynomial;
    gsl_interp* poly = gsl_interp_alloc(t,n);
    gsl_interp_init (poly, x, y,n);
    for (double xi=x[0]; xi<x[n-1]; xi+= 0.01) {
        double yi = gsl_interp_eval (poly, x, y, xi, acc);
        printf ("%g %g\n", xi, yi);
    }
}

2 个答案:

答案 0 :(得分:2)

快速扫描documentation后,GSL似乎没有这样的功能。这可能是由两个原因造成的:首先,获得多项式系数是特殊的,这种插值方法不适合一般设计(可以处理任意函数)。其次,引用数字食谱:

  

但请确保系数是您所需要的。通常,内插多项式的系数可以比其在期望横坐标处的值更精确地确定。另外,确定仅用于计算插值的系数不是一个好主意。如此计算的值不会完全通过列表点,例如......

原因在于,原则上,计算系数涉及求解具有Vandermonde矩阵的线性系统,该矩阵具有高度病态。

然而,Numerical Recipes提供了一个例程polcoe,通过它您可以获得插值多项式。您可以在第3.5章找到它。在free second edition

答案 1 :(得分:1)

我用Akima的插值做了类似的事情。 首先,将状态定义为GSL:

typedef struct
{
  double *b;
  double *c;
  double *d;
  double *_m;
}akima_state_t;

然后,创建插值

spline = gsl_spline_alloc (gsl_interp_akima, M_size);
gsl_spline_init (spline, x, y, M_size);

之后,你可以这样做:

const akima_state_t *state = (const akima_state_t *) ( spline -> interp -> state);
  double _b,_c,_d;
  for (int i = 0; i < M_size; i++)
  {
    _b = state->b[i];
    _c = state->c[i];
    _d = state->d[i];
    std::cout << "(x>"<<x[i]<<")*(x<"<<x[i+1]<<")*("<<y[i]<< "+ (x-"<< x[i]<<")*("<<_b<<"+(x-"<< x[i]<<")*("<<_c<<"+"<<_d<<"*(x-"<<x[i]<<")))) + ";
  }

我没有尝试过多项式插值,但这里是多项式的状态结构,它应该是一个很好的起点。

typedef struct
{
  double *d;
  double *coeff;
  double *work;
}
polynomial_state_t;