# CVX doesn't maximize objective

I am trying to implement the following convex program (the simplest two variable instance of equation 34 from this paper):

\begin{array}{ll} \text{maximize}&\log|I+\text{diag}\{(h_1^HQ_1h_1, h_2^HQ_2h_2)\} |\\ \text{subject to} & h_1^HQ_2h_1 = 0\\ &h_2^HQ_1h_2 = 0 \\ &[Q_1]_{1,1} + [Q_2]_{1,1} \leq P \\ &[Q_1]_{2,2} + [Q_2]_{2,2} \leq P \\ & Q_1\succeq 0 \\ & Q_2\succeq 0 \end{array}

where h_k\in\mathbb{R}^{2\times 1} and Q_k\in\mathbb{R}^{2\times 2}. h_1 and h_2 are initialized to Gaussian random vectors, then the following code is called:

cvx_begin
variables Q1(2,2) Q2(2,2)
maximize sum_log([1+h1'*Q1*h1 1+h2'*Q2*h2])
h2'*Q1*h2 == 0;
h1'*Q2*h1 == 0;
Q1(1,1) + Q2(1,1) <= P;
Q1(2,2) + Q2(2,2) <= P;
Q1 == hermitian_semidefinite(n);
Q2 == hermitian_semidefinite(n);
cvx_end


However, when comparing the supposedly optimal result of Q_1 and Q_2 to a naive but computationally simpler method, I find that more often than not, the naive method produces a larger objective. The supposedly maximizing values of Q_1 and Q_2 do not achieve the global optimal.

Further, when I make all the variables complex (h_k\in\mathbb{C}^{2\times 1} and Q_k\in\mathbb{C}^{2\times 2}) then I get the error:

Disciplined convex programming error:
Invalid computation: geo_mean( {complex affine} )


Which is similar to this question), though in this instance there is no reason I can think of for the diagonal matrix to not be real. Just to be sure, I tried changing the objective to

maximize sum_log(real([1+h1'*Q1*h1 1+h2'*Q2*h2]))


which eliminated the error, but returned values of Q_1 and Q_2 with entries on the order of 10^{-10}. Is there something obvious that I’m missing here?

The one problem I definitely see with your code is that you have not declared Q1 and Q2 to be complex. Even though you set them to be equal to hermitian_semidefinite matrices later on, you declared them to be real at the beginning, so the result is that they’ll be constrained to be real positive semidefinite instead. So you’re very likely getting the wrong results because of this.

There are a couple of other things I would try.

First of all, instead of using sum_log, use geo_mean. It’s equivalent—in exact arithmetic, it is guaranteed to arrive at the same solution—and it avoids the use of the successive approximation heuristic (see the manual for information about that).

Secondly, go ahead and declare Q1 and Q2 to be hermitian:

variable Q1(2,2) hermitian
variable Q2(2,2) hermitian


This also causes them to be complex.

Finally, check the scaling of the values of h1 and h2.

Incidentally, the reason CVX doesn’t think that 1+h1'*Q1*h1 and 1+h2'*Q2*h2 are real is because for non-symmetric/Hermitian Q1 and Q2, they are not.

Setting the variables as hermitian solved the problem, thank you. As for the use of sum_log/geo_mean, I found that using log_det/det_rootn of the diag’d vector gave the correct answer… though these two things should be mathematically equivalent.

Hmm, you should submit a bug report to http://support.cvxr.com with data to reproduce the bug if det_rootn gives different (and more correct) results than geo_mean. That seems legitimately wrong. geo_mean should be the most accurate choice among sum_log/geo_mean/det_rootn/log_det.

Of course, the objective value for det_rootn/geo_mean should be different from sum_log/log_det.

I posted a new question) to address this issue between det_rootn, geo_mean, sum_log, and log_det, for those interested.