数值分析C++实现牛顿(Newton)插值值多项式

问题:已知插值节点序列(xi, yi),i=01,2,…,n, 牛顿(Newton) 插值值多项
式Nn(x)计算的函数f(x)在点x0的近似值。
首先给出算法步骤:
(1)给已知条件(X0,y0),(X1,y1),(X2,y2),…,(Xn,yn)点进行对应的包装操作和编号处理
(2)根据已知条件(X0,y0),(X1,y1),(X2,y2),…,(Xn,yn)和要求解的x值计算差商:
在这里插入图片描述
2.1 当k=0时,N(x)=f(x0);
2.2 当k=1时,首先通过差商公式计算得到1阶差商
在这里插入图片描述
然后通过计算w(x)=(X-X0)(X-Xn-1)
2.3 N(x)=N(x)+f[x0,x1]*(X-X0);
2.4 每次k自增1,重复2.2~2.3步骤操作,直到k=n为止
2.5 最后得出结果 N(x)即为x对应的值
源程序代码及运行结果截图

	#include<iostream>
	#include<vector>
	#include<math.h>
	#include<iomanip>
	using namespace std;

	struct Point
	{
		Point(float x, float y) {
			this->x = x;
			this->y = y;
		}
		Point() {
		}
		float x;			//坐标的x轴
		float y;			//坐标的y轴
		int k = -1;          //给每个已知点进行编号,表示第k个点,k = 0,1,2....n
	};
	//存放已知点编号完成后的动态向量
	vector<Point> *vec = NULL;

	/*
	@param points  要初始化的已知点数组
	@param len 数组长度
	*/
	void init(Point points[], int len)
	{
		vec = new vector<Point>();
		for (int i = 0; i < len; i++)
		{
			//给每个点进行编号处理
			points[i].k = i;
			//将每个点放入到向量集合中
			vec->push_back(points[i]);
		}
	}
	/*
	@to do: 获取差商值
	@param  k   第k个点
	@return float 返回结果
	*/
	float getDifferenceQuotient(int k) {
		float result = 0;			//差商值
		vector<Point>::iterator it;
		int count = 0;
		for (it =vec->begin();  it!=vec->end(); it++)
		{
			float molecule = (*it).y;			//差商的分子
			float denominator = 1;      //差商的分母
			for (int i = 0; i <= k; i++)
			{

				if ((*it).k != i)
				{
					//开始利用差商公式累加求解
					denominator = denominator*((*it).x - (*vec)[i].x);
				}
			}

			//计算差商值
			result += (molecule / denominator);
			if (count == k)
			{
				break;
			}
			count++;
		}
	
		return result;
	}
	/*
	@to do: 获取(x-x0)*(x-x1)*...*(x-Xk-2)的连乘结果
	@param X   需要求解的x的值
	@param k   需要连乘的次数
	@return float 返回结果
	*/
	float getContinuousMultiplication(float x,int k) {
		//用于保存连乘的结果
		float result = 1.0f;
		vector<Point>::iterator it;
		//控制跳出循环的变量
		int count = 0;
		for (it = vec->begin(); it != vec->end(); it++)
		{
			//开始跳出循环
			if (count == k)
			{
				break;
			}
			//累加进行求解 (X-X0)*...*(X-Xn-1)
			result *= (x-(*it).x);
			count++;
		}
		return result;
	}
	/*
	@to do: 获取x0节点对应的朗格朗日函数值
	@param X0   需要求解的x0的值
	@return float 返回结果
	*/
	float getNewTonValue(float x0) {
	
		vector<Point>::iterator it;
		float result = 0;				//最终结果
		//用于控制k=0的情况和k>0的情况
		int index = 0;
		for (it = vec->begin(); it != vec->end(); it++)
		{
			if (index == 0)
			{
				//处理k=0时的情况
				result += (*it).y;
			}
			else {
				//处理k > 1时的情况
				int k = (*it).k;
				//获取差商值
				float a = getDifferenceQuotient(k);
				//获取连乘的值
				float b = getContinuousMultiplication(x0,k);
				//获取N(x)
				result +=  a*b;
			}
			index++;
		}

		return result;
	}

	int main()
	{
		//测试数据
		Point p1(0.4f, -0.9163f);
		Point p2(0.5f, -0.6931f);
		Point p3(0.6f, -0.5108f);
		Point p4(0.7f, -0.3567f);
		Point p5(0.8f, -0.2231f);
		Point points[5] = { p1,p2,p3,p4,p5 };
		init(points, 5);
		float x = 0.54f;
		float result = getNewTonValue(x);
		cout << "通过牛顿插值公式计算后的数当x=" << x << "时其结果为:" << result << endl;
		system("pause");
		return 0;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌意随影

您的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值