C++实现牛顿迭代法求一元二次方程

        牛顿迭代法定义如下(来自百度百科):


        用牛顿迭代法小试牛刀用来求解一元二次方程的根(工程下载地址【注:不好意思,下载题目写成了二元一次方程,见谅。】,release下的应用程序可以直接运行),代码如下:

typedef struct _MyP
{
	float x;
	float y;
}MyP;

// C++实现牛顿迭代法求一元二次方程的解
// 设一元二次方程的通用方程为 y = ax^2 + bx + c
// 则其导函数为 y = 2ax + b

// 1、构造方程
float accuracy = 0.001;
float a = -5;
float b = 4;
float c = 0;

// 2、找极值点,令导函数 y = 2ax + b = 0,求的极值点坐标P.x = -b/2a, P.y = aP.x^2 + bP.x + c
MyP P;
MyP PTemp;
P.x = (-1 * b) / (2 * a);
P.y = (a * P.x * P.x) + (b * P.x) + c;

// 3、判断定义域在(-无穷大, P.x)和在定义域(P.x, +无穷大)的单调性和开口方向
PTemp.x = P.x - 10;
PTemp.y = (a * PTemp.x * PTemp.x) + (b * PTemp.x) + c;
if (PTemp.y > P.y){ // 在(-无穷大, P.x)单调递减,在(P.x, +无穷大)单调递增,开口向上

	ui.tbResult->append(QString::fromLocal8Bit("开口方向:向上"));
	// 4.1、判断方程是否有解,有解的话几个解
	if (P.y > 0){

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:无解"));
	}
	else if (P.y == 0){

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:1个解"));
		ui.tbResult->append(QString::fromLocal8Bit("解1:") + QString("(%1, %2)").arg(P.x).arg(P.y));
	}
	else{

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:2个解"));
		// 5.1、牛顿迭代求解
		float k;		// 切点斜率
		MyP P1, P2;
		P1.x = P.x + accuracy;	// 设置迭代起始点1
		P2.x = P.x - accuracy;	// 设置迭代起始点2
		float x1, x2;	// 解1和解2

		while(1){

			k = (2 * a * P1.x) + (b);					// 求切点斜率
			x1 = P1.x - (P1.y / k);						// 切线与X轴的交点的x坐标
			P1.y = (a * x1 * x1) + (b * x1) + c;		// 求x1在一元二次方程曲线上的Y值
			if (fabs(P1.y) <= 0.001){

				if (x1 < accuracy) x1 = 0;
				if (P1.y < accuracy) P1.y = 0;
				ui.tbResult->append(QString::fromLocal8Bit("解1:") + QString("(%1, %2)").arg(x1).arg(P1.y));
				break;
			}
			P1.x = x1;									// 更新迭代点
		}
		while(1){

			k = (2 * a * P2.x) + (b);					// 求切点斜率
			x2 = P2.x - (P2.y / k);						// 切线与X轴的交点的x坐标
			P2.y = (a * x2 * x2) + (b * x2) + c;		// 求x1在一元二次方程曲线上的Y值
			if (fabs(P2.y) <= 0.001){

				if (x2 < accuracy) x2 = 0;
				if (P2.y < accuracy) P2.y = 0;
				ui.tbResult->append(QString::fromLocal8Bit("解2:") + QString("(%1, %2)").arg(x2).arg(P2.y));
				break;
			}
			P2.x = x2;									// 更新迭代点
		}
	}
}
else{				// 在(-无穷大, P.x)单调递增,在(P.x, +无穷大)单调递减,开口向下		

	ui.tbResult->append(QString::fromLocal8Bit("开口方向:开口向下"));
	// 4.2、判断方程是否有解,有解的话几个解
	if (P.y < 0){

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:无解"));
	}
	else if (P.y == 0){

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:1个解"));
		ui.tbResult->append(QString::fromLocal8Bit("解1:") + QString("(%1, %2)").arg(P.x).arg(P.y));
	}
	else{

		ui.tbResult->append(QString::fromLocal8Bit("解集情况:2个解"));
		// 5.2、牛顿迭代求解
		float k;		// 切点斜率
		MyP P1, P2;
		P1.x = P.x + accuracy;	// 设置迭代起始点1
		P2.x = P.x - accuracy;	// 设置迭代起始点2
		float x1, x2;	// 解1和解2

		while(1){

			k = (2 * a * P1.x) + (b);					// 求切点斜率
			x1 = P1.x - (P1.y / k);						// 切线与X轴的交点的x坐标
			P1.y = (a * x1 * x1) + (b * x1) + c;		// 求x1在一元二次方程曲线上的Y值
			if (fabs(P1.y) <= 0.001){

				if (x1 < accuracy) x1 = 0;
				if (P1.y < accuracy) P1.y = 0;
				ui.tbResult->append(QString::fromLocal8Bit("解1:") + QString("(%1, %2)").arg(x1).arg(P1.y));
				break;
			}
			P1.x = x1;									// 更新迭代点
		}
		while(1){

			k = (2 * a * P2.x) + (b);					// 求切点斜率
			x2 = P2.x - (P2.y / k);						// 切线与X轴的交点的x坐标
			P2.y = (a * x2 * x2) + (b * x2) + c;		// 求x1在一元二次方程曲线上的Y值
			if (fabs(P2.y) <= 0.001){

				if (x2 < accuracy) x2 = 0;
				if (P2.y < accuracy) P2.y = 0;
				ui.tbResult->append(QString::fromLocal8Bit("解2:") + QString("(%1, %2)").arg(x2).arg(P2.y));
				break;
			}
			P2.x = x2;									// 更新迭代点
		}

	}
}

        开发环境为VS2013+QT580+OPENCV300,软件运行截图如下:



        工程中的release下的应用程序可以直接运行,需要软件和代码工程的请戳这里

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值