C语言实现拉格朗日插值法和牛顿插值法

拉格朗日插值法的实现就是通过构造函数,通过已知几对数据然后估算输入对应的数据所得得值。

 通过例子可知道拉格朗日法,假设有三组数据分别为(x0,y0),(x1,y1),(x2,y2),与第一个y值相乘得数的分母是(x0-x1)*(x0-x2),分子是:(x-x1)*(x-x2),第二个数就是分母是(x1-x0)*(x1-x2),分子是(x-x0)*(x-x2),第三个数分子是:(x-x0)*(x-x1),分母是(x2-x0)*(x2-x1).

代码实现:

#include<stdio.h>
# define N 100	
int main()
{
    //设置数据; 
	int n,i,j;double l[N],l1[N],l2[N],x,f=1.0,y=0 ,x1[N],y1[N];
	printf("输入已知数据对数:"); 
	scanf("%d",&n); 
	printf("输入一个x,输入一个y:");
	for(i=0;i<n;i++)
	{  
		//先输入一个x,再输入一个y 
		scanf("%lf",&x1[i]);
		scanf("%lf",&y1[i]);
		//将数据进行赋初值 
		l1[i]=1;
		l2[i]=1;
	}
	printf("输入最后已知的x,求y:") ;//输入数据对
	scanf("%lf",&x);
	//赋初值
	//进行l(x)的分子分母构造 
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			l1[i]=1.0*l1[i]*(x-x1[j]);//分子构造
			if(i!=j)
			  {
			   l2[i]=1.0*l2[i]*(x1[i]-x1[j]);//分母构造
			  }
		}
		l1[i]=1.0*l1[i]/(x-x1[i]);
		l[i]=1.0*l1[i]/l2[i];	
    }
    //计算得到y; 
    for(i=0;i<n;i++)
    {
    	y=y+l[i]*y1[i];
	}
	printf("%lf",y);
	return 0;
}

牛顿插值法:

 以例子为例:0.43505=(0.78846-0.87547)/(2.4-2.2)  ,0.40010=(0.95551-0.87547)/(2.6-2.4)

一阶差商下列数类似,二阶差商:-0.087375=(0.40010-0.43505)/(2.6-2.4-(2.4-2.2) ,-0.073875=(0.37055-0.40010)/(2.8-2.6-(2.6-2.4)),三阶差商:0.02250=(-0.073875+0.087375)/(2.8-2.6-(2.6-2.4)-(2.4-2.2)

据此大家应该能总结出规律:

代码实现,在此说明,由于本人能力有限,这段代码写的非常不好,不能自由实现数据对的更改,但是可以告诉如何修改数据对个数:

#include<stdio.h>
# define N 100 
int main()
{
	int i,j,n=8,n1[N],n2;double x1[N],y1[N],x,y=0,w=1,k2[N],k3[N],k4[N],k5[N],k6[N],k7[N],k8[N],K9[N],k[N];
	//录入数据
    printf("本文以最多8组数据为例,已经满足问题讨论要求\n");//为了发现荣格现象
	printf("请输入进行牛顿插值次数n2(n2<=n):");
	scanf("%d",&n2);
/*	for(i=0;i<8;i++)
	{
       n1[i]=i;
	}
*/
	printf("请一组组数据输入,先输一个x,再输一个y:"); 
	for(i=0;i<n;i++)
	{   
		scanf("%lf",&x1[i]);
		scanf("%lf",&y1[i]);
	}
	printf("输入x点:");
	scanf("%lf",&x);
	//若要换成八组以上基础数据,可将i<7换成你想要的i<?,后面需要加上k[],按照下面规律进行更改
    for(i=0;i<7;i++)
	{
		k2[i]=1.0*(y1[i+1]-y1[i])/(x1[i+1]-x1[i]);
	}
	for(i=0;i<6;i++)
	{
		k3[i]=1.0*(k2[i+1]-k2[i])/(x1[i+2]-x1[i]);
	}
	for(i=0;i<5;i++)
	{
		k4[i]=1.0*(k3[i+1]-k3[i])/(x1[i+3]-x1[i]);
	}
	for(i=0;i<4;i++)
	{
		k5[i]=1.0*(k4[i+1]-k4[i])/(x1[i+4]-x1[i]);
	}
	for(i=0;i<3;i++)
	{
		k6[i]=1.0*(k5[i+1]-k5[i])/(x1[i+5]-x1[i]);

	}
	for(i=0;i<3;i++)
	{
		k7[i]=1.0*(k6[i+1]-k6[i])/(x1[i+6]-x1[i]);
	}
	for(i=0;i<2;i++)
	{
		k8[i]=1.0*(k7[i+1]-k7[i])/(x1[i+7]-x1[i]);
	}
	for(i=0;i<1;i++)
	{
		k8[i]=1.0*(k5[i+1]-k5[i])/(x1[i+5]-x1[i]);
	}
	printf("\n");
	printf("为了方便讨论,以第一个点为起始点,开始讨论");
	y=y1[0];
	//数据录入 
	k[0]=k2[0];//起始点可更改,但为了方便,采取强制第一个
	k[1]=k3[0];
	k[2]=k4[0];
	k[3]=k5[0];
	k[4]=k6[0];
	k[5]=k7[0];
	k[6]=k8[0];
	for(i=0;i<n2;i++)
    {
    	w=w*(x-x1[i]);
    	y=y+w*k[i];
    }
	printf("输出y结果为:%lf\n",y);
	return 0;
}

 本代码进行强制默认,如需更改起始点,需注意更改后的点满足你所要进行的运算次数

数据输入以空格为区分,不要以逗号为区分哇,举例:3.0 2.8不是3.0, 2.8这样输入不含逗号!

C语言实现拉格朗日插值法的思路如下: 首先,定义一个结构体或数组来存储已知点的横纵坐标,可以命名为`Point`结构体,包含`x`和`y`两个成员。 ```c typedef struct { double x; double y; } Point; ``` 然后,实现一个函数来计算拉格朗日插值多项式的系数。该函数接受已知点的数组和点的个数作为参数,返回一个数组,存储插值多项式的系数。 ```c double* calculateCoefficients(Point* points, int numPoints) { double* coefficients = malloc(numPoints * sizeof(double)); for (int i = 0; i < numPoints; i++) { double coefficient = 1.0; for (int j = 0; j < numPoints; j++) { if (i != j) { coefficient *= (points[i].x - points[j].x); } } coefficients[i] = points[i].y / coefficient; } return coefficients; } ``` 接下来,实现一个函数来计算给定横坐标的插值结果。该函数接受已知点的数组、插值多项式的系数数组、点的个数以及待插值的横坐标作为参数,返回插值结果。 ```c double interpolate(Point* points, double* coefficients, int numPoints, double x) { double result = 0.0; for (int i = 0; i < numPoints; i++) { double term = coefficients[i]; for (int j = 0; j < numPoints; j++) { if (i != j) { term *= (x - points[j].x) / (points[i].x - points[j].x); } } result += term; } return result; } ``` 使用时,可以按照以下步骤进行: 1. 创建一个`Point`数组,存储已知点的横纵坐标。 2. 调用`calculateCoefficients`函数计算插值多项式的系数。 3. 调用`interpolate`函数计算给定横坐标的插值结果。 注意:在使用完动态分配的内存后,需要及时释放以避免内存泄漏。 希望这些代码对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值