Crossposted on Stack Overflow
I have a convex objective function and a convex constraint of the form $$\frac{y^2}{x} + z \leq 1$$ on the domain $x \geq 0$. However, I'm not sure how to encode this constraint in a way that CVXPY will accept it. It seems to be rejecting it because it can't convince itself that the constraint is convex.
Here is a simple example code:
import numpy as np
import cvxpy as cp
n = 5
x = cp.Variable(n)
xtarget = np.random.normal(0, 1, n)
A = np.random.normal(0, 1, [n, n])
B = np.random.normal(0, 1, [n, n])
y = A @ x
z = B @ x
obj = cp.sum_squares(xtarget - x)
constraints = [x>= 0, y ** 2 / x + z <= 1]
prob = cp.Problem(cp.Minimize(obj), constraints)
prob.solve()
This gives the error:
DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP
I have tried to replace y ** 2 / x + z <= 1 with cp.multiply(y ** 2, cp.pos_inv(x)) + z <= 1 so that it know that $x$ variable is non-negative. It still gives me the DCP error.
Is there a way to reformulate the problem such that it satisfies the DCP rules?
Addendum
Thanks, Rodrigo de Azevedo, for suggesting positive semidefinite programming idea. Here is the code I ended with. I didn't know how to do this cleanly, so here is a hacky way of doing it.
import numpy as np
import cvxpy as cp
n = 5
x = cp.Variable(n, pos = True)
xtarget = np.random.normal(0, 1, n)
A = np.random.normal(0, 1, [n, n])
B = np.random.normal(0, 1, [n, n])
y = A @ x
z = B @ x
obj = cp.sum_squares(xtarget - x)
constraints = [x>= 0, y ** 2 <= 1, 1 - z >= 0]
Ms = [cp.Variable([2, 2], symmetric = True) for i in range(n)]
for i in range(n):
constraints.append(Ms[i] >> 0)
constraints.append(Ms[i][0,0] == x[i])
constraints.append(Ms[i][0,1] == y[i])
constraints.append(Ms[i][1,0] == y[i])
constraints.append(Ms[i][1,1] == 1 - z[i])
prob = cp.Problem(cp.Minimize(obj), constraints)
prob.solve()
yandzin terms ofx? – Rodrigo de Azevedo Mar 21 '23 at 13:12