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这样输入不含逗号!

  • 21
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值