Error in matrix operations involving CVX variables

Hi, I’m trying to solve the following problem

KA=vector of dimensions (k,1);
KB=vector of dimensions (k,1);

cvx_begin
    variable alp(k,1) nonnegative;
    variable bet(k,1) nonnegative;
    expression x(k,1);
    minimize(sum(bet))
    subject to
        x=KA.*alp+(ones(k,1)-alp).*KB;
        diag(x*Stilde*x')<=ones(k,1)+bet;
        alp<=1;
cvx_end

but I get the following error

Error using .* (line 46)
Matrix dimensions must agree.

Error in Prog2CVX (line 17)
x=KA.*alp+(ones(k,1)-alp).*KB;

I believe that I’m not using the variable alp correctly because if I fix the values of alp then everything goes smoothly. I will really appreciate some help. Thanks in advance.

Try use Stilde*square(x) to replace diag(x*Stilde*x'). See if it works.

The code should execute without error as originally written, provided:

  1. KA and KB really have the stated dimensions
  2. Stilde is a nonnegative scalar

If either of these are not true, an error message will be produced

I ran it with k = 3, KA = KB =ones(k,1), Stilde = 3; The optimal objective value is 6, with alp = zeros(3,1), bet = 2*ones(3,1), x = ones(3,1).

Sorry I forgot a relevant information. Stilde is a semi definite positive symmetric matrix.

With your code as written, and per my previous post, that will only work ifStilde is a scalar (nonnegative). Otherwise, it is dimensionally incompatible.

if Stilde is not a scalar, but rather, k by k, then you need to fix your formulation to what you want. You could change x*Stilde*x' to x'*Stilde*x but that would produce a scalar, which wouldn’t make sense with the RHS being a vector. So you need to figure out what constraint you really want.

Sorry again, I think I figured out what I was missing before. Considering the following code

KA=ones(k,3);
KB=ones(k,3);
Stilde=eye(3);

cvx_begin
    variable alp(k,1) nonnegative;
    variable bet(k,1) nonnegative;
    expression x(k,3);
    minimize(sum(bet))
    subject to
        x=KA.*alp+(ones(k,1)-alp).*KB;
        diag(x*Stilde*x')<=ones(k,1)+bet;
        alp<=1;
cvx_end

At least theoretically this is dimensional coherent. if alp is a (k,1) vector and KA is a (k,3) matrix then KA.alp should return a (k,3) matrix where the first row of KA is multiplied by alp(1), the second row by alp(2) and the third row by alp(3). Analogously for (ones(k,1)-alp).KB . Therefore, x should be a matrix of dimensions (k,3) and then xStildex’ is a (k,k) matrix, so its diagonal is a (k,1) vector and I should be able to compare it to ones(k,1)+ bet which is a (k,1) vector.

But I think the problem is that CVX does not allow me to do the operation KA.*alp, correct me if I’m wrong.

KA.*alp relies on implicit expansion, which is not supported by CVX. Perhaps you can use repmat, which is supported by CVX, to do what you want.

Use diag(alp)*KA or a more universal way KA.*repmat(alp,1,3).

Thanks both for the help! Using repmat it works but then I get the error “Only scalar quadratic forms can be specified in CVX”.
I’m starting to think that I cannot do what I need with this formulation. I can solve the problem using for cycles, but I was trying to vectorize everything in order to make it faster.

Show your circles or mathematical formulas, I think perhaps it can be vectorized using the combinations of permute and repmat.

So this is the code with the for cycles

A=10+10*rand(10,2);
B=-10+10*rand(10,2);
[k,n]=size(A);
[l,n]=size(B);
Stilde=eye(n+1);
C1=1.0;
Atilde=[ones(k,1),A];
Btilde=[ones(l,1),B];
  
cvx_begin
    variable alp(k,l) nonnegative;
    variable bet(k,l) nonnegative;
    minimize(C1*sum(sum(bet)))
    subject to
        for i=1:k
            for j=1:l
                temp= Atilde(i,:)*alp(i,j) + (1-alp(i,j))*Btilde(j,:);
                temp*Stilde*temp'<= 1+bet(i,j);
                alp(i,j)<=1;
            end
        end
cvx_end
alphastar=alp;
betastar=bet;

and this for me it works, but when the dimensions of A and B increase it will take too much time to create the model.

The following might work (if Stilde is identity matrix):

Atilde2=permute(repmat(Atilde,1,1,l),[1 3 2]);
Btilde2=permute(repmat(Atilde,1,1,k),[3 1 2]);
alp2=repmat(alp,1,1,n+1);
temp=Atilde2.*alp2+(1-alp2).*Btilde2;
sum(square(temp),3) <= 1+bet;
alp <= 1;

Thank you, this works perfect. But do you think it is possible to generalize it when Stilde is not the identity matrix, or in this case it is much more complicated?

I don’t know. Since temp*Stilde*temp' is a function of temp, but it seems that this function can’t be applied to 3 or bigger than 3-dimensional arrays in CVX . So, to fullfill your purpose, you can try do a linear transform for temp, so that Stilde become identity matrix.