C语言实现三次样条插值函数
时间: 2023-09-21 15:02:38 浏览: 45
三次样条插值是一种常用的数据插值方法,可以通过一些已知的数据点构造出一个光滑的函数拟合这些数据点并进行插值。下面是一个用C语言实现三次样条插值函数的示例代码。
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000
double x[MAXN], y[MAXN], h[MAXN], b[MAXN], c[MAXN], d[MAXN];
int n;
void input() {
printf("请输入数据点数 n:");
scanf("%d", &n);
printf("请输入已知数据点:\n");
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &x[i], &y[i]);
}
}
void solve() {
for (int i = 1; i < n; i++) {
h[i] = x[i] - x[i-1];
b[i] = (y[i] - y[i-1]) / h[i];
}
c[0] = c[n] = 0;
for (int i = 1; i < n; i++) {
double temp1 = h[i-1] / (h[i-1] + h[i]);
double temp2 = h[i] / (h[i-1] + h[i]);
c[i] = temp1 * c[i-1] + 2 * temp2;
b[i] = 3 * (temp2 * b[i] - temp1 * b[i-1]);
}
for (int i = n-1; i >= 1; i--) {
d[i] = (b[i] - h[i] * d[i+1]) / (2 * h[i] + 2 * h[i-1]);
c[i] = (b[i-1] - h[i-1] * c[i-1]) / (2 * h[i-1] + 2 * h[i]);
}
}
double S(double t) {
int k = 0;
while (k < n && x[k] < t) k++;
if (k == 0) k = 1;
if (k == n) k = n - 1;
double A = c[k-1] * (x[k] - t) - (y[k] - y[k-1]);
double B = -c[k] * (x[k-1] - t) + (y[k] - y[k-1]);
double s = (A * pow(x[k]-t, 3) + B * pow(t-x[k-1], 3)) / (6 * h[k])
+ (y[k-1] - c[k-1] * pow(h[k-1], 2) / 6) * (x[k] - t) / h[k]
+ (y[k] - c[k] * pow(h[k], 2) / 6) * (t - x[k-1]) / h[k];
return s;
}
int main() {
input();
solve();
double t;
while (1) {
printf("请输入插值点 t:");
scanf("%lf", &t);
if (t < x[0] || t > x[n-1]) {
printf("输入错误,请重新输入!\n");
continue;
}
double s = S(t);
printf("在 t=%lf 处的插值结果为:%.5lf\n", t, s);
printf("是否继续插值(1表示是,0表示否):");
int flag;
scanf("%d", &flag);
if (!flag) break;
}
return 0;
}
```
该代码中,`input()`函数用于输入已知的数据点,`solve()`函数用于解三次样条插值方程,`S()`函数用于计算插值点的函数值。其中,`b`、`c`、`d`数组分别存储三次样条插值方程中的系数,`h`数组存储相邻数据点的间距。在计算插值点的函数值时,首先找到插值点所在的区间 `[x[k-1], x[k]]`,然后根据三次样条插值方程计算出函数值。