Использование файла или ge со скалярной левой стороной создает массив формул без размера

#python-3.x #drake

#python-3.x #дрейк

Вопрос:

При создании формулы со le скалярной левой стороной или ge со скалярной левой стороной возвращаемая формула имеет .shape == () , т.Е. Является объектом без размера. Это вызывает проблемы при добавлении ограничения с формулой.

Я не уверен, что это ошибка.

 prog = MathematicalProgram()
q = prog.NewContinuousVariables(1, 'q')
z = prog.NewContinuousVariables(2, 'z')
r = prog.NewContinuousVariables(rows=2, cols=3, name='r')
constraint = prog.AddConstraint(le(q, r[0,2]   2*r[1,0])) # works
constraint2 = prog.AddConstraint(z[1] <= r[0,2]   2*r[1,0]) # works
# constraint2 = prog.AddConstraint(le(z[1], r[0,2]   2*r[1,0])) # fails
constraint2 = prog.AddConstraint(le([z[1]], r[0,2]   2*r[1,0])) # works

formula = le(z[1], r[0,2]   2*r[1,0])
print(formula.shape)
# > ()
  

Комментарии:

1. Привет, Руфус! Иногда (читай: почти всегда) мутит воду, когда вы публикуете сообщение об ошибке, но только указываете, что оно «сбой», не расширяя сообщение об ошибке. Можете ли вы опубликовать сообщение об ошибке здесь?

Ответ №1:

TL; DR

На данный момент ваши доступные обходные пути:

  • Переформулируйте, чтобы быть строго векторным (как вы это делали)
  • Передайте прямое значение объекта (используя ndarray.item )
  • Преобразование / отмена запроса скалярного массива в одномерный массив

Также будет опубликован выпуск Drake.

Длинная Форма

Сообщение Soonho в целом правильное, с некоторыми незначительными исправлениями:

  1. le(x, y) это другой способ записи np.asarray(x) <= np.asarray(y) . (См.: drake#11171, numpy.vectorize документы)
  2. Хотя это правда, что он не повторяется, это не важная часть. Более важной частью является то, что <Formula> вывод объекта оборачивается в «скалярный массив» array(<Formula>, dtype=object) .
  3. Как уже упоминалось, это 0-мерный массив (пустая форма); однако «пустой массив» может быть немного неправильным, поскольку в нем есть данные. Вы можете получить содержимое, используя np.item()
  4. Также правильно. Однако здесь есть нюанс, который np.vectorize вернет «скалярные массивы», а те, в свою очередь, не могут быть интерпретированы с помощью наших привязок Python pybind11 .

Для пункта (4) я повторно запустил ваш пример каждую ночь drake-20201104-bionic.tar.gz и получил это сообщение об ошибке:

 TypeError: AddConstraint(): incompatible function arguments. The following argument types are supported:
    1. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, func: function, lb: numpy.ndarray[numpy.float64[m, 1]], ub: numpy.ndarray[numpy.float64[m, 1]], vars: numpy.ndarray[object[m, 1]], description: str = '') -> drake::solvers::Binding<drake::solvers::Constraint>
    2. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, arg0: pydrake.symbolic.Expression, arg1: float, arg2: float) -> drake::solvers::Binding<drake::solvers::Constraint>
    3. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, arg0: pydrake.symbolic.Formula) -> drake::solvers::Binding<drake::solvers::Constraint>
    4. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, constraint: drake::solvers::Constraint, vars: numpy.ndarray[object[m, 1]]) -> drake::solvers::Binding<drake::solvers::Constraint>
    5. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, formulas: numpy.ndarray[object[m, n], flags.f_contiguous]) -> drake::solvers::Binding<drake::solvers::Constraint>
Invoked with: <pydrake.solvers.mathematicalprogram.MathematicalProgram object at 0x7f6eb081cdf0>, array(<Formula "(z(1) <= (2 * r(1,0)   r(0,2)))">, dtype=object)
  

Самое важное, что следует отметить, это то, что перегрузка (3) могла бы перехватить необработанный скаляр <Formula> , а (5) могла бы перехватить 1- или 2-мерный массив, но ни один из них не настроен на перехват array(<Formula>) .

Это более или менее pydrake проблема и / или pybind11 . На данный момент я подам вопрос о Дрейке.


FWIW Я опубликовал проблему NumPy, в которой спрашивается о правильной терминологии для массива 0-dim:
https://github.com/numpy/numpy/issues/17744

Комментарии:

1. Опубликованная проблема: github.com/RobotLocomotion/drake/issues/14305

Ответ №2:

  1. le(x,y) это другой способ записи np.array(x <= y) .
  2. x <= y формирует символьную формулу, которая не может быть повторена.
  3. В результате np.array(x <= y) создается пустой массив. Вы можете определить это, проверив его shape ( () ) или попробовав np.array(x <= y)[0] (что выдает ошибку).
  4. Это не зависит от символа Дрейка. np.array(42) выдает пустой массив.