用numpy autograd 实现牛顿迭代

Python数值计算 专栏收录该内容
4 篇文章 0 订阅


考虑非线性方程:

f ( x ) = sin ⁡ ( x ) − e − x = 0 f(x)= \sin(x) - \mathrm{e}^{-x}=0 f(x)=sin(x)ex=0

1、 导入包库

import autograd.numpy as np   
from autograd import grad
import matplotlib.pyplot as plt

2、定义函数

def sin_exp(x):
  return np.sin(x) - np.exp(-x)

查看一下函数的图象:

x_points = np.linspace(-3,3,1000)
y_points = sin_exp(x_points)

plt.plot(x_points,y_points)
plt.show()

可见该函数在附近没有重根。

3、使用autograd定义导数

grad_func = grad(sin_exp)

4、实现牛顿迭代

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)

x = -3.  # grad只支持float
fun_vals = [sin_exp(x)] # 该变量用于存储函数值
for i in range(50):  
  x -= sin_exp(x)/grad_func(x)
  fun_vals.append(sin_exp(x))

print('x=',x)
print('f(x)=',sin_exp(x))
x= 0.5885327439818611
f(x)= 0.0

画出收敛过程:

plt.plot(fun_vals)
plt.show()

在这里插入图片描述

# 前10个点
plt.plot(fun_vals[:10])
plt.show()

5、用scipy对应方法检验结果

from scipy.optimize import root

result = root(sin_exp,-3.)

print('x=',result.x)
print('f(x)=',result.fun)
x= [0.58853274]
f(x)= [0.]

对比一下差距:

print(x-result.x)
[0.]

6、小结

(1)用autograd实现简单非线性方程十分简单

(2)牛顿迭代收敛速度极快

另外:

(1)函数本身的性质仍然会影响算法的收敛性。本文选取的函数在给定区间内仅有一个根,更复杂的情况未讨论。

(2)初始值的选取仍然会影响算法收敛性,本文亦未讨论。

  • 3
    点赞
  • 10
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值