避免多次使用相同的输入评估函数

时间:2017-05-24 16:05:27

标签: python numpy scipy solver

我正在尝试利用scipy.optimise.fsolve来解决一个函数。我注意到在迭代步骤的开始和结束时多次使用相同的值计算函数。例如,在评估以下代码时:

{namespace s=HIT\huskytheme\ViewHelpers} 
...
Comments: ({s:news.countCommnets(news: newsItem.uid)})

获得以下输出:

from scipy.optimize import fsolve

def yy(x):
    print(x)
    return x**2+9*x+20

y = fsolve(yy,22.)

print(y)

因此,该功能用22.评估三次,这是不必要的。

当功能需要大量评估时间时,这尤其令人讨厌。有人可以解释一下并建议如何避免这个问题吗?

2 个答案:

答案 0 :(得分:1)

第一次评估仅用于检查函数输出的形状和数据类型。具体而言,fsolve调用_root_hybr,其中包含the line

shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))

当然,_check_func calls the function

res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))

由于此评估仅保留形状和数据类型,因此当实际的根查找过程开始时,解算器将再次使用值x0调用该函数。

上面说明了一个无关的电话(两个中有两个)。我没有追踪到另一个,但可以想象FORTRAN代码会对其进行某种初步检查。当很久以前编写的算法一遍又一遍地被包裹时,就会发生这种事情。

如果你真的想保存昂贵的函数yy的这两个评估,一种方法是分别计算值yy(x0)并存储它。例如:

def yy(x):
    if x == x0 and y0 is not None:
       return y0
    print(x)
    return x**2+9*x+20

x0 = 22.
y0 = None
y0 = yy(x0)
y = fsolve(yy, x0)

答案 1 :(得分:0)

我意识到这个问题的一个重要原因是fsolve不适用于这样的问题:应该明智地选择解算器:)

multivariate: fmin, fmin_powell, fmin_cg, fmin_bfgs, fmin_ncg
nonlinear: leastsq
constrained: fmin_l_bfgs_b, fmin_tnc, fmin_cobyla
global: basinhopping, brute, differential_evolution
local: fminbound, brent, golden, bracket
n-dimensional: fsolve
one-dimensional: brenth, ridder, bisect, newton
scalar: fixed_point