pythoncvxpycvx

How to populate a variable/expression in CVXPY


I am trying to translate cvx code to cvxpy. The major problem I am having is finding something similar to expressions. I used expressions to set values for an entire list of len(n). From my understanding the attributes in a variable in cvx cannot be modified while an expression can. In cvx I would do this by:

n = 100;
init = 10;
cvx begin 
   variables A(n), B(n), C(n)
   expression X(n)
   X(1) = init;
   for t=2:n
       X(t) = X(t - 1) + A(t - 1) + B(t - 1) + C(t - 1)
   end

   minimize(sum(A) + max(B))
   subject to 
     for t = 1:n
       A(t) >= 1;
       B(t) <= 1;
       C(t) >= 1;
     end
cvx end   

According to a previous post(How to set cvxpy n-dim variable first value?)there seems to be no equivalent to expressions in cvxpy afaik, so I would need to create that variable to a constraint like so.

   import cvxpy as cp
   n = 100
   init = 10
   A = cp.variable(n)
   B = cp.variable(n)
   C = cp.variable(n)
   X = cp.variable(n)
   
   obj = cp.Minimize(sum(A) + max(B))
   # TODO automate introduction of variables.
   cons = [
      X[0] == init,
      A[0] >= 1,
      B[0] <= 1,
      C[0] >= 1
   ]

   cons2 = [
      X[t] == X[t - 1] + A[t - 1] + B[t - 1] + C[t - 1],
      A[t] >= 1,
      B[t] <= 1,
      C[t] >= 1
      for t in range(1,n)
   ]
   cons.append(cons2)
   prob = cp.Problem(obj, cons)  

I get this error message: "NotImplementedError: Strict inequalities are not allowed." Apparently cvxpy does not like == in the constraints, but I am not sure how to populate X otherwise. Also, I think I might be off with my list creation for the constraints as well. Thank you for the help.

Alternate cvxpy code:

   import cvxpy as cp
   n = 100
   init = 10
   A = cp.variable(n)
   B = cp.variable(n)
   C = cp.variable(n)
   X = cp.variable(n)
   
   obj = cp.Minimize(sum(A) + max(B))
   # TODO automate introduction of variables.
   cons = [
      X[0] == init,
      A[0] >= 1,
      B[0] <= 1,
      C[0] >= 1
   ]

   for t in range(1,n)
      cons2 = [
          X[t] == X[t - 1] + A[t - 1] + B[t - 1] + C[t - 1],
          A[t] >= 1,
          B[t] <= 1,
          C[t] >= 1
      ]
      cons.append(cons2)
   prob = cp.Problem(obj, cons)  

Solution

  • I also don't know how to translate expression of cvx to cvxpy, nor do I know how to solve your optimization problem with cvxpy. However, I can provide fixes to your code sample so that no errors are raised.

    Fix 1:

    I get this error message: "NotImplementedError: Strict inequalities are not allowed." Apparently cvxpy does not like == in the constraints, but I am not sure how to populate X otherwise.

    This error is actually caused by calling the wrong sum and max function. You have to call the functions of cvxpy module, which can take the Variable Expression of cvxpy as input. So the proper way would be cp.sum(A) + cp.max(B).

    Fix 2:

    Also, I think I might be off with my list creation for the constraints as well. Thank you for the help.

    1. In your first cvxpy code sample: the list comprehension syntax provided to create list cons2 seems to be wrong and is not applicable like that. I don't know if there is an elegant way to use list comprehension for that specific creation.
    2. In your alternate cvxpy code sample: cons.append(cons2) would actually append the list cons2 into cons instead of the elements contained in the list cons2. What you want is to combine those 2 lists and this can be easily achieved with following syntax: cons += cons2.

    Fix 3:

    1. Wrong spelling: cp.variable(n) should be cp.Variable(n) instead.

    Fixed cvxpy code:

    import cvxpy as cp
    n = 100
    init = 10
    A = cp.Variable(n)
    B = cp.Variable(n)
    C = cp.Variable(n)
    X = cp.Variable(n)
    
    obj = cp.Minimize(cp.sum(A) + cp.max(B))
    # TODO automate introduction of variables.
    cons = [
       X[0] == init,
       A[0] >= 1,
       B[0] <= 1,
       C[0] >= 1
    ]
    
    for t in range(1,n):
        cons2 = [
            X[t] == X[t - 1] + A[t - 1] + B[t - 1] + C[t - 1],
            A[t] >= 1,
            B[t] <= 1,
            C[t] >= 1
        ]
        cons += cons2
    prob = cp.Problem(obj, cons)
    
    print(prob.solve(solver=cp.SCS))
    print(prob.status)