Как добавить целочисленную переменную в драйвер openmdao?

Меня смущает эта ошибка openmdao. Почему это поднимается? Могу ли я как-то сказать openmdao, что у меня нет градиентов и использовать конечные различия? Почему это повышено для childWeight, но не для eta?

Я могу обойти эту проблему, инициализировав все мои переменные как числа с плавающей запятой (например, root.add('childWeight', IndepVarComp('x',100)) -> root.add('childWeight', IndepVarComp('x',100.0))), но я хотел бы понять, почему возникла эта ошибка.

from openmdao.api import Component, Group, Problem, ScipyOptimizer, IndepVarComp

class gym(Component):
    def __init__(self):
        super(gym, self).__init__()
        self.add_param('eta', 0.01)
        self.add_param('childWeight', 240)

        self.add_output('acc', 1)

    def solve_nonlinear(self, params, unknowns, resids):
        <...... parameters are used to produce objective "acc" ...>
        unknowns["acc"] = ....

top = Problem()
root = top.root = Group()
root.add('gym', gym())
top.driver = ScipyOptimizer()
top.driver.options['optimizer'] = 'BFGS'

root.add('eta',IndepVarComp('x', 0.01))
root.add('childWeight', IndepVarComp('x',100))

root.connect('eta.x', 'gym.eta')
root.connect('childWeight.x', 'gym.childWeight')

top.driver.add_desvar('eta.x', 0, 1.0)
top.driver.add_desvar('childWeight.x', 0, 1000)

top.driver.add_objective('gym.acc')
top.setup()
top.run()

вызывает ошибку

  File "script.py", line 98, in <module>
    top.setup()
  File "/usr/local/lib/python2.7/site-packages/openmdao/core/problem.py", line 694, in setup
    self.driver._setup()
  File "/usr/local/lib/python2.7/site-packages/openmdao/drivers/scipy_optimizer.py", line 91, in _setup
    super(ScipyOptimizer, self)._setup()
  File "/usr/local/lib/python2.7/site-packages/openmdao/core/driver.py", line 115, in _setup
    (item_name, name, oname))
RuntimeError: Parameter 'childWeight.x' is a 'pass_by_obj' variable and can't be used with a gradient based driver of type 'BFGS'.

person kilojoules    schedule 17.02.2016    source источник


Ответы (2)


Проблема в этой строке

root.add('childWeight', IndepVarComp('x',240))

Вы создали целочисленную переменную. Попробуйте это вместо этого:

root.add('childWeight', IndepVarComp('x',240.))

Если вы хотите использовать конечные разности, вам также понадобится:

top.root.fd_options['force_fd'] = True
person Justin Gray    schedule 17.02.2016
comment
Так нет ли способа добавить целочисленную переменную в драйвер на основе градиента? - person kilojoules; 18.02.2016
comment
По определению нет. Оптимизатору на основе градиента требуются градиенты (производные), которые не определены для целочисленных переменных. - person Justin Gray; 18.02.2016

Я считаю, что эта ошибка возникает, потому что значение по умолчанию для childWeight предоставляется как целое число 240 вместо числа с плавающей запятой 240,0. Если вы гарантируете, что ваши проектные переменные всегда имеют значения по умолчанию как числа с плавающей запятой, их не следует классифицировать как переменную pass_by_obj.

person thearn    schedule 17.02.2016