前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性化和牛顿法

线性化和牛顿法

作者头像
用户3577892
发布2021-03-13 22:44:05
8170
发布2021-03-13 22:44:05
举报
文章被收录于专栏:数据科学CLUB数据科学CLUB
  • 问题引入
  • 线性化问题的一般方法
  • 微分
  • 牛顿法
  • Python实现

问题引入

如何使用导数去估算特定的量. 例如, 假设想不借助计算器就得到 的一个较好估算. 我们知道 比 略大, 所以显然可以说 大约 比 3 多一点. 这没问题, 但其实可以不费太多劲就做出一个好得多的估算. 下面是具体做法.

先设 我们想要估算 的值, 因为不知道其确切 值.另一方面,我们知道 确切是多少 它就是 由于已知 当 时的值, 可以绘出 的函数图像, 并画出一条通过点 (9,3) 的切线,如下图所示

这条切线, 我标记为 在 附近非常接近于曲线 当 附近, 它就没有那么接近了. 但这无关紧要, 因为我们想要估算的是 而 11 是非常接近 9 的. 在上图中, 切线和曲线在 处非常接近. 这意味着 是对 的很好近似. 线性函数 通过点 并且由于它与曲线 在 相切, 所 以 的斜率为 由于 所以 因 此, 斜率为 并通过点 于是其方程为

化简可得 也就是说,

现在, 只需将 代人上式, 算得 的值 :

因此, 我们得到结论:

这可比之前的 3 多一点要好得多! 事实上, 可以使用计算器算得 约为 3.317 , 所以我们的近似值 还是相当不错的.

线性化问题的一般方法

如果你想要估算某个量, 首先试着把它 写成某个适当的函数 的值. 在上述例子中,我们想要估算 所以设函数 并意识到我们感兴趣的是 的值. 接下来,我们选某个与 很接近的数 并使得 容易计算. 在这个例子 中, 我们无法处理 但容易计算 因为 9 开根号很容易. 我们也可以选择 毕竟 25 开根号也很容易,但这就不如选 9 好, 因为 25 离 11 相当远了. 再次, 已知函数 和特殊值 , 我们找出通过曲线 上点 的 切线. 这条切线的斜率为 所以其方程为

如果设切线为 则在上述方程两边同时加上 得到

这个线性函数 被称为 在 处的线性化. 回想一下, 我们将把 作为 的近似. 所以有

并知道当 很接近于 时, 这个近似是非常好的! 事实上, 当 实际上等于 时, 这个近似是完美的! 此时上述方程的两边都为 不过, 这并没什么用, 毕竟对 我们已经知根知底了. 这样, 现在有了对 在 接近于 时的近似.

微分

再来看一下刚才的一般方法. 我们看到

不妨定义 这样 上述公式则变为

这时的情形可用下图表示.

图中显示了曲线 以及线性化 后者是前者在 处的切 线. 我们想要估算 的值, 也就是图中点 的高度. 但作为近似, 我们实 际上使用的是 也就是图中点 的高度. 这两个量之间的差:其中为在和之间的某个数

牛顿法

下面是线性化的另一个有用应用. 假设现在要解一个形为 的方程,但 你死活都解不出来. 所以你退而求其次, 试着猜测该方程有一个解, 并把它记为 这时的情形可能如下图所示.

从图中可以看出, 实际上并不等于零, 所以 其实并不是该方程的解, 它 仅仅是解的一个近似或估算. 可以把它视为近似的第一次尝试, 所以在上图中把它 标记为了“初始的近似"。牛顿法的基本思想是, 通过使用 在 处的线性化 来改善估算. (当然, 这意味着 需要在 处是可导的.)

这个线性化的 轴截距记为 并且显而易见, 相对于真正的零点, 它是个比 更好的近似. 这样从一个初始的猜测, 我们得到了一个更好的结果. 但 的值具体 是多少呢? 它就是线性化

的 轴截距. 为了求 轴截距, 设 则我们有 解 得 有

由于刚才把 轴截距记为 于是有如下公式::

