# Checking whether an algorithm is convergent

Hi there!

I am dealing with an optimization problem in which I intend to solve it using the alternating optimization (AO) method. Since I set the random initial value for variables when I run the code, I might face this error: “Disciplined convex programming error: Cannot perform the operation: {invalid} .* {real affine}”, which I think it might be due to infeasible initial values. But after running several times, it goes through its loop and starts to solve the problem. After some iterations, the value of the variable “We” becomes Invalid (-Inf), or the other variable, “V”, becomes a sparse matrix, and the program cannot do its computation. I am a neophyte in using CVX, do these errors indicate that this algorithm is not convergent? I appreciate any help. Thank you in advance. Here is my code:

clc
clear all
warning off
%% parameters setup %%
%% **************** %%

% DISTANCE SETUP %%
Xu2 = 200;
Xap = 50;
XI = 50;
YI = 8;
U1 = [0 0];
U2 = [Xu2 0];
AP = [Xap 0];
IRS = [XI YI];

d1 = sqrt((AP(1)-U1(1))^2+(AP(2)-U1(2))^2); %the distance between the AP and U1
d2 = sqrt((U2(1)-AP(1))^2+(U2(2)-AP(2))^2); % the distance between the AP and U2
dI1 = sqrt((U1(1)-IRS(1))^2+(U1(2)-IRS(2))^2); % the distance between the IRS and U1
dI2 = sqrt((U2(1)-IRS(1))^2+(U2(2)-IRS(2))^2); % the distance between the IRS and U2
dg = sqrt((AP(1)-IRS(1))^2+(AP(2)-IRS(2))^2); % the distance between the AP and IRS

k = -30;
K = 10^(k/10);
a = 3.5;

PL_1 = K*((d1)^(-a));
PL_2 = K*((d2)^(-a));
PL_I1 = K*((dI1)^(-a));
PL_I2 = K*((dI2)^(-a));
PL_G = K*((dg)^(-a));

N = 5;
M = 4 ;
eta = 0.5;
var = 1;
Q = (10^(-4));
Pt = 8;

a1 = 1/5;
a2 = 4/5;

epsilon = 10^(-3);% convergence threshold
sigma = 10^((-70-30)/10);

%% initial V & Wr & We%%

L = 2pirand(N,1);
u = zeros(1,N);
for k = 1:N
u(k) = exp(L(k)1i);
end
v = [u 1]’;
V = v
v’;

wr = sqrt(var/2) * ( randn(M,M) + sqrt(-1)*randn(M,M));
Wr = wr/norm(wr);
We = sqrt(var/2) * ( randn(M,M) + sqrt(-1)*randn(M,M));

itr_max =5000;
We_v = zeros(1,itr_max);
We_v(1)=trace(We);

%% optimization loop %%
%% ***************** %%

for j=1:itr_max

j

h1 = sqrt((var/2)*PL_1) * ( randn(M,1) + sqrt(-1)*randn(M,1)) ;
h2 = sqrt((var/2)*PL_2) * ( randn(M,1) + sqrt(-1)*randn(M,1)) ;
h1N = sqrt((var/2)PL_I1) ( randn(N,1) + sqrt(-1)*randn(N,1)) ;
h2N = sqrt((var/2)PL_I2) ( randn(N,1) + sqrt(-1)*randn(N,1)) ;
G = sqrt((var/2)*PL_G) * ( randn(N,M) + sqrt(-1)*randn(N,M)) ;

H1 = [diag(h1N’)*G; h1’ ];
H2 = [diag(h2N’)*G; h2’ ];

%% OPTIMIZATION OVER We %%
%% %%
cvx_begin sdp quiet
variable We(M, M) hermitian ;
We==hermitian_semidefinite(M);
minimize real(trace(We))
subject to
real(trace(H1’VH1We))+ real(trace(H2’VH2We))>= Pt ;
real(trace(H2’VH2We))real(trace(h2’Wrh2))>=(Qsigma/0.7);
real(trace(H1’VH1
We))real(trace(h1’Wrh1))>= real(trace(H2’VH2We))real(trace(h2’Wrh2))Q0.7+ Qsigma;
cvx_end

if length(cvx_status)==6 && sum(cvx_status == ‘Solved’)==6

