如何解决将le或ge与标量左手边一起使用可创建未调整大小的公式数组
在使用带有左侧标量的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,0]) # works
# constraint2 = prog.AddConstraint(le(z[1],0])) # fails
constraint2 = prog.AddConstraint(le([z[1]],0])) # works
formula = le(z[1],0])
print(formula.shape)
# > ()
解决方法
TL; DR
目前,您可以使用的解决方法:
- 重新构造为严格的矢量值(如您所做的那样)
- 传递直接对象值(使用
ndarray.item
) - 将标量数组整形/解压缩为一维数组
还将发布Drake问题。
Longform
Soonho的帖子通常是正确的,但有一些小的更正:
-
le(x,y)
是另一种编写np.asarray(x) <= np.asarray(y)
的方式。 (请参阅:drake#11171,numpy.vectorize
docs) - 虽然它确实是不可迭代的,但这并不是重要的部分。更重要的部分是
<Formula>
对象的输出被包装到一个“标量数组”array(<Formula>,dtype=object)
中。 - 如上所述,这是一个0维数组(空形状);但是,“空数组”可能有点用词不当,因为它有数据。您可以使用
np.item()
来检索内容
- 也正确。但是,这里的细微差别是
np.vectorize
将返回“标量数组”,而这些反过来又不能被我们使用pybind11
的Python绑定解释。
对于第(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,vars: numpy.ndarray[object[m,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,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)可能已捕获一维或二维数组,但都未设置为捕获array(<Formula>)
。
这或多或少是pydrake
和/或pybind11
的问题。我现在将提交Drake问题。
FWIW我已经发布了一个NumPy问题,询问0维数组的正确术语:
https://github.com/numpy/numpy/issues/17744
-
le(x,y)
是另一种编写np.array(x <= y)
的方式。 -
x <= y
形成了一个符号公式,该符号公式不能迭代。 - 结果,
np.array(x <= y)
创建一个空数组。您可以通过检查其形状(()
)或尝试使用np.array(x <= y)[0]
(这会给您带来错误)来说明这一点。 - 这不是Drake符号专用的。
np.array(42)
给您一个空数组。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。