CVX not recording values in other variables once finished

I’ve stumbled into quiet the odd bug in CVX. It is refusing to fill in the value for a parameter after the model finishes computing the answer. Here we have an example where the optimal solution is x=0 and y =1. CVX correctly solves the SDP, but it does not record the value for y afterwards. Instead it leaves it as y=0. This is all the more odd because trace(y) ==2 is an explicit constraint provided to the SDP. I’ve tried it with both SDPT3 and Mosek, but the result is the same.

cvx_begin sdp 

variable x(2,2) hermitian

expression y(2,2) %<-adding or removing this line makes no difference.

y = x+1;


minimize(trace(x))

trace(y) == 2;

cvx_end

trace(y) %outputs 0 !?

Any clue as to what is going on? How can I avoid this? Has anyone else found this problem before?

It’s not a bug, it’s a feature.

CVX variables are populated with their optimal values after cvx_end, but CVX expressions (whether declared as such or not) are not necessarily populated with their optimal values after cvx_end. So to get the optimal values of CVX expressions, you need to compute them after cvx_end, starting with the CVX optimal variable values.

The optimization is performed correctly even though the populated values for the expressions might not be correct. That reflects a CVX design decision. At the expense of some additional computation, CVX could have been written to automatically populate CVX expressions with their final optimal value, but was not designed that way. At minimum, the CVX Users’ Guide should have been clear and explicit about this (design decision), but is not.

Ah! that explains a lot! Thank you! I noticed that in many circumstances (as in I’ve used CVX for 5 years and this is the first time I’ve come across this) it does fill in the values. Is their any particular rime or reason for when this happens?

I don’t know the exact criteria for when expressions are populated with their optimal value. The safe thing to do is to not count on them being correctly populated, and to recompute them after cvx_end, starting from optimal variable values.

Oh no. I need to go update my code base now.