【算法】牛顿迭代法

算法-牛顿迭代法


前置知识
  • 函数(数学意义上的)
  • 导数(斜率)
  • 基本导函数
  • 泰勒展开(不需要)
  • 小学几何(雾)

思路

现在,你有一个方程 f ( x ) = 0 f(x)=0 f(x)=0,怎么求解它的根(近似根)呢?
牛顿是这么干的(以下以方程 x 3 + 2 x 2 + 3 x + 4 = 0 为例 x^3+2x^2+3x+4=0为例 x3+2x2+3x+4=0为例):
先作函数 f ( x ) f(x) f(x) 的图像,并任取 x x x 轴上的一点 A A A
图一
f ( x ) f(x) f(x) 在A处的切线 g g g g g g x x x 轴交于 B B B(本人很菜,此处表述不太准确,请结合图片理解)
图二
重复上述操作,就可以得到方程 f ( x ) = 0 f(x)=0 f(x)=0 其中一个近似根了。
这是迭代 4 4 4 次的效果
图三
这里的点 E E E 已经极其精确了,误差在 1 0 − 5 10^{-5} 105 左右。
我们可以根据下文的递推式证明牛顿迭代法的近似根精度是以平方的级别增长的。
图四
(图片来源:GeoGebra)


数学实现

接下来,考虑怎么使用数学的语言求出递推式
这里给出不使用泰勒展开的证明(好像很简单啊
我们设迭代 k k k 次后得到的近似根为 x k x_k xk
此时,在 x x x 轴上 x k − x k + 1 = f ( x k ) f ′ ( x k ) x_k-x_{k+1}=\frac{f(x_k)}{f'(x_k)} xkxk+1=f(xk)f(xk)请自证
x k + 1 x_{k+1} xk+1 x k x_k xk 表示,则有 x k + 1 = x k − f ( x k ) f ′ ( x k ) x_{k+1}=x_k-\frac{f(x_k)}{f'(x_k)} xk+1=xkf(xk)f(xk)
这就是牛顿迭代法的递推式。


实现代码

这是自己写的奇奇怪怪的程序的一部分。。。
此程序用来处理整次数多项式方程的根。

void NewtonIterationMethod(){//f(x)=0
	ll k;long double a[6],x;
	cout<<"This code will help you solve f(x)=0(decimal solution)!\n";
	cout<<"Please type in the maxium power times k:";cin>>k;
	cout<<"please type in k+1 numbers, which is the coefficient of x^0 to x^k:";for (ll i=0;i<=k;i++) cin>>a[i];
	cout<<"Please type in the initial solution x0:";cin>>x;
	cout<<"We can use Newton iteration method to solve the equation\n";
	for (ll i=1;;i++){
		printf("We use the folmula x%d=x%d-f(x%d)/f'(x%d) to calculate x%d\n",i,i-1,i-1,i-1,i);
		long double f1=0.000,f2=0.000;
		for (ll i=0;i<=k;i++) f1=f1+a[i]*pow(x,i);
		for (ll i=1;i<=k;i++) f2=f2+i*a[i]*pow(x,i-1);
		assert(fabs(f2)>eps);
		long double xp=x-f1/f2;
		printf("So, we can get that x%d=%.18Lf\n",i,xp);
		x=xp;
		ll f;
		cout<<"Do you want another calculation?\ntype 1 for yes, or type any other for no:";cin>>f;
		if (f!=1) break;
	}
	printf("So the solution we get is: x=%.18Lf\n",x);
}

练习

附记

牛顿迭代法在处理某些方程时会出现迭代不收敛的情况。
例子:方程 x = 0 \sqrt{x}=0 x =0 的递推式为 x k + 1 = − x k x_{k+1}=-x_k xk+1=xk 一下子无语了
此时,建议使用改进的牛顿迭代法解决:下山法改进
我才不会告诉你我不会其他方法呢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值