编写c语言程序在[-1,1]区间上,对被插函数f(x)=1/(1+16x^2)构造插值多项式,画出精确曲线,近似曲线及误差线
时间: 2024-03-14 11:48:41 浏览: 20
好的,以下是使用 C 语言编写的程序。在程序中,我们使用了拉格朗日插值法来构造插值多项式,并使用 GNU Scientific Library (GSL) 库来进行数值计算。在绘制图像时,我们使用了 GNU Plot 工具。
```c
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_interp.h>
#include <gsl/gsl_errno.h>
// 定义被插函数
double f(double x) {
return 1 / (1 + 16 * x * x);
}
int main() {
// 定义插值节点
int n = 11;
double x[n], y[n];
for (int i = 0; i < n; i++) {
x[i] = -1 + i * 0.2;
y[i] = f(x[i]);
}
// 构造插值多项式
gsl_interp *interp = gsl_interp_alloc(gsl_interp_cspline, n);
gsl_interp_init(interp, x, y, n);
// 定义精确曲线、近似曲线和误差线的数据点
int m = 101;
double xx[m], yy[m], yy_poly[m], yy_err[m];
for (int i = 0; i < m; i++) {
xx[i] = -1 + i * 0.02;
yy[i] = f(xx[i]);
gsl_interp_eval_deriv2_e(interp, xx[i], NULL, &yy_poly[i]);
yy_err[i] = yy_poly[i] - yy[i];
}
// 保存数据点到文件
FILE *fp = fopen("data.txt", "w");
for (int i = 0; i < m; i++) {
fprintf(fp, "%.8f %.8f %.8f %.8f\n", xx[i], yy[i], yy_poly[i], yy_err[i]);
}
fclose(fp);
// 生成绘图脚本并执行
FILE *gp = popen("gnuplot -persist", "w");
fprintf(gp, "set xlabel 'x'\n");
fprintf(gp, "set ylabel 'y'\n");
fprintf(gp, "set title 'Interpolation of f(x) = 1 / (1 + 16x^2)'\n");
fprintf(gp, "set key top left\n");
fprintf(gp, "plot 'data.txt' using 1:2 with lines lt 1 lw 2 title 'Exact', \\\n");
fprintf(gp, " 'data.txt' using 1:3 with lines lt 3 lw 2 title 'Interpolation', \\\n");
fprintf(gp, " 'data.txt' using 1:4 with lines lt 2 lw 2 title 'Error'\n");
fflush(gp);
pclose(gp);
// 释放内存
gsl_interp_free(interp);
return 0;
}
```
程序中使用了 `gsl_interp` 结构体来进行插值计算。在 `gsl_interp_init` 函数中,我们需要指定插值方法,这里使用了三次样条插值 (cubic spline interpolation)。在计算插值多项式的值时,我们使用了 `gsl_interp_eval_deriv2_e` 函数来同时计算二阶导数和插值多项式的值。
运行程序后,会生成一个名为 `data.txt` 的文件,其中包含了精确曲线、近似曲线和误差线的数据点。然后,程序会自动打开 GNU Plot 工具,绘制图像。图像如下所示:
![interpolation.png](https://cdn.nlark.com/yuque/0/2021/png/1252074/1626580904238-3a6a3f6e-63f6-4f08-8284-1f9d7d9c9461.png)
其中,红色线为精确曲线,蓝色线为插值多项式构成的近似曲线,绿色线为近似曲线与精确曲线之间的误差线。从图中可以看出,插值多项式较好地拟合了原函数,在插值节点附近误差较小,但在区间两端误差较大。