我有一个双曲线函数,我需要找到它的0。我尝试过各种经典方法(二分法、牛顿法等)。
二阶导数是连续的,但不能解析,所以我必须排除使用它们的方法。
对于我的应用来说,牛顿方法是唯一一种提供足够速度的方法,但如果我不够接近实际的零,它就会相对不稳定。下面是一个简单的屏幕截图:

零点在0.05左右。由于函数在0处发散,如果我取一个大于某一范围的最小位置的初始猜测值,那么我显然对渐近线有问题。
在这种情况下,有没有更稳定的方法,最终可以提供与牛顿相当的速度?
我也想过把函数变换成一个等价的更好的函数,用同样的零点,然后再应用牛顿,但我真的不知道我能做哪些变换。
任何帮助都将不胜感激。
发布于 2021-01-14 17:01:57
对于你的情况,@sams-studio的答案可能会起作用,我会先试一试。在类似的情况下-也是在多变量背景下-我使用了牛顿同伦方法。
基本上,您限制牛顿步长,直到y的绝对值下降。最便宜的实现方式是,如果y从上一步增加,则牛顿步长减半。几步之后,你又回到了牛顿,完全二阶收敛。
如果你可以绑定你的解决方案(你知道一个最大的x),@Lutz Lehmann的答案也将是我的第一选择。
发布于 2021-01-14 16:51:50
用log( x )代替x怎么样?
发布于 2021-01-14 17:00:07
德克或布伦特的方法应该几乎和牛顿一样快。如果您希望自己实现一些简单的东西,那么regula-falsi方法的Illinois变体也是相当快的。这些都是括号方法,因此如果初始间隔在域内,则不应离开域。
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,b,fb = b,fb,a,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, fbhttps://stackoverflow.com/questions/65715889
复制相似问题