How to Correctly Retrieve Lagrange Dual Variables?

73 views
Skip to first unread message

Yuxuan Chen

unread,
Feb 26, 2025, 3:05:28 AMFeb 26
to YALMIP
 I am solving a complex optimization problem using YALMIP, where there is a semidefinite constraint , and is a complex block matrix. Each block contains different optimization variables, for example, . When I use dual(A >= 0), the Lagrange dual variables I obtain are NaN. I understand that the dual variables for semidefinite constraints are stored in sol.solveroutput.res.sol.itr.barx, but it clearly contains both the real and imaginary parts of the dual variables. The documentation also tells me that barx only stores the lower triangular part. I would like to know how the dual variables are arranged in barx, which block corresponds to the real part and which corresponds to the imaginary part, so that I can correctly recover them.  

Johan Löfberg

unread,
Feb 26, 2025, 3:47:40 AMFeb 26
to YALMIP

Johan Löfberg

unread,
Feb 26, 2025, 3:49:23 AMFeb 26
to YALMIP
But if you want to dig into absolutely low-level details on how duals are communicated from mosek to yalmip, undegoiung various maps due to complex reformulations, you will have to reverse engineer that via simple examples. It's horrible

On Wednesday, 26 February 2025 at 09:05:28 UTC+1 tianzhend...@gmail.com wrote:

Yuxuan Chen

unread,
Feb 26, 2025, 5:04:48 AMFeb 26
to YALMIP
Here are my codes. The reason I want to understand how barx is stored is that when I use dual, I always get NaN. I would like to know how to handle this situation. Thank you very much!
                R = 2;
M = 4;
N = M*R;
K = 2;
C_GBD_process = init_binary_matrix(R,M,L);
F_GBD_fea = sdpvar(N,R,'full','complex');
phi_GBD_fea = sdpvar(L,1,'full','complex');
A_GBD_fea = sdpvar(N,N,'hermitian','complex');
B_GBD_fea = sdpvar(R,R,'hermitian','complex');
gamma_GBD_fea = sdpvar(1);
constraints = [];
constraints = [constraints, gamma_GBD_fea >= 0];
  ……
some constraints are omitted
……
aux_matrix = [A_GBD_fea, F_GBD_fea, 1/sqrt(M)*C_GBD_process;
F_GBD_fea', B_GBD_fea, kron(eye(R),phi_GBD_fea)';
1/sqrt(M)*C_GBD_process.', kron(eye(R),phi_GBD_fea), eye(R*L)];
constraints = [constraints,(aux_matrix >= 0):'required'];
constraints = [constraints, trace(A_GBD_fea)-R <= 0];
constraints=[constraints, trace(B_GBD_fea)-R <= 0];
options = sdpsettings('solver','mosek','verbose',1,'savesolveroutput',1,'savesolverinput',1);
sol = optimize(constraints, -gamma_GBD_fea, options);
Requireddual=dual(constraints(' required  '));

Johan Löfberg

unread,
Feb 26, 2025, 5:33:15 AMFeb 26
to YALMIP
On closer inspection, YALMIP does not recover duals in complex-valued SDP, except when the solver is SeDuMi (which deals with complex models natively)

Hence, to get duals via YALMIP you would have to manually rewrite as a real problem first, solve and compute duals, and then map those real duals to the original complex space

If you want to manually inspect the mosek dual for the real version of the model YALMIP has sent to mosek, you will simply have to put a break in callmosek and then reverse engineer what has been sent, and how the computed dual corresponds to your model

Yuxuan Chen

unread,
Feb 26, 2025, 6:05:24 AMFeb 26
to YALMIP
Thank you. I will try other approaches.
Reply all
Reply to author
Forward
0 new messages