Nesting Block Diagonals in CVX

Hello! I was wondering if there is a way to construct a larger block diagonal matrix with other block diagonal matrices in CVX.
The current problem I have is:
\begin{bmatrix} C_{1} (k) & 0 \\ 0 & C_{2} (k) \end{bmatrix} \geq 0 where C_{1}(k) and C_{2}(k) are matrices computed at each time step.

The constraint in CVX I wish to implement is that the above matrix is semi-definite at every time step.

Given 100 time steps, I am trying to avoid to type:
blkdiag(C_{1}(0), C_{2}(0), C_{1}(1), C_{2}(1), ... ,C_{1}(100), C_{2}(100)) , where I would need to assign 200 separate variables for each C matrix after calculating them at each time step.

My original plan is to generate a large block diagonal matrix consisting of 100 x \begin{bmatrix} C_{1} (k) & 0 \\ 0 & C_{2} (k) \end{bmatrix} .

My current code is as follows, where I wish to build up the large block diagonal matrix.

for i=1:100
C1 =…;
C2 =…;
if i ==1
C3 = blkdiag(C1,C2)
else
C3=blkdiag(C3,blkdiag(C1,C2))
end

However, CVX does not allow repeated blkdiag(). I have also tried defining an expression that is the dimension of the large matrix and then assigning each small block of the large matrix with the individual 100 small block diagonals. However, I have gotten the following error msg:

Unable to perform assignment because the indices on the left side are not compatible with the size of the right side.
Error in cvx/subsasgn (line 79)
bx( :, ndx_x ) = by;

It would be great if anyone could kindly share if it is possible to somehow construct this large matrix of block diagonals in CVX, or if there are other methods to solve the original LMI problem. Cheers!

If you have a block diagonal matrix which you want to constrain to be psd, you are better off specifying a semidefinite (LMI) constraint for each block, which is mathematically equivalent to a single semidefinite constraint on the block diagonal matrix, but is generally easier for the solver to solve. I don’t know whether CVX would automatically undo your block diagonal matrix(ces) and spare the added difficulty for the solver, but you won’t be worse off by never forming block diagonal matrices, nested or otherwise, if all you want to do with them is specify a semdefinite constraint.

So specify the psd constraints inside the for loop(s) after you have constructed whatever block you want to constrain.

1 Like

Thanks Mark!

Following your advice, I simply did:

for i=1:length(Q)-1
C1 = …;
C2 =…;

C1 == semidefinite(n*2); 
C2 == semidefinite(L);

end

and have double-checked that C1 and C2 at each time step are psd. Initially I thought CVX would override the constraint and only keep the last time step as the constraint with each changing C1 and C2, but I’m glad it is working!

In CVX, an expression will be whatever it is at the time it is used in a constraint or objective; and the expression in that constraint or objective will not be overritten if the expression is subsequently overwritten.