Python数值计算(7)

继续求根的数值算法。这次介绍牛顿法和割线法。

3. 牛顿迭代法

该算法是数值分析中最著名也是最强健的数值方法之一,其迭代公式为:

p_n=p_{n-1}-\frac{f(p_{n-1})}{f{}'(p_{n-1})}

例如,还是求方程:

f(x)=x^3-x-1=0

在[1,2]之间的根,其算法及测试代码为:

def f(x):
    return x**3-x-1

def df(x):
    return 3*x**2-1

def newton(f,df,p0,tol):
    cnt=0
    ret=0
    while True:
        p=p0-f(p0)/df(p0)
        if math.fabs(p-p0) < tol:
            ret=p
            break
        cnt+=1
        p0=p
    return ret,cnt
    
x,cnt=newton(f,df,1,1e-6)
print(cnt,x) # 4 1.3247179572447898

可以看到,只需要4次就可以计算出误差在1e-6的水平。

4. 割线法

牛顿法速度快效率高,但是有个很大的问题是必须要事先知道函数的导数,有时候计算导数是一件费时费力的事情,例如上例中是预选定义好了导函数。为了克服这个问题,可以逆向思维,导数的定义之一通过计算微商,然后取极限的方式,可以将f(p_{n-1})处的导数用微商代替,这就是割线法的原理,实现代码如下:

def secant(f,a,b,tol):
    ret=0
    cnt=0
    p0,p1=a,b
    q0,q1=f(p0),f(p1)
    while True:        
        p=p1-q1*(p1-p0)/(q1-q0)
        if math.fabs(p-p1)<tol:
            ret=p
            break
        p0=p1
        q0=q1
        p1=p
        q1=f(p)
        cnt+=1
    return ret,cnt

x,cnt=secant(f,1,2,1e-6)
print(cnt,x) # 6 1.3247179572446703

测试显示通过6次迭代也可以实现误差在1e-6的水平。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值