Problem:Only scalar quadratic forms can be specified in CVX

Equation:
image

How to program this formula?

Error location: Sigma_i{i} = Sigma_i{i} + H_ij{i, j} * V_i{j} * V_i{j}’ * H_ij{i, j}';
Error message: Disciplined convex programming error:
Only scalar quadratic forms can be specified in CVX

Matlab code:

% -------- 基站 --------
M0 = 2 ; % 基站发射天线数量
N0 = 2 ; % 基站接收天线数量

% -------- 上行 UL --------
K = 2 ; % 上行UL用户数量
Mk = 2 ; %上行用户的天线数量
d_kUL = 2 ; % 上行数据流数量

% -------- 下行 DL --------
J = 2 ; % 下行DL用户数量
Nj = 2 ; % 下行用户的天线数量
d_jDL = 2 ; % 下行数据流数量

% 上行-下行用户 索引
S_UL = 1:K ; % 上行用户
S_DL = K+1:K+J ; % 下行用户

%% 上行信道+下行信道+自干扰信道+用户间信道CCI
H_kUL = cell(K,1) ; % 上行信道
for k_index = 1:K
h_UL = sqrt(1/2) * ( randn(N0, Mk) + 1i * randn(N0, Mk) ) ;
H_kUL{k_index,:} = h_UL ;
end

H_jDL = cell(J,1) ; % 下行信道
for j_index = 1:J
h_DL = sqrt(1/2) * ( randn(Nj, M0) + 1i * randn(Nj, M0) ) ;
H_jDL{j_index,:} = h_DL ;
end

% -------- 自干扰信道 --------
H0 = sqrt(1/2) * ( randn(N0, M0) + 1i * randn(N0, M0) ) ;

% -------- 上行用户-下行用户之间的干扰信道CCI --------
H_jkDU = cell(J,K) ;
for j_index = 1:J
for k_index = 1:K
h_DU = sqrt(1/2) * ( randn(Nj, Mk) + 1i * randn(Nj, Mk) ) ;
H_jkDU{j_index,k_index} = h_DU ;
end
end

% 公式(6)下面Denoting的H_ij
H_ij = cell(K+J,K+J) ;

for i = 1:(K+J)
for j = 1:(K+J)
if ismember(i, S_UL) && ismember(j, S_UL)
% i,j均为UL
H_ij{i, j} = H_kUL{j,:} ; % 上行信道
elseif ismember(i, S_UL) && ismember(j, S_DL)
% i为UL, j为DL
H_ij{i, j} = H0 ; % 基站自干扰信道
elseif ismember(i, S_DL) && ismember(j, S_UL)
% i为DL, j 为UL
H_ij{i, j} = H_jkDU{i-K, j} ; % 上下行用户干扰信道CCI
elseif ismember(i, S_DL) && ismember(j, S_DL)
% i,j均为DL
H_ij{i, j} = H_jDL{i-K,:} ;% 下行信道
end
end
end

%% CVX
cvx_begin
% 定义CVX变量
% 上行UL预编码
variable V_kUL(Mk, d_kUL, K) complex
% 下行DL预编码
variable V_jDL(M0, d_jDL, J) complex

% 初始化 V_i 矩阵
V_i = cell(K+J, 1);
for i = 1:(K+J) 
    if ismember(i,S_UL) % i是上行用户
        V_i{i,:} = V_kUL(:,:,i);
    elseif ismember(i,S_DL) % i是下行用户
        V_i{i,:} = V_jDL(:,:,i-numel(S_UL));
    else
        error('用户i不在定义的用户集合中')
    end
end

%% 计算 Sigma_i 公式(7)
Sigma_i = cell(K+J, 1);
for i = 1:(K+J)
if ismember(i, S_UL) % 上行用户
N = N0 ;
elseif ismember(i, S_DL) % 下行用户
N = Nj ;
end

Sigma_i{i} = zeros(N, N);
for j = 1:(K+J)
    if j ~= i
        Sigma_i{i} = Sigma_i{i} + H_ij{i, j} * V_i{j} * V_i{j}' * H_ij{i, j}';
    end
end
Sigma_i{i} = Sigma_i{i} + eye(N);

end

cvx_end

What do you plan to do with Sigma_i? In order fro CVX to be applicable, the problem needs to be a convex optimization problem.

If what you need is the trace, you can reformulate using
trace(H*V*V'*H') = square_pos(norm(H*V,'fro')), and make use of trace being linear to build up the trace of the overall thing.

Or if you only need to use this for a quadratic form, you can form each individual quadratic form, then take the sum of the quadratic forms.

Thank you for your suggestion!
I want to calculate the term ’ H * V * V’ * H’ ’ in CVX.
image

When I use ‘trace(H * V * V’ * H’)‘, the code still has errors here. According to the description in the paper, it seems that ‘trace(H * V * V’ * H’)’ cannot be used as a replacement here.

You can’t form that in CVX. You still haven’t told us what you want to do with that.

As for trace, that needs to be reformulated using square of Frobenius norm, as I showed. I didn’t tell you to jut take the trace; you should do so only if trace is what you want.

