微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将le或ge与标量左手边一起使用可创建未调整大小的公式数组

如何解决将le或ge与标量左手边一起使用可创建未调整大小的公式数组

在使用带有左侧标量的lege创建公式时,返回的公式具有.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的帖子通常是正确的,但有一些小的更正:

  1. le(x,y)是另一种编写np.asarray(x) <= np.asarray(y)的方式。 (请参阅:drake#11171numpy.vectorize docs
  2. 虽然它确实是不可迭代的,但这并不是重要的部分。更重要的部分是<Formula>对象的输出被包装到一个“标量数组” array(<Formula>,dtype=object)中。
  3. 如上所述,这是一个0维数组(空形状);但是,“空数组”可能有点用词不当,因为它有数据。您可以使用np.item()
  4. 来检索内容
  5. 也正确。但是,这里的细微差别是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

,
  1. le(x,y)是另一种编写np.array(x <= y)的方式。
  2. x <= y形成了一个符号公式,该符号公式不能迭代
  3. 结果,np.array(x <= y)创建一个空数组。您可以通过检查其形状(())或尝试使用np.array(x <= y)[0](这会给您带来错误)来说明这一点。
  4. 这不是Drake符号专用的。 np.array(42)给您一个空数组。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。