``````s = rank(We);
if  s~=1
% Gaussian randomization %
[Ue, De]=eig(We);
re    = sqrt(var/2) * ( randn(M,1) + 1i*randn(M,1)) ;
we    = Ue*(De.^(0.5))*re;
we_bar = Ue*(De.^(0.5))*re;
We_bar = we_bar*we_bar';
We_hat = We_bar/trace(We_bar);

cvx_begin sdp quiet
variable  Pap ;
minimize Pap*real(trace(We_hat))
subject to
real(trace(Pap*H1'*V*H1*We_hat))+ real(trace(Pap*H2'*V*H2*We_hat))>= Pt ;
real(trace(Pap*H2'*V*H2*We_hat))*real(trace(h2'*Wr*h2))>=(Q*sigma/eta);
real(trace(Pap*H1'*V*H1*We_hat))*real(trace(h1'*Wr*h1))>=...
real(trace(Pap*H2'*V*H2*We_hat))*real(trace(h2'*Wr*h2))*Q*eta+ Q*sigma;
cvx_end

Pap = cvx_optval;
We  = Pap*We_hat;

We_v(j+1) = trace(We);
We_vv     = nonzeros(We_v);
end
``````

%% The constraint for stoping the loop %%

% because vector We_v might have so many zeroes due to
% continuing the loop to reach the CVX solved status,
% we should first take the nonzeros of We_v and then
% check the convergence criteria
if length(We_vv)~=1
for n=1:length(We_vv)-1
if ( abs(We_vv(n+1)-We_vv(n)) )/abs(We_vv(n+1)) <= epsilon
break;
end
end
end

elseif length(cvx_status)==10 && sum(cvx_status == ‘Infeasible’)==10
continue;
elseif length(cvx_status)==9 && sum(cvx_status == ‘Unbounded’)==9
continue;
elseif length(cvx_status)==10 && sum(cvx_status == ‘Inaccurate’)==10
continue;
elseif length(cvx_status)==6 && sum(cvx_status == ‘Failed’)==6
continue;
end

%% OPTIMIZATION OVER Wr %%
%% %%
cvx_begin SDP
variable Wr(M, M) hermitian ;
Wr==hermitian_semidefinite(M);
subject to
real(trace(H2’VH2We))real(trace(h2’Wrh2))>=(Qsigma/0.7);
real(trace(H1’VH1
We))real(trace(h1’Wrh1))>=…
real(trace(H2’VH2
We))real(trace(h2’Wrh2))Qeta+ Qsigma;
real(trace(Wr))==1;
cvx_end

if length(cvx_status)==6 && sum(cvx_status == ‘Solved’)==6
q = rank(Wr);
if q~=1
% Gaussian randomization %
[Ur, Dr]= eig(Wr);
rr = sqrt(var/2) * ( randn(M,1) + 1irandn(M,1)) ;
wr = Ur
(Dr.^(0.5))rr;
wr_bar = Ur
(Dr.^(0.5))rr;
Wr = wr_bar
wr_bar’;

`````` end
``````

end

%% OPTIMIZATION OVER V %%
%% %%

cvx_begin SDP
variable V(N+1, N+1) hermitian ;
V==hermitian_semidefinite(N+1);
subject to
real(trace(H2’VH2We))real(trace(h2’Wrh2))>=(Qsigma/0.7);
real(trace(H1’VH1
We))real(trace(h1’Wrh1))>=…
real(trace(H2’VH2
We))real(trace(h2’Wrh2))Qeta+ Qsigma;
for n=1:N+1
V(n,n)==1;
end
cvx_end

if length(cvx_status)==6 && sum(cvx_status == ‘Solved’)==6
d=rank(V);
if d~=1
% Gaussian randomization %
[Uv, Dv]= eig(V);
rv = sqrt(var/2) * ( randn(N+1,1) + 1irandn(N+1,1)) ;
v_bar = Uv
(Dv.^(0.5))*rv;
u_hat = v_bar(1:N)/v_bar(N+1);
u = exp(angle(u_hat)*1i);
v = [u’ 1];
V = v’*v;

``````end
``````

end

end

1 Like

Until everything is debgugged and working correctly, you should remove `quiet` so that you can see the solver and CVX output and figure out what’s going on. If a problem is infeasible, the CVX variable values will be populated with NaN. If you then use those values as input to a new problem, you may get `invalid`.

When using AO, there is generally no guarantee of convergence to anything, let alone a local optimum or global optimum of the original problem. Starting (initial) value can have a major impact on performance.

hello,did you solve it? Could I communicate with you?