问题描述
我有一个双曲线函数,我需要找到它的 0。我尝试过各种经典方法(二分法、牛顿法等)。
二阶导数是连续的,但无法解析,所以我必须排除使用它们的方法。
就我的应用而言,牛顿方法是唯一一种提供足够速度的方法,但如果我没有足够接近实际零,它会相对不稳定。这是一个简单的屏幕截图:
零在 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 的答案也将是我的首选。