Please carefully re-read the link.

Sigma_i is used to solve the problem in the below picture.


Hence, I want to calculate the term ’ H * V * V’ * H’ ’ in CVX.

I don’t know whether constraint (11) is convex, but it’s not obvious to me that is.

Per the instructions in the link I provided above, please show us your proof that the constraint is convex.

I am sure that the original problem is transformed into a convex one.



Please re-read the link more carefully. Then show us your proof that the constraint is convex. The convexity claim, without proof being shown to us, is not adequate.

Maybe I don’t understand all the notation and assumptions. But you are trying to implement this, so you need to.

This is a published paper. So it can be believed that the problem is convex.

That is not accepted in this forum, per the rules in the link.

You can believe it, and maybe it’s true. But that doesn’t mean the readers of this forum will believe it, and they’re the people you’re counting on for help.

I have carefully read the content of your link many times. I will think about how to solve the problem again.
Thank you again for your guidance!

I looked at the original paper at https://www.pure.ed.ac.uk/ws/portalfiles/portal/24974444/07299645.pdf

(10)-(12) is easy to formulate in CVX. The key to my understanding was figuring out (even though it’s not explicitly stated) that l-1 subscripts apply to the previous SCA iteration. Therefore, everything with an l-1 subscript is input data to CVX, and that includes \Gamma_{i,j,l}, because everything on the RHS of (13) is input data. Therefore, the term inside tr in (11) is affine in the variable V_{i,l}, and can be entered essentially as is in CVX.

As shown earlier in this thread, the tr in the objective function can be reformulated as square_pos(norm(V,'fro')). I’ll let you deal with the indexing and summation.

You never should have been trying to calculate \Sigma_i with CVX variables. In the SCA problem (10-12), \Sigma_i is input data, which you calculate using standard double precision MATLAB calculation, not CVX.

As I wrote previously

Maybe I don’t understand all the notation and assumptions. But you are trying to implement this, so you need to.

Now that I have seen the paper, I figured out the notation and assumptions, and see that it is convex. You are not likely to have much success unless you invest the effort to thoroughly understand the problem you are trying to implement.

You need a starting value of V_{ii,l-1} , and need to calculate all the other starting l-1 values from that. Then you update after every CVX subproblem has been executed. It may not be easy to make the SCA work reliably, or at all; and the details of how to do so are out of scope of this forum. It will probably take you a lot of time and effort.

Thank you for your guidance! Your guidance has given me a lot of inspiration. I will write the Matlab code according to your guidance.

Dear Mr. Mark_L_Stone,

I sincerely want to ask you the following questions.
When I change the constraint Ri in equation (11), the value of ‘tr_VV_sum_save1’ do not change. Accoding to the Fig.1 in the paper, when Ri increases, the value of ‘tr_VV_sum_save1’ do so.
What’s wrong with my Matlab code?

Matlab code is as follows:
%% 参数设置
% -------- 基站 --------
M0 = 8 ; % 基站发射天线数量
N0 = 1 ; % 基站接收天线数量

% -------- 上行 UL --------
K = 1 ; % 上行UL用户数量
Mk = 1 ; %上行用户的天线数量
d_kUL = Mk ; % 上行数据流数量

% -------- 下行 DL --------
J = 2 ; % 下行DL用户数量
Nj = 1 ; % 下行用户的天线数量
d_jDL = Nj ; % 下行数据流数量

% -------- SCP相关参数 --------
Ri = 5000*ones(K+J,1) ; % 约束 公式(11) 不等号右边

% 上行-下行用户 索引
S_UL = 1:K ; % 上行用户
S_DL = K+1:K+J ; % 下行用户

delta = 1e-1 ; % 约束 公式(12)

%% 信道
[H_ij] = fun_QoS_FDMIMO1_Channel1(K, N0, Mk, J, Nj, M0, S_UL, S_DL, zhongzi) ;

%% 初始化
% ------ 预编码 ------
[V_init] = fun_QoS_FDMIMO1_Precode1(K, Mk, d_kUL, J, M0, d_jDL, S_UL, S_DL, zhongzi) ;
% 约束 公式(11) Γ_{i,j,l}计算需要先计算:公式(13)、公式(9)、公式(7)
% ------ 公式(7) ------
[Sigma_init] = fun_QoS_FDMIMO1_Sigma1(K, J, N0, Nj, H_ij, V_init, S_UL, S_DL) ;
% ------ 公式(9) ------
[I_iV_init] = fun_QoS_FDMIMO1_IiV1(K, J, H_ij, V_init, Sigma_init) ;
% ------ 公式(13) ------
[A_init] = fun_QoS_FDMIMO1_Ai1(K, J, H_ij, V_init, Sigma_init) ;
[Gamma_ij_init] = fun_QoS_FDMIMO1_Gamma1(K, J, H_ij, V_init, Sigma_init, A_init) ;

%% SCP

V_i = cell(K+J, 1) ; % 预编码 CVX变量
tr_VV = cell(K+J,1) ; % 目标函数

