Suppling гессиана в fmin_ncg в питоне - PullRequest
3 голосов
/ 04 июля 2011

Для функции SciPy fmin_ncg, есть ли способ заменить гессиан и градиент как переменную, а не функцию?

Я пытаюсь переписать некоторый код Matlab на python. В коде используется подпрограмма оптимизации для подгонки некоторых параметров к набору данных. Для этого я поставил градиент и гессиан. Например в Matlab у меня что-то вроде этого:

fmincon(@myFunc,x0,[],[],[],[],lb,ub,[],options);

где myFunc возвращает 3 значения: оценка функции, градиент и гессиан.

Однако для fmin_ncg в Python кажется, что градиент и гессиан должны быть предоставлены как отдельные функции.

Мне это кажется неэффективным, поскольку код должен пройти большой набор данных, и есть вычисления, которые являются общими для функции, градиента и гессиана. например Представьте себе функцию f(x) = a(x)*b(x) с градиентом g(x) = a(x)*c(x), гессиан h(x) = a(x)*d(x) ... в Matlab, я могу вычислить a(x) один раз, где, как мне кажется, мне нужно вычислить это три раза в python.

Я неправильно понял, как работает fmin_ncg или есть способ обойти это?

1 Ответ

4 голосов
/ 04 июля 2011

Вы можете создать класс, включающий все ваши функции. На каждой итерации общие переменные вычисляются во время первого вызова функции, а затем повторно используются для других вызовов. Функция обратного вызова 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)

Это добавляет некоторые накладные расходы, поэтому оно того стоит, только если усилия по вычислению для вычисления общих переменных значительны.

...