How to create a couple of matrix variables with different dimension?


(Jianqiao Huang) #1

Hi,

I want to create a couple of square matrix variables in my model, for example 83 matrix variables. They have different dimension, for example X1 is a 5 by 5 matrix, X2 is a 8 by 8 matrix.

In cvx documentation, X(5,5,6) is like 6 matrices with the same dimension. It can’t satisfy my requirement. How can I create these matrix variables?


(Mark L. Stone) #2

What is wrong with just declaring separate matrix variables?
variable X1(5,5) X2(6,6)

If there are a large number of variables and you wish to do so in an automated way, use string concatenation to create “variable” variable names.

You can also create cell arrays of MATLAB variables. For instance,

variable X1(5,5) X2(6,6)
Fred = {X1,X2}

(Jianqiao Huang) #3

Hi Mark,

Thanks. I tried both strategies and have 2 questions below.

(1) I used string concatenation to create variable names, but I can’t get “variable” variable names. My code is below
.
s1 = ‘x’;
s2 = ‘1’;
s = strcat(s1,s2)
cvx_begin
variable s
cvx_end

The output is below:
s =
cvx real affine expression (5x5 matrix)

I want x1 to be the matrix variable name. But cvx can only recognize the character s instead of the content of s.

(2) I also tried cell arrays of variables. In this case, I still can’t create variable names automatically. At first, I tried the following code. But I get errors like “Duplicate variable name: x”. Did I misunderstand what you said?

cvx_begin
for i=1: 83
variable x(Num(i),Num(i))
F={F,x};
end
cvx_end

Thanks,
Jianqiao Huang


(Mark L. Stone) #4

I thought maybe you could use an approach similar to my post in Building Functions using CVX , but that doesn’t seem to work with variable declarations

I don’t know how “efficient” this is, but one possibility is to declare a single 3D array
variable giant_array(max_num_rows,max_num_columns,num_matrices)
in which the max_num_rows and max_num_cols are respectively the maximum of the number of rows and number of columns across all num_matrices matrices.

If matrix k is i by j, then just use giant_array(1:i,1:j,k) in the remainder of your CVX program. I think that the unused portions of giant_array never go to the solver, but I guess they do use up some memory in CVX processing.


(Jianqiao Huang) #5

HI Mark,

I refer your post. It works, and my code is following. Now I have another question. I need to use eval to express all the expressions containing x1 in the objective function and constraints. Is it correct?

It is slow to use function eval in cvx. It takes 0.0030 seconds to define x1(5,5) with “variable x1(5,5)”. However, using function eval takes 0.0047 seconds.

code: % define a 5 by 5 matrix variable x1
t=‘x1(’;
cvx_begin
eval(sprintf(’%s %s %d %s %d %s’,‘variable’,t,5,’,’,5,’)’))
cvx_end

When I type x1 before solver works, the output is the following:
x1 =
cvx real affine expression (5x5 matrix)


(Mark L. Stone) #6

Well, if that eval approach works, great. I think eval is slow - the Mathworks people seem to discourage such use.

I will let you determine empirically the speed of the various approaches. At this point, you know as much or more about this as I do.


(Jianqiao Huang) #7

Hi Mark,

Do you also think that I need to use function eval for all the expression in the objective function and constraints containing variable x1?

Thanks,
Jianqiao Huang


(Mark L. Stone) #8

I suggest you try the giant_array approach I mentioned in my previous post. That is very straightforward to implement, but it does waste some memory.