java弦截法,牛顿逼近法求迭代式及应用

基本原理

先将原问题表达为 f(x)=0求零根问题

设 r 是 f(x)=0 的一个根,则 x0处的切线方程为

de9fb22edd86ba455c5c26f2c41ea7f7.gif

04465eaf0e5670d9c060b720c61c8cd1.gif

选取 x0 为接近根的初始值,不断用过

8f15c491431a3b404666466486f5b0fe.gif 点的切线将 

844632ddcfdfad890b1a02647cb5ba4a.gif 的过程就是迭代过程。

所以 xn 是

c400275a27edc32f5f2fbea2c029437d.gif  的解。

整理并解得:

f96e28763c30a56a6ebd6c6ca515edc0.gif

即为迭代通式。

迭代的适用性

首先原函数的导数可以比较容易的可得,且其导函数中不含有形如原函数的因子。

另外需要关注两个问题:

迭代是否收敛?    直接决定是否可以使用迭代法

迭代的收敛速度?    决定了逼近的速度

牛顿迭代法具有较高的收敛速度,收敛阶数为=2。

而牛顿迭代法的局部收敛性较强,只有初值充分地接近,才能确保迭代序列的收敛性。

为了放宽对局部收敛性的限制,必须再增加条件建立以下收敛的充分条件。

对于f(x)在区间[a,b]上,需满足:

f(a)f(b)<0,即保证根的存在性

f'(x)≠0,单调性是一致的,即有唯一的解

f"(x)不变号,即函数的凹向不变

f'(x0)f"(x0)>0

因此,在放宽x0取值时,必须要满足上述4个条件才可以迭代逼近。

6b701dce61c8c0bb686a788781b33159.gif的迭代式

该问题等价于

f5fffd7fa992d3c2afc32b358bb477c1.gif的问题。

所以有 f'(x)=2x ,代入到迭代通式中得:

7309de2b3f706110e64c68224bcf68e8.gif

简化整理得:

56a532874bd28f3751d4cf09dfa1ec45.gif

即为

6b701dce61c8c0bb686a788781b33159.gif的逼近法解决的迭代式。

28d6214f03dc0bacfe5851a8ed3cab75.gif的迭代式

该问题等价于

3dea0ba109a2f653a8f5a514a9b6e3ac.gif

所以有 f'(x)=3x2,代入到迭代通式中得:

428c9acfac1e06cc53476436fadcdf0b.gif

简化整理得:

d90c27c6ccd552f24561144e7ae1fbf2.gif

即为

28d6214f03dc0bacfe5851a8ed3cab75.gif的逼近法解决的迭代式。

实际应用

讨论牛顿逼近法一方面可以了解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的结果:

baf2b265b899114cfe418097c10bf00c.gif

与bc结果一致,即有了

c396928ce68fbfcab0e8a78e04318bf9.gif的精度。

特别注意到,当上面循环改为 i>0 时,第97位以后出现偏差,即有了

e8e860586cfa8c4bb3f674c33fa7a953.gif的精度。

这也说明了,有限精度多次计算造成精度降低,于是,要适当的提高精度要求或者增加迭代次数。

其它

某些高阶方程问题无法用计算机直接计算的时候,可以尝试使用牛顿迭代法。

显然,要利用计算机解决这些问题,就需要算出迭代式,这才是程序的关键。

前面已经给出了利用牛顿迭代法求开方的例子。同时也给出开三次方的迭代式,上面的newtonMethodSqrt2按通式稍稍变形即可计算开三次方。

同理,用通式算出开n次方的迭代式,也可以计算。

同理,对于大数 loga(x)的计算,等价于对 X开 a次方的问题,所以如法炮制。

还有,对于其它某些高阶问题需要用迭代法解决时,发现其导数不易求得或者牛顿法迭代式比原式更复杂,则可以考虑使用牛顿迭代法的变种,比如牛顿下山法、单点弦截法、双点弦截法等来解决,但通常它们具有更低的收敛速度,即需要更多次的迭代才能很好的逼近真实值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值