python 5(暗淡 1)!= 1(暗淡 0)

python 5 (dim 1) != 1 (dim 0)

我正在尝试使用 scipy.optimize 求解二次规划。

def objFun(vector):
    "input value is a vector parameter"
    return ((vector.transpose()*Q*vector + b.transpose()*vector)[0] + c).item()

def scipy_result():
    init = np.matrix([[1] for i in range(5)])
    res = optimize.minimize(objFun, init, method="CG")
    print("value of x^* is", res.x, '\n')

if __name__ == "__main__":
    scipy_result()

乘法的维度什么的我没发现有什么错误。

但是

Traceback (most recent call last):

  File "C:\Users\Siyuan Xu\OneDrive - purdue.edu\Purdue Courses\CS 520\programming hw 1\homework 1.py", line 91, in <module>
    scipy_result()

  File "C:\Users\Siyuan Xu\OneDrive - purdue.edu\Purdue Courses\CS 520\programming hw 1\homework 1.py", line 63, in scipy_result
    res = optimize.minimize(objFun, init, method="CG")

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py", line 610, in minimize
    return _minimize_cg(fun, x0, args, jac, callback, **options)

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 1423, in _minimize_cg
    sf = _prepare_scalar_function(fun, x0, jac=jac, args=args, epsilon=eps,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 261, in _prepare_scalar_function
    sf = ScalarFunction(fun, x0, args, grad, hess,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 76, in __init__
    self._update_fun()

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 166, in _update_fun
    self._update_fun_impl()

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 73, in update_fun
    self.f = fun_wrapped(self.x)

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 70, in fun_wrapped
    return fun(x, *args)

  File "C:\Users\Siyuan Xu\OneDrive - purdue.edu\Purdue Courses\CS 520\programming hw 1\homework 1.py", line 30, in objFun
    return ((vector.transpose()*Q*vector + b.transpose()*vector)[0] + c).item()

  File "C:\ProgramData\Anaconda3\lib\site-packages\numpy\matrixlib\defmatrix.py", line 220, in __mul__
    return N.dot(self, asmatrix(other))

  File "<__array_function__ internals>", line 5, in dot

ValueError: shapes (1,5) and (1,5) not aligned: 5 (dim 1) != 1 (dim 0)

我很困惑。我试过了。使输入成为一个数组(也更改 obj 函数)并且它也不起作用。请帮我看看如何解决这个问题。非常感谢!

Quickfix:将您的 objFun(vector) 更改为:

def objFun(vector):
    "input value is a vector parameter"
    vector = np.reshape(vector, (-1, 1))
    return ((vector.transpose()*Q*vector + b.transpose()*vector)[0] + c).item()

在您的问题陈述中,Q,b,c 没有定义或描述。但是这个错误让我怀疑 Qnp.matrix.

让我们探索一个稍微简单的函数:

In [58]: from scipy import optimize
In [59]: def f(x):
    ...:     print(x, x.shape)
    ...:     Q = np.matrix([[1,2],[3,4]])
    ...:     res = x.T*Q*x
    ...:     print(res, res.shape)
    ...:     return res
    ...: 

单独测试 objective 函数通常是个好主意。 np.minimize 表示初始变量应为 1d,(n,) 形状,但让我们看看各种参数如何工作:

1d(2,) 形状:

In [60]: f(np.arange(2))
[0 1] (2,)
Traceback (most recent call last):
  File "<ipython-input-60-ef04d08d3a6e>", line 1, in <module>
    f(np.arange(2))
  File "<ipython-input-59-ef8f7ef56c80>", line 4, in f
    res = x.T*Q*x
  File "/usr/local/lib/python3.8/dist-packages/numpy/matrixlib/defmatrix.py", line 218, in __mul__
    return N.dot(self, asmatrix(other))
  File "<__array_function__ internals>", line 5, in dot
ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)

详细:

In [65]: Q=np.matrix([[1,2],[3,4]])
In [66]: x=np.arange(2)
In [67]: x*Q                    # first matrix product (because of Q)
Out[67]: matrix([[3, 4]])       # (1,2) shape
In [68]: (x*Q)*x                # second product
Traceback (most recent call last):
  File "<ipython-input-68-94f5369405fc>", line 1, in <module>
    (x*Q)*x
  File "/usr/local/lib/python3.8/dist-packages/numpy/matrixlib/defmatrix.py", line 218, in __mul__
    return N.dot(self, asmatrix(other))
  File "<__array_function__ internals>", line 5, in dot
ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)

Q 一起使用时,np.matrix(np.arange(2)) 生成 (1,2) matrix([[0, 1]]) 矩阵。

但是如果 x 以 (2,1) 形状开始,那么双乘积确实有效:

In [72]: x=np.arange(2)[:,None]
In [73]: (x.T*Q)*x
Out[73]: matrix([[4]])
In [74]: f(x)
[[0]
 [1]] (2, 1)
[[4]] (1, 1)
Out[74]: matrix([[4]])

但是如果我将 fx 加到 minimize 中,我会得到一个错误,因为 (2,1) 数组已经 'reduced' 到 (2 ,)

In [76]: optimize.minimize(f, x)
[0. 1.] (2,)
Traceback (most recent call last):
....
  File "<__array_function__ internals>", line 5, in dot
ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)

更改 f 以使用一维数组:

def f(x):
    print(x, x.shape)
    x = x[:,None]
    Q = np.array([[1,2],[3,4]])
    res = x.T@Q@x
    print(res, res.shape)
    return res.item()
In [86]: f(np.arange(2))
[0 1] (2,)
[[4]] (1, 1)
Out[86]: 4

现在 optimize.minimize(f, np.arange(2)) 运行(但不收敛)。

修复将使用 np.array

定义所有内容
def objFun(vector):
    "input value is a column vector parameter"

 
    return ((np.matmul(np.matmul(vector.transpose(),Q),vector) + \
            np.matmul(b.transpose(),vector))[0] + c).item()

def scipy_result():
    vector = np.ones((5,1),int)
    print("This is result of c part")
    res = optimize.minimize(objFun, vector, method="CG")
    print("value of x^* is", res.x.reshape(-1,))
    print("value of f(x^*)", objFun(res.x))