Rate_i = cell(K+J,1) ; % 约束 公式(11) 不等号左边

V_left = cell(K+J,1) ; % 约束 公式(12) 不等号左边
V_right = cell(K+J,1) ; % 约束 公式(12) 不等号右边

lmax = 21 ; % SCP最大迭代次数
tr_VV_sum_save1 = cell(lmax,1) ; % 保存 SCP迭代过程所得功率,即目标函数。 注意:CVX变量不能保存到zeros中
Rate_save1 = cell(lmax,1) ; % 保存 SCP迭代过程中每个下行用户的速率

l_index = 0 ;
while l_index < lmax
l_index = l_index +1

% -----  CVX  ------
cvx_begin quiet
    %% 定义CVX变量
    % 上行UL预编码
    variable V_kUL(Mk, d_kUL, K) complex
    % 下行DL预编码
    variable V_jDL(M0, d_jDL, J) complex

    % 初始化 V_i 矩阵
    for i = 1:(K+J) 
        if ismember(i,S_UL) % i是上行用户
            V_i{i,:} = V_kUL(:,:,i) ;
        elseif ismember(i,S_DL) % i是下行用户
            V_i{i,:} = V_jDL(:,:,i-numel(S_UL)) ;
        end
    end

    %% 目标函数
    tr_VV_sum = 0 ;
    for i = 1:(K+J)
        tr_VV{i} = square_pos(norm(V_i{i,:},'fro')) ;
        tr_VV_sum = tr_VV_sum + square_pos(norm(V_i{i,:},'fro')) ;
    end

% minimize(tr_VV_sum) % 目标函数
%
% % — 保存 —
% tr_VV_sum_save1{l_index,:} = tr_VV_sum ;

    %% 约束条件
    % ------ 约束 公式(11) ------
    for i = 1:(K + J)
        % 初始值 第l-1次迭代 I_i_l-1(V)
        I_iV = I_iV_init(i) ; 
        
        %  2Re{....}
        sum_term = 0 ;
        for j = 1:(K + J)
            if i ~= j
                % Gamma_ij, i ≠ j
                tr_Gamma = trace((V_i{j, :} - V_init{j, :})' * Gamma_ij_init{i, j}) ;
                sum_term = sum_term + tr_Gamma ;
            end
        end

        % 公式(11) 不等号左边
        Rate_i{i,:} = I_iV + 2 * real(sum_term);
    end
    % --- 保存 ---
    Rate_i_DL = Rate_i(K+1:K+J) ; % 只需要下行用户的速率
    Rate_save1{l_index,:} = Rate_i_DL ;

     % ------ 约束 公式(12) ------
    for j = 1:(K + J)
        % 不等号左边
        V_left{j,:} = norm(V_i{j, :} - V_init{j, :}, 'fro') ;
        % 不等号右边
        V_right{j,:} = norm(V_init{j, :}, 'fro') ;
    end

%% ------- 求解 -------------
minimize(tr_VV_sum) % 目标函数

    % --- 保存 ---
    tr_VV_sum_save1{l_index,:} = tr_VV_sum ;


    subject to
    % 约束 公式(11)(12)
    for ii = 1:(K+J) 
        Rate_i{ii,:} <= Ri(ii,:) ;
        V_left{ii,:} <= delta * V_right{ii,:} ;
    end

cvx_end

% 更新
V_init = V_i ; 
% ------ 公式(7) ------
[Sigma_init] = fun_QoS_FDMIMO1_Sigma1(K, J, N0, Nj, H_ij, V_init, S_UL, S_DL) ;
% ------ 公式(9) ------
[I_iV_init] = fun_QoS_FDMIMO1_IiV1(K, J, H_ij, V_init, Sigma_init) ;
% ------ 公式(13) ------
[A_init] = fun_QoS_FDMIMO1_Ai1(K, J, H_ij, V_init, Sigma_init)  ;
[Gamma_ij_init] = fun_QoS_FDMIMO1_Gamma1(K, J, H_ij, V_init, Sigma_init, A_init) ;

end

It looks like you never declare or set tr_VV_sum to anything. So I don’t know what you are doing.

tr_VV_sum is the objective function (see euqation (10)) in the paper at https://www.pure.ed.ac.uk/ws/portalfiles/portal/24974444/07299645.pdf.

The Matlab code is to solve the problem, i.e. equation (10), (11) and (12).

Is it set to anything in your code? I don’t see it.

‘tr_VV_sum’ is the objective function and is calculated by the following code
%% 目标函数
tr_VV_sum = 0 ;
for i = 1:(K+J)
tr_VV{i} = square_pos(norm(V_i{i,:},‘fro’)) ;
tr_VV_sum = tr_VV_sum + square_pos(norm(V_i{i,:},‘fro’)) ;
end

‘tr_VV_sum’ is minimized in the following code: minimize(tr_VV_sum) % 目标函数

The problem is that the value of objective function in the convergence process remain unchanged for different Ri in equation (11). However, according to Fig.1 in the paper, the the value of objective function increases with Ri increasing.
Fig1 is as follows.