牛顿逼近法求迭代式及应用
基本原理先将原问题表达为?f(x)=0?求零根问题 选取?x0?为接近根的初始值,不断用过? 所以?xn?是? 整理并解得: 即为迭代通式。 迭代的适用性首先原函数的导数可以比较容易的可得,且其导函数中不含有形如原函数的因子。
牛顿迭代法具有较高的收敛速度,收敛阶数为=2。 对于f(x)在区间[a,b]上,需满足:
因此,在放宽x0取值时,必须要满足上述4个条件才可以迭代逼近。 求该问题等价于 所以有 f'(x)=2x?,代入到迭代通式中得: 简化整理得: 即为 求该问题等价于 所以有?f'(x)=3x2?,代入到迭代通式中得:
简化整理得: 即为 实际应用讨论牛顿逼近法一方面可以了解Math.sqrt()实现,另一方面,对于大数计算/高精度计算就显得非常重要了。 例如Java中BigDecimal对象没有sqrt方法,如果需要对一个大数(或者一个高精度实数)进行开方应该怎么办? 就按照上面的方法我们自己实现一个:(关键点就是得到迭代式) //?利用BigDecimal做数值容器 //?利用上面求出的牛顿法迭代式 //?实现??对任意大数/任意精度实数进行开方 static?BigDecimal?newtonMethodSqrt2?(BigDecimal?a,?int?precision)?{ ??????????BigDecimal?_2?=?new?BigDecimal(2); ??????????BigDecimal?xn?=?a.divide(_2);?????//?x0的初始值 ??????????MathContext?mc?=?new?MathContext(precision,?RoundingMode.HALF_UP); ??????????int?loop?=?(int)?Math.ceil(Math.log(precision)?/?Math.log(2)); ??????????for?(int?i?=?loop;?i?>=?0;?i--)?{ ????????????????xn?=?xn.add(a.divide(xn,?mc)).divide(_2,?mc);?//?上面求出的迭代式 ??????????} ??????????return?xn; } public?static?void?main(String[]?args)?{ ??????????System.out.println(newtonMethodSqrt2(new?BigDecimal(2),?100)); } 这就是对一个大数/高精度数进行开方的运算(指定了100位精度),看一下运算结果,再对比一下高精度计算器bc的结果: 与bc结果一致,即有了 特别注意到,当上面循环改为 i>0 时,第97位以后出现偏差,即有了 这也说明了,有限精度多次计算造成精度降低,于是,要适当的提高精度要求或者增加迭代次数。 其它某些高阶方程问题无法用计算机直接计算的时候,可以尝试使用牛顿迭代法。 显然,要利用计算机解决这些问题,就需要算出迭代式,这才是程序的关键。 前面已经给出了利用牛顿迭代法求开方的例子。同时也给出开三次方的迭代式,上面的newtonMethodSqrt2按通式稍稍变形即可计算开三次方。 同理,用通式算出开n次方的迭代式,也可以计算。 同理,对于大数?loga(x)?的计算,等价于对?X?开?a?次方的问题,所以如法炮制。 还有,对于其它某些高阶问题需要用迭代法解决时,发现其导数不易求得或者牛顿法迭代式比原式更复杂,则可以考虑使用牛顿迭代法的变种,比如牛顿下山法、单点弦截法、双点弦截法等来解决,但通常它们具有更低的收敛速度,即需要更多次的迭代才能很好的逼近真实值。? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |