假設我的約束是矩陣變量的第一列和第三列的乘積大於1。我如何在CVXPY中實現?例如:如何在CVXPY中的兩列的內積上創建不等式約束?
w = Variable(4,3)
在Matlab中,我的約束是:
w(:,1)'*w(:,3)>1
我怎麼能實現它在CVXPY?或者我們可以在CVXPY下執行點積? CVXPY不支持numpy.dot
。
假設我的約束是矩陣變量的第一列和第三列的乘積大於1。我如何在CVXPY中實現?例如:如何在CVXPY中的兩列的內積上創建不等式約束?
w = Variable(4,3)
在Matlab中,我的約束是:
w(:,1)'*w(:,3)>1
我怎麼能實現它在CVXPY?或者我們可以在CVXPY下執行點積? CVXPY不支持numpy.dot
。
將兩個變量相乘是不可能的,所有約束都必須是線性的(一般爲DCP)。
如果您嘗試執行禁止操作,CVXPY會引發DCPError。
import cvxpy
x = cvxpy.Variable()
y = cvxpy.Variable()
constraints = [x*y > 1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\cvxpy\expressions\expression.py", line 43, in cast_op
return binary_op(self, other)
File "C:\Python27\lib\site-packages\cvxpy\expressions\expression.py", line 226, in __mul__
raise DCPError("Cannot multiply two non-constants.")
cvxpy.error.DCPError: Cannot multiply two non-constants.
如果至少有一個變量是整數/布爾值,那麼可以使用鬆弛變量來避免這種情況。否則你可以使用任何非線性求解器,例如IPOPT。
回答同樣的問題here。
如果兩個變量都是正值,那麼{x * y > 1}
實際上是凸的,而函數x*y
既不是凸也不是凹的。這可以通過查看在第二衍生物
(x*y)'' =
[[0, 1],
[1, 0]]
其是{-1, 1}
的矩陣的特徵值來檢查。矩陣不是正定的,也不是負定的。
有時您可以轉換問題以使其變凸。在這種情況下,這可以通過對兩邊的對數:
log(x) + log(y) >= 0
這是一個有效的限制,因爲這兩個日誌(X)和log(y)是凹的功能和不等式是大於 - 或 - 等於。這個約束將通過「規則凸規劃」規則。祝你好運。
對於格雷姆矩陣Q := W.T * W
的東北入口,您有一個嚴格的不等式約束,它是對稱半正定的。因此,請使用格雷姆矩陣Q
代替,然後引入嚴格的不等式約束Q[0,2] > 1
。
例如,這裏有一個半定程序(SDP)與零目標:
>>> from cvxpy import *
>>> Q = Semidef(3)
>>> objective = Minimize(0)
>>> constraints = [ Q[0,2] > 1 ]
>>> prob = Problem(objective,constraints)
>>> prob.solve()
0.0
>>> Q.value
matrix([[ 2.33101529e+00, 2.57980002e-30, 1.76709537e+00],
[ 2.57980002e-30, 2.57740598e-15, -2.00304682e-30],
[ 1.76709537e+00, -2.00304682e-30, 2.33101529e+00]])
注意,東北條目1.76709537e+00 > 1
。從革蘭氏矩陣Q
恢復矩陣W
,使用Cholesky分解和追加零,以獲得4×3矩陣的行,如下所示:
>>> import numpy as np
>>> L = np.linalg.cholesky(Q.value)
>>> W = (np.insert(L, 3, np.array([0,0,0]), axis=1)).T
>>> W
matrix([[ 1.52676628e+00, 1.68971508e-30, 1.15741053e+00],
[ 0.00000000e+00, 5.07681591e-08, -7.79768444e-23],
[ 0.00000000e+00, 0.00000000e+00, 9.95698832e-01],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]])
讓我們驗證:
>>> W.T * W - Q.value
matrix([[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 7.00649232e-46],
[ 0.00000000e+00, 7.00649232e-46, 0.00000000e+00]])