#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 в целом правильное, с некоторыми незначительными исправлениями:
le(x, y)
это другой способ записиnp.asarray(x) <= np.asarray(y)
. (См.: drake#11171,numpy.vectorize
документы)- Хотя это правда, что он не повторяется, это не важная часть. Более важной частью является то, что
<Formula>
вывод объекта оборачивается в «скалярный массив»array(<Formula>, dtype=object)
. - Как уже упоминалось, это 0-мерный массив (пустая форма); однако «пустой массив» может быть немного неправильным, поскольку в нем есть данные. Вы можете получить содержимое, используя
np.item()
- Также правильно. Однако здесь есть нюанс, который
np.vectorize
вернет «скалярные массивы», а те, в свою очередь, не могут быть интерпретированы с помощью наших привязок Pythonpybind11
.
Для пункта (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:
le(x,y)
это другой способ записиnp.array(x <= y)
.x <= y
формирует символьную формулу, которая не может быть повторена.- В результате
np.array(x <= y)
создается пустой массив. Вы можете определить это, проверив его shape (()
) или попробовавnp.array(x <= y)[0]
(что выдает ошибку). - Это не зависит от символа Дрейка.
np.array(42)
выдает пустой массив.