1

假設我的約束是矩陣變量的第一列和第三列的乘積大於1。我如何在CVXPY中實現?例如:如何在CVXPY中的兩列的內積上創建不等式約束?

w = Variable(4,3) 

在Matlab中,我的約束是:

w(:,1)'*w(:,3)>1 

我怎麼能實現它在CVXPY?或者我們可以在CVXPY下執行點積? CVXPY不支持numpy.dot

回答

1

將兩個變量相乘是不可能的,所有約束都必須是線性的(一般爲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

0

如果兩個變量都是正值,那麼{x * y > 1}實際上是凸的,而函數x*y既不是凸也不是凹的。這可以通過查看在第二衍生物

(x*y)'' = 
[[0, 1], 
[1, 0]] 

其是{-1, 1}的矩陣的特徵值來檢查。矩陣不是正定的,也不是負定的。

有時您可以轉換問題以使其變凸。在這種情況下,這可以通過對兩邊的對數:

log(x) + log(y) >= 0 

這是一個有效的限制,因爲這兩個日誌(X)和log(y)是凹的功能和不等式是大於 - 或 - 等於。這個約束將通過「規則凸規劃」規則。祝你好運。

0

對於格雷姆矩陣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]])