我正在尝试利用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.评估三次,这是不必要的。
当功能需要大量评估时间时,这尤其令人讨厌。有人可以解释一下并建议如何避免这个问题吗?
答案 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