Получите градиент и гессиан цели в Pyomo

У меня есть модель Pyomo, и я хотел бы получить градиент и гессиан цели. Связанный вопрос SO задает тот же вопрос. Когда я пробую предложенное там решение

from pyomo.core.base.symbolic import differentiate
from pyomo.core.base.expr import identify_variables

varList = list(identify_variables(zipfe.loglikelihood.expr))
firstDerivs = differentiate(zipfe.loglikelihood.expr, wrt_list=varList)

Я получаю следующую ошибку:

Traceback (most recent call last):
  File "/home/pauperei/.conda/envs/py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2862, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-9-6f2637b1fe13>", line 1, in <module>
    firstDerivs = differentiate(zipfe.loglikelihood.expr, wrt_list=varList)
  File "/home/pauperei/.conda/envs/py36/lib/python3.6/site-packages/pyomo/core/base/symbolic.py", line 122, in differentiate
    tmp_expr, locals=dict((str(x), x) for x in sympy_vars) )
  File "/home/pauperei/.conda/envs/py36/lib/python3.6/site-packages/sympy/core/sympify.py", line 354, in sympify
    expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
  File "/home/pauperei/.conda/envs/py36/lib/python3.6/site-packages/sympy/parsing/sympy_parser.py", line 894, in parse_expr
    return eval_expr(code, local_dict, global_dict)
  File "/home/pauperei/.conda/envs/py36/lib/python3.6/site-packages/sympy/parsing/sympy_parser.py", line 807, in eval_expr
    code, global_dict, local_dict)  # take local objects in preference
  File "<string>", line 1, in <module>
TypeError: 'Symbol' object does not support indexing

Вот как выглядит моя цель (первые несколько строк):

zipfe.loglikelihood.pprint()
loglikelihood : Size=1, Index=None, Active=True
Key  : Active : Sense    : Expression
None :   True : minimize : log( 1 + exp( alpha1[0] + 2.0*alpha1[1] + alpha1[4] + 2.8986705607108596*( delta[0] + 2.0*delta[1] ) ) ) - ( 2.0*beta1[0] + beta1[3] + 2.8986705607108596*( gamma[0] + 2.0*gamma[1] ) ) + log( exp(  - log( 1 + exp( alpha1[0] + 2.0*alpha1[1] + alpha1[4] + 2.8986705607108596*( delta[0] + 2.0*delta[1] ) ) ) + 2.0*beta1[0] + beta1[3] + 2.8986705607108596*( gamma[0] + 2.0*gamma[1] ) ) + exp(  - log( 1 + exp( alpha1[0] + 5.0*alpha1[1] + 2.8986705607108596*( delta[0] + 2.0*delta[1] ) ) ) + 5.0*beta1[0] + 2.8986705607108596*( gamma[0] + 2.0*gamma[1] ) ) + exp(  - log( 1 + exp( alpha1[0] + 2.0*alpha1[1] + alpha1[7] + 2.8986705607108596*( delta[0] + 2.0*delta[1] ) ) ) + 2.0*beta1[0] + beta1[6] + 2.8986705607108596*( gamma[0] + 2.0*gamma[1] ) ) + exp(  - log( 1 + exp( alpha1[0] + alpha1[1] + alpha1[6] 

Похоже, проблема в том, что Sympy не любит индексированные переменные, такие как alpha1[0]. Есть ли способ решения этой проблемы?

Редактировать:

Я использую Pyomo 5.2 и Python 3.6. Вскоре я постараюсь добавить минимальный рабочий пример.

За последние пару дней это было добавлено как To Do в репозиторий Pyomo GitHub, так что, надеюсь, скоро будет решение.


person Maturin    schedule 27.02.2018    source источник
comment
differentiate должен нормально работать с индексированными переменными. Не могли бы вы обновить свой вопрос, указав версию pyomo, версию python и минимальный пример, иллюстрирующий поведение?   -  person jsiirola    schedule 28.02.2018


Ответы (1)


Чтобы использовать индексированные переменные, используйте Indexed.

>>> alpha1 = IndexedBase('alpha1')
>>> alpha1[0]
alpha1[0]
person asmeurer    schedule 28.02.2018
comment
После определения всех моих переменных как IndexedBase у меня все еще есть та же проблема. Я думаю, что это правильное решение, но IndexBase следует вызывать в функции дифференцирования в Pyomo. Как я прокомментировал в редактировании моего вопроса, похоже, это указано в списке дел для будущей версии Pyomo. Спасибо! - person Maturin; 03.03.2018