使用 np.array 对 cvxpy 仿射表达式求和时出现广播错误



在下面的代码片段中,我打算执行以下操作:

(1( 将恒等式的每个元素乘以d优化变量。
(2(将一个向量求和为CVXPY仿射表达式,这也是一个由24个元素组成的向量。
(3( 创建一个约束,逐个元素比较两个向量。

import numpy as np
import cvxpy as cp
weights = cp.Variable(5)
d = cp.Variable(1)
meas = np.random.rand(8, 3)
det = np.random.rand(24, 5)
dm = d * np.eye(3)   # (1)
beh = np.ones([24, 1]) + cp.reshape((dm @ meas.T).T, [24, 1])    # (2)
constrs = [beh == det @ weights]   #(3)

我的问题是:

Q1:我是否编写了我想要的代码?

Q2:在 (2( 处,我收到以下错误:

/usr/lib/python3.8/site-packages/cvxpy/utilities/shape.py in sum_shapes(shapes)
45         # Only allow broadcasting for 0D arrays or summation of scalars.
46         if shape != t and len(squeezed(shape)) != 0 and len(squeezed(t)) != 0:
---> 47             raise ValueError(
48                 "Cannot broadcast dimensions " +
49                 len(shapes)*" %s" % tuple(shapes))
ValueError: Cannot broadcast dimensions  (24, 1) [24, 1]

这到底是什么意思,我该如何解决?

Q3:当我做det @ weights时,在(3(时,我得到了一个Expression(AFFINE, UNKNOWN, (24,))。在约束中,我将它与beh进行比较,我猜这将是一个Expression(AFFINE, UNKNOWN, (24, 1))。这种比较也会带来问题吗?

当我开始使用 cvxpy 时,我在制作尺寸时也遇到了一些麻烦。根据我的经验,使用维度尽可能少的数组是个好主意。因此,如果您有一个二维数组,其中 1 个维度只有长度为 1,请查看是否可以减小维度。(见下文(

当您将 cvxpy 表达式整形时使用的括号更改为 (24,1( 时,(2( 中的问题得到解决,如下所示:

beh = np.ones([24, 1]) + cp.reshape((dm @ meas.T).T, (24, 1))    # (2)

您也可以通过简单地执行以下操作来避免您的问题:

beh = 1 + cp.reshape((dm @ meas.T).T, (24, 1))    # (2)

这将做同样的事情:在 CVXPY 数组的每个条目中添加 1。

完成此操作后,最后一行将出现问题:"值错误:无法广播维度 (24, 1( (24,(">

这也可以通过(24, )维度beh来补救(如前所述,减小维度将解决您的问题(。完整的工作代码将是:

import numpy as np
import cvxpy as cp
weights = cp.Variable(5)
d = cp.Variable(1)
meas = np.random.rand(8, 3)
det = np.random.rand(24, 5)
dm = d * np.eye(3)   # (1)
beh = 1 + cp.reshape((dm @ meas.T).T, (24, ))    # (2)
constrs = [beh == det @ weights]   #(3)

希望这有帮助!

最新更新