根上已知边界的牛顿法

问题描述

我有一个方程 f(x)=y 具有以下属性

  • 我们有导数 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'的表达式是什么。 ff' 很长,所以我在这里做了要点: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)])