【问题标题】:SciPy's Newton function does not find the intersection pointSciPy 的牛顿函数找不到交点
【发布时间】:2020-09-06 15:58:01
【问题描述】:

我试图理解为什么下面的代码不返回 -1.17 而是返回 -6.67e-09。这个数字实际上告诉我什么?

如果我将估计值从 0 更改为 -1,它确实正确计算 -1.17。但是,如果我必须为 100 多个不同的函数执行此操作,我将不得不为每个函数编写一个 while 循环,从而使计算过程变得异常缓慢。

这是简单的计算方式还是我错过了这种情况下的特定参数?

from scipy.optimize import newton


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


def g(x):
    return x**3

def insection():
    def difference(x):
        return g(x) - f(x)
    insection_point_value = newton(difference, 0)

    return insection_point_value 

print(insection())
Returns: -6.665555511432543e-09
Has to be: -1.1745594102929802

【问题讨论】:

    标签: python scipy newtons-method scipy-optimize


    【解决方案1】:

    Newton-Raphson 方法(NR) 对您提供的初始值高度敏感。

    查看差分函数的图形:
    x = 0 处的函数的导数是0NR 是一种迭代方法,不能使用零导数从初始点x0 = 0 前进。这就是为什么它继续停留在那里,而不是向预定点收敛。试试x0 = -0.1,它可以工作,或者其他任何东西。
    任何x > 0 都会继续失败,因为在x = 0.667 处还有另一个零导数,并且迭代方法将滑入山谷,使用外行语言。

    您得到的奇怪十进制值(而不是 0)是浮点数学、函数的离散值或两者的组合的产物。

    【讨论】:

      【解决方案2】:

      Newton-Raphson 方法是一种找到实值函数根的良好近似值的方法(在您的情况下:f(x) =x**3 - x**2 + 3)。这是一个严重依赖起点的迭代算法(x0 我的意思是)。

      所以,我建议使用多个起点,然后获取最常见的根。这段代码解释了我的意思:

      >>> from scipy.optimize import newton
      >>> from collections import Counter
      
      
      >>> # using [-10, -9, -8, ..., 8, 9, 10] as starting point(s)
      >>> roots = newton(lambda x: x**3 - x**2 +3, range(-11, 11))
      
      >>> # find the most common root
      >>> root, count = Counter(roots).most_common(1)[0]
      >>> root
      -1.17455941029298
      >>> count
      17
      

      这意味着在 22 个起点中,有 17 个收敛到 -1.17

      【讨论】:

        【解决方案3】:

        您可以提供函数导数:fprime - 请参阅docs。这应该会使搜索更加稳定。

        【讨论】:

        • 有趣,适用于大多数值,但如果将零微分点输入为x0,该方法仍然会失败并显示警告:RuntimeWarning: derivative was zero.
        • 可以先检查导数,如果为零,则添加一些随机值。
        猜你喜欢
        • 2017-05-05
        • 2020-09-17
        • 2018-02-26
        • 2018-01-03
        • 2017-06-11
        • 1970-01-01
        • 1970-01-01
        • 2015-04-17
        • 2021-12-20
        相关资源
        最近更新 更多