2017-05-24 55 views
3

我试图利用scipy.optimise.fsolve来解决一个函数。我注意到函数在迭代步骤的开始和结束时多次使用相同的值进行评估。例如,当下面的代码进行评价:获得避免多次使用相同输入来评估函数

from scipy.optimize import fsolve 

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

y = fsolve(yy,22.) 

print(y) 

以下输出:

[ 22.] 
[ 22.] 
[ 22.] 
[ 22.00000033] 
[ 8.75471707] 
[ 4.34171812] 
[ 0.81508685] 
[-1.16277103] 
[-2.42105811] 
[-3.17288066] 
[-3.61657372] 
[-3.85653348] 
[-3.96397335] 
[-3.99561793] 
[-3.99984826] 
[-3.99999934] 
[-4.] 
[-4.] 
[-4.] 

因此,功能与22三次,这是不必要的评价。

当功能需要大量评估时间时,这特别烦人。任何人都可以请解释这一点,并建议如何避免这个问题?

+0

其中一个论据是['fprime '](https://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.optimize.fsolve.html),它被描述为*“用函数来计算函数的Jacobi函数行。默认情况下,雅可比将被估计。“*。我想知道最初的几个呼叫是否在第一对夫妇步骤的近似雅可比行列。 – CoryKramer

+0

但是,为什么它会使用相同的变量?它不应该改变评估雅可比算子的价值么? – tmt

+0

看起来像我的猜测是错误的,我写了一个雅可比你的函数'高清y_p(X):返回2 * X + 9'​​并通过了为'fprime = y_p',它仍然评估'22.'值数倍。奇怪的是,我没有猜测为什么这样做。 – CoryKramer

回答

1

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

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

自然地,_check_funccalls 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) 
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