I want to convert the following SDP — which just verifies the feasibility of the constraints — from CVX (MATLAB) to CVXPY (Python):
Ah = [1.0058, -0.0058; 1, 0];
Bh = [-1; 0];
Ch = [1.0058, -0.0058; -0.9829, 0.0056];
Dh = [-1; 1];
M = [0, 1;1, 0];
ni = size(M,1)/2;
n = size(Ah,1);
rho = 0.5;
cvx_begin sdp quiet
variable P(n,n) semidefinite
variable lambda(ni) nonnegative
Mblk = M*kron(diag(lambda),eye(2));
lambda(ni) == 1 % break homogeneity (many ways to do this...)
[Ah Bh]'*P*[Ah Bh] - rho^2*blkdiag(P,0) + [Ch Dh]'*Mblk*[Ch Dh] <= 0
cvx_end
switch cvx_status
case 'Solved'
feas = 1;
otherwise
feas = 0;
end
Below is my Python code,
import cvxpy as cvx
import numpy as np
import scipy as sp
Ah = np.array([[1.0058, -0.0058], [1, 0]])
Bh = np.array([[-1], [0]])
Ch = np.array([[1.0058, -0.0058], [-0.9829, 0.0056]])
Dh = np.array([[-1], [1]])
M = np.array([[0, 1], [1, 0]])
ni, n = M.shape[0] / 2, Ah.shape[0]
rho = 0.5
P = cvx.Semidef(n)
lamda = cvx.Variable()
Mblk = np.dot(M, np.kron(cvx.diag(lamda), np.eye(2)))
ABh = np.concatenate((Ah, Bh), axis=1)
CDh = np.concatenate((Ch, Dh), axis=1)
constraints = [lamda[-1] == 1,
np.dot(ABh.T, np.dot(P, ABh)) - rho**2*np.linalg.block_diag(P, 0) +
np.dot(CDh.T, np.dot(Mblk, CDh)) << 0]
prob = cvx.Problem(cvx.Minimize(1), constraints)
feas = prob.status is cvx.OPTIMAL
There are several errors when I run the program. 1. When I print Mblk, it shows
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
Out[1]: exec code_obj in self.user_global_ns, self.user_ns
File "", line 1, in
Mblk
File "/usr/lib/python2.7/dist-packages/IPython/core/displayhook.py", line 247, in call
format_dict, md_dict = self.compute_format_data(result)
File "/usr/lib/python2.7/dist-packages/IPython/core/displayhook.py", line 157, in compute_format_data
return self.shell.display_formatter.format(result)
File "/usr/lib/python2.7/dist-packages/IPython/core/formatters.py", line 152, in format
data = formatter(obj)
File "/usr/lib/python2.7/dist-packages/IPython/core/formatters.py", line 481, in call
printer.pretty(obj)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 362, in pretty
return _default_pprint(obj, self, cycle)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 482, in _default_pprint
p.text(repr(obj))
File "/usr/lib/python2.7/dist-packages/numpy/core/numeric.py", line 1553, in array_repr
', ', "array(")
File "/usr/lib/python2.7/dist-packages/numpy/core/arrayprint.py", line 454, in array2string
separator, prefix, formatter=formatter)
File "/usr/lib/python2.7/dist-packages/numpy/core/arrayprint.py", line 256, in _array2string
'int' : IntegerFormat(data),
File "/usr/lib/python2.7/dist-packages/numpy/core/arrayprint.py", line 641, in init
max_str_len = max(len(str(maximum.reduce(data))),
File "/usr/local/lib/python2.7/dist-packages/cvxpy/constraints/leq_constraint.py", line 67, in nonzero
Raise Exception("Cannot evaluate the truth value of a constraint.")
Exception: Cannot evaluate the truth value of a constraint.
When I step to this line,
constraints = [lamda[-1] == 1,
np.dot(ABh.T, np.dot(P, ABh)) - rho**2*np.linalg.block_diag(P, 0) +
np.dot(CDh.T, np.dot(Mblk, CDh)) << 0]
it shows
Traceback (most recent call last): File
".../sdp.py", line 22, in
np.dot(ABh.T, np.dot(P, ABh)) - rho**2*np.linalg.block_diag(P, 0) +
ValueError: setting an array element with a sequence.
How to fix these problems?
The big issue with your code is that you can't use NumPy functions on CVXPY objects. You need to use the equivalent CVXPY functions. Here's a working version of your code:
import cvxpy as cvx
import numpy as np
import scipy as sp
Ah = np.array([[1.0058, -0.0058], [1, 0]])
Bh = np.array([[-1], [0]])
Ch = np.array([[1.0058, -0.0058], [-0.9829, 0.0056]])
Dh = np.array([[-1], [1]])
M = np.array([[0, 1], [1, 0]])
ni, n = M.shape[0] / 2, Ah.shape[0]
rho = 0.5
P = cvx.Semidef(n)
lamda = cvx.Variable()
Mblk = M*lamda*np.eye(2)
ABh = cvx.hstack(Ah, Bh)
CDh = cvx.hstack(Ch, Dh)
zeros = np.zeros((n,1))
constraints = [lamda[-1] == 1,
ABh.T*P*ABh - rho**2*cvx.bmat([[P,zeros],[zeros.T, 0]]) +
CDh.T*Mblk*CDh << 0]
prob = cvx.Problem(cvx.Minimize(1), constraints)
prob.solve()
feas = prob.status is cvx.OPTIMAL
I removed the kron function because it wasn't doing anything here and CVXPY doesn't currently support Kronecker products with a variable left-hand side. I can add it if you need it.