Search code examples
pythoncvxpy

Why am I getting a "disciplined convex programming" error when using cvxpy?


import cvxpy as cp
import numpy as np

n = 3
PP = cp.Variable((n,n),"PP")
KK = [[2,1,3],[1,2,1],[3,1,2]]
s = np.array([[.1, .4, .5]]).T
t = np.array([[.4, .2, .4]]).T
e = np.ones((n,1))
x = PP.T@e - s
y = PP@e - t
for b in range(1,21):
    obj = (1/4/b) * (cp.quad_form(x,KK) + cp.quad_form(y,KK)) - cp.trace(KK@PP) 
    prob = cp.Problem(cp.Minimize(obj),[PP>=0,cp.sum(PP)==1])
    obj=prob.solve()
    print("status:",prob.status)
    print("obj:",obj)
    print(PP.value)

When I run this, I get

cvxpy.error.DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:
QuadForm(PP.T * [[1.]
 [1.]
 [1.]] + -[[0.1]
 [0.4]
 [0.5]], [[2. 1. 3.]
 [1. 2. 1.]
 [3. 1. 2.]])

I don't see why I'm getting this error when my matrix KK is clearly PSD. Why is this happening?

Duplicate here at https://scicomp.stackexchange.com/q/34657/34383


Solution

  • EDIT: I spoke too soon. Your matrix KK is not PSD (it has an eigenvalue -1). For people who see this issue with a matrix that should mathematically be PSD, I've left my original answer below.

    Your matrix likely is likely, numerically, not quite PSD, even though mathematically it is. This is a limitation with CVXPY's quad form atom (that we may try to address later).

    For now, you can take a (matrix) square root sqrt_K of K (using, eg, scipy.linalg.sqrtm), and replace the quad_form atom with cp.sum_squares(sqrt_K @ y).