问题描述
- 我们有导数
f'
的显式表达式 - 已知根在 0 和 1 之间(实际上
f
仅在此区间内定义) -
f
正在(微弱)增加
我目前正在用 scipy.optimize.brentq
求解这个方程,效果很好。
optimize.brentq(f_to_zero,1)
brentq
使用割线法,这是牛顿法的有限差分等效法;它不使用任何明确的 f'
。
我希望通过使用这个导数可以更快地找到根。换句话说,我想使用带有边界增强的牛顿方法;这个 article 提出了以下想法:如果在任何时候牛顿猜测落在边界之外,则执行二等分(在当前猜测和边界之间)。是否有任何经过良好测试的软件包?我真的宁愿不编写自己的实现(为了提高性能可能不值得)。
另一点是函数甚至没有定义在边界之外,所以使用
optimize.newton(f_to_zero,fprime=f_prime,x0=0.5)
不仅效率低下,还会抛出错误
有人问f'
的表达式是什么。 f
和 f'
很长,所以我在这里做了要点:https://gist.github.com/d3c48dde09389e8c48da0e990b57bf99
解决方法
如果您限制自己使用 scipy 优化器,您可以将其转换为具有目标函数 f(x)2 的最小化问题,并使用 fmin_tnc 优化器,该优化器使用牛顿方法并增加了边界:
fsq = lambda x : f(x) ** 2
fsqprime = lambda x : 2 * f(x) * fprime(x)
optimize.fmin_tnc(fsq,x0 = [0.5],fprime = fsqprime,bounds = [(0,1)])