非线性方程的根问题

问题描述

我有一个双曲线函数,我需要找到它的 0。我尝试过各种经典方法(二分法、牛顿法等)。

二阶导数是连续的,但无法解析,所以我必须排除使用它们的方法

就我的应用而言,牛顿方法是唯一一种提供足够速度的方法,但如果我没有足够接近实际零,它会相对不稳定。这是一个简单的屏幕截图:

enter image description here

零在 0.05 左右。并且由于函数在 0 处发散,如果我取的初始猜测值大于一定程度的最小位置,那么我显然在渐近线方面有问题。

在这种情况下,是否有一种更稳定的方法最终可以提供与牛顿相当的速度?

我还想过将函数转换为具有相同零的等效更好函数,然后才应用牛顿,但我真的不知道我可以做哪些转换。

任何帮助将不胜感激。

解决方法

用 log(x) 代替 x 怎么样?

,

Dekker 或 Brent 的方法应该几乎和 Newton 一样快。如果你想自己实现一些简单的东西,regula-falsi 方法的伊利诺伊州变体也相当快。这些都是括号方法,所以如果初始区间在域内,就不要离开域。

def illinois(f,a,b,tol=1e-8):
    '''regula falsi resp. false postion method with
        the Illinois anti-stalling variation'''
    fa = f(a)
    fb = f(b)
    if abs(fa)<abs(fb): a,fa,fb = b,fb,fa
    while(np.abs(b-a)>tol):
        c = (a*fb-b*fa)/(fb-fa)
        fc = f(c)
        if fa*fc < 0:
            fa *= 0.5
        else:
            a,fa = b,fb
        b,fb = c,fc
    return b,fb
,

对于您的情况,@sams-studio 的答案可能有效,我会先尝试一下。在类似的情况下 - 也是在多变量上下文中 - 我使用了牛顿同伦方法。

基本上,您限制牛顿步长,直到 y 的绝对值下降。 最便宜的实现方法是,如果 y 比上一步增加,则牛顿步减半。几步之后,您就回到了牛顿的完全二阶收敛。

免责声明:如果您可以绑定您的解决方案(您知道最大 x),@Lutz Lehmann 的答案也将是我的首选。