❝牛顿法 假设 是对方程 的解的一个近似. 如果令则在很多情况下, 是个比 更好的近似. 但有时牛顿法也会不起作用. 下面是 失效的四种不同情况. ❞

(1) 的值接近于0. 显然, 如果

则 不能为 否则 是没有定义的. 在这种情况下, 在 处的切线不可能 与 轴相交, 因为它是水平的! 即使 很接近但不等于 牛顿法仍会给出一个 很糟糕的结果. 如下图所示的情形.

即便从一个相当好的近似 开始, 牛顿法给出的结果 还是远离真正的零点. 所以根本没有得到一个更好的近似. 为了避免出现这种情况, 要确保你的初始猜测不在函数 的临近点附近.

(2) 如果 有不止一个解,可能得到的不是你想要的那个解. 例如在下图中,如果你想估算左边的根 并且猜测从 开始,那么最终你估算的其实 是另一个根

所以你应该稍微花些工夫, 选取一个接近于你想要的那个零点的初始猜测 除 非你确定只有一个解.

(3) 近似可能变得越来越糟.

例如, 如果 方程 唯一的解 是 如果你尝试对此使用牛顿法, 那么怪 事就会出现. 你看, 除非从 开始, 否则会得到

所以下一个近似值总是你初始值的 -2 倍. 例如, 如果从 开始,那么下一个近似值将是 如果重复这个过程, 将得到 等等. 结果是离正确值 0 越 来越远. 如果遇到这类情况,牛顿法就无能为力了.

(4) 你可能陷入一个循环而无法自拔. 有可能出现,你通过估算 得到 估 算 却又得到 a. 重复这个过程是没有意义的, 这种情况可 能如下图所示

在 处的线性化有 轴截距 而在 处的线性化有 轴截距 所 以牛顿法在这里就不灵了. 一个具体的例子是

如果从 开始, 将算出 由于 为奇函数, 显然再从 -1 开始 的计算会再次得到

Python实现

代码语言:javascript
复制
from sympy import *
x = symbols('x')
#x0 = 0.5
x0 = float(input("输入初始值:"))
# 用来存储一步步的迭代过程
x_list = [x0]
i = 0

def f(x):
    f = x * exp(x) - 1
    return f

while True:   
#    如果x_0的导数为0即为极值点,牛顿法失效,退出循环
    if diff(f(x),x).subs(x,x0) == 0:
        print('极值点:',x0)
        break
    else:
#         diff()返回函数求导结果
        x0 = x0 - f(x0)/diff(f(x),x).subs(x,x0)
        x_list.append(x0)
        i += 1
        error = abs((x_list[-1] - x_list[-2]) / x_list[-1])
#        设置误差范围,小于则退出while循环
        if error < 10 ** (-6):
            print(f'迭代第{i}次后,误差小于10^(-6),误差为{error}')
            break

print(f'所求方程式的根为{x_list[-1]},\n迭代过程为{x_list}')
代码语言:javascript
复制
输入初始值:1.2
迭代第6次后,误差小于10^(-6),误差为9.90726474709430E-13
所求方程式的根为0.567143290409784,
迭代过程为[1.2, 0.791451914505546, 0.602629885740983, 0.568149269957630, 0.567144118692980, 0.567143290410346, 0.567143290409784]
可视化
代码语言:javascript
复制
import matplotlib.pyplot as plt

%matplotlib inline
#设置绘图风格
plt.style.use('ggplot')
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

x_values = list(range(1,i+2))
y_values = x_list
#横坐标是迭代次数
#纵坐标是误差值
plt.plot(x_values,
         y_values,
         color = 'r', # 折线颜色
         marker = '*', # 折线图中添加圆点
         markersize = 13, # 点的大小
         )
# 修改x轴和y轴标签
plt.xlabel('迭代次数')
plt.ylabel('误差值')
# 显示图形
plt.show()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据科学CLUB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题引入
  • 线性化问题的一般方法
  • 微分
  • 牛顿法
  • Python实现
    • 可视化
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档