对于SciPy函数fmin_ncg,是否可以将粗麻布和渐变作为变量而不是函数提供?
我正在尝试用python重写一些Matlab代码.该代码涉及使用优化例程以使某些参数适合一组数据.为此,我提供了渐变和粗麻布.例如在Matlab中,我有这样的东西:
fmincon(@myFunc,x0,[],[],[],[],lb,ub,[],options);
其中myFunc返回3个值:函数求值,梯度和粗麻布.
但是对于Python中的fmin_ncg,似乎必须将gradiant和hessian作为单独的函数提供.
对我来说,这似乎效率很低,因为代码必须经过一个大型数据集,并且函数,渐变和粗麻布的计算是通用的.例如想象一个函数f(x)= a(x)* b(x),梯度为g(x)= a(x)* c(x),hessian h(x)= a(x)* d(x). ..在Matlab中,我只能计算一次(x),在这里看来我必须在python中计算三次.
我是否误解了fmin_ncg的工作方式,或者是否有解决方法?
解决方法:
您可以创建一个包含所有功能的类.每次迭代时,在第一个函数调用期间计算公共变量,然后将其重用于其他调用. fmin_ncg的回调功能可用于在每次迭代结束时重置公共变量.
class function(object):
def __init__(self):
self.commonVarsDirty = True
def calcFunction(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*b
def calcGradient(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*c
def calcHessian(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*d
def resetCommonVars(self,*args,**kwargs):
self.commonVarsDirty = True
def calcCommonVars(self):
self.commonVarsDirty = False
# calculate common variables and save them as class attributes
self.a = 1+1
您将像这样使用它.
f = function()
fmin_ncg(f.calcFunction,x0,f.calcGradient,fhess=f.calcHessian,callback=f.resetCommonVars)
这增加了一些开销,因此只有在计算公共变量的计算工作量很大的情况下才值得.