用C语言 在区间[-1,1]上,对被插函数f(x)=1/(1+16x^2 )构造插值多项式,采用空间上均匀分布的节点,构造不同阶的插值多项式来近似被插函数,画出精确曲线、近似曲线及误差线。
时间: 2024-03-20 07:39:56 浏览: 68
数值计算,插值,解方程(C语言实现)
以下是使用C语言实现在区间[-1,1]上,对被插函数f(x)=1/(1+16x^2 )构造插值多项式的代码。其中,采用空间上均匀分布的节点,分别构造了1阶、3阶和5阶插值多项式,并将其与精确曲线进行比较,画出了近似曲线和误差线。
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 11 // 节点数
#define ORDER 5 // 插值多项式阶数
double f(double x) // 被插函数
{
return 1.0 / (1.0 + 16.0 * x * x);
}
double lagrange(double x[], double y[], int n, double t) // 拉格朗日插值多项式
{
double sum = 0.0;
for (int i = 0; i < n; i++) {
double product = 1.0;
for (int j = 0; j < n; j++) {
if (j != i) {
product *= (t - x[j]) / (x[i] - x[j]);
}
}
sum += y[i] * product;
}
return sum;
}
double newton(double x[], double y[], int n, double t) // 牛顿插值多项式
{
double h[N], b[N], c[N], d[N];
for (int i = 0; i < n; i++) {
h[i] = x[i + 1] - x[i];
b[i] = (y[i + 1] - y[i]) / h[i];
}
for (int i = 1; i < n; i++) {
c[i] = (b[i] - b[i - 1]) / h[i];
}
for (int i = 1; i < n; i++) {
d[i] = c[i] - c[i - 1];
}
int k = 0;
for (int i = 0; i < n; i++) {
if (t >= x[i] && t <= x[i + 1]) {
k = i;
break;
}
}
double p = (t - x[k]) / h[k];
return y[k] + b[k] * p + c[k] * p * (p - 1.0) * h[k] + d[k] * p * (p - 1.0) * (p - 2.0) * h[k] * h[k] / 6.0;
}
int main()
{
double x[N], y[N], t, exact, approx, error;
double exact_values[200], approx_values[200], error_values[200];
FILE *fp;
// 构造节点
for (int i = 0; i < N; i++) {
x[i] = -1.0 + 2.0 * i / (N - 1);
y[i] = f(x[i]);
}
// 1阶插值多项式
fp = fopen("order1.txt", "w");
for (int i = 0; i < 200; i++) {
t = -1.0 + 2.0 * i / 199;
exact = f(t);
approx = lagrange(x, y, 2, t);
error = fabs(approx - exact);
fprintf(fp, "%lf %lf %lf %lf\n", t, exact, approx, error);
exact_values[i] = exact;
approx_values[i] = approx;
error_values[i] = error;
}
fclose(fp);
// 3阶插值多项式
fp = fopen("order3.txt", "w");
for (int i = 0; i < 200; i++) {
t = -1.0 + 2.0 * i / 199;
exact = f(t);
approx = lagrange(x, y, 4, t);
error = fabs(approx - exact);
fprintf(fp, "%lf %lf %lf %lf\n", t, exact, approx, error);
exact_values[i] = exact;
approx_values[i] = approx;
error_values[i] = error;
}
fclose(fp);
// 5阶插值多项式
fp = fopen("order5.txt", "w");
for (int i = 0; i < 200; i++) {
t = -1.0 + 2.0 * i / 199;
exact = f(t);
approx = lagrange(x, y, 6, t);
error = fabs(approx - exact);
fprintf(fp, "%lf %lf %lf %lf\n", t, exact, approx, error);
exact_values[i] = exact;
approx_values[i] = approx;
error_values[i] = error;
}
fclose(fp);
// 画出精确曲线、近似曲线及误差线
fp = fopen("plot.txt", "w");
for (int i = 0; i < 200; i++) {
t = -1.0 + 2.0 * i / 199;
fprintf(fp, "%lf %lf %lf %lf\n", t, f(t), lagrange(x, y, ORDER + 1, t), fabs(lagrange(x, y, ORDER + 1, t) - f(t)));
}
fclose(fp);
printf("Done!\n");
return 0;
}
```
运行上述代码后,会生成三个数据文件(order1.txt、order3.txt、order5.txt)和一个绘图数据文件(plot.txt),可以使用 MATLAB 等软件将其绘制成图形,以便比较精确曲线、近似曲线及误差线。
阅读全文