Search code examples
python-3.xcvxpy

Why is this CVXPY expression not DCP?


I have this short sample..

sysclk.value = 320e6

ddsdiv = cp.Variable(integer = True,                    # DDS divisor
         name = 'ddsdiv')
ddsdivpos = cp.Variable(pos = True)                     # Constrain to be positive

ddsclk = cp.Variable(pos = True, name = 'ddsclk')       # Resulting clock

constraints = [
        ddsdiv == ddsdivpos,                            # Constrain DDS divisor to be positive
        sysclk == ddsclk * ddsdiv,                      # Compute DDS clock
        ]
objective = cp.Minimize(cp.abs(ddsclk - 10e6))
prob = cp.Problem(objective, constraints);

prob.solve()
print(ddsclk.value)

However it says..

DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
sysclk == ddsclk * ddsdiv , because the following subexpressions are not:
|--  ddsclk * ddsdiv

Similarly it fails if I try (the more naive)..

        ddsclk == sysclk / ddsdiv,                      # Compute DDS clock

It also emits a DCPError.

I don't understand how a positive number divided by a positive integer could not my convex (but my math is not great :)

I'm using CVXPY 1.0.25, Python 3.7.5 on MacOSX 10.14.6.

Thanks.


Solution

  • Let's say your constraint is x * y == 9 where x and y are (continuous) variables. The set of solutions to this equation needs to be a convex set. We can test if this is convex by taking two solutions and checking if all points between those two solutions are also in the set.

    For example, (1,9) and (9,1) are both valid solutions. However the midpoint between these solutions (5,5) is not a solution. We found a counterexample, therefore this is not a convex set.

    Ultimately since this is not convex it's not possible to make this satisfy DCP. You'll need to reformulate your problem to make it convex or something else more amenable.