-
Notifications
You must be signed in to change notification settings - Fork 13
/
PGM_opt.m
112 lines (90 loc) · 3.01 KB
/
PGM_opt.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
% Function that implements the PGM iterative optimization
function [Cout,iter_time] = PGM_opt(Pt,Hdir,H1,H2,maxIter,Qinit,myomegaunitball,c)
% Load the initial covariance matrix and RIS phase shifts
myomegaunitcirc = myomegaunitball.';
Q = Qinit;
% Line-search parameters
delta = 1e-5;
rho = 0.5;
iIter = 0;
stepsize = 10000; % Inital step size
Cout = [RIScap(Hdir,H2,H1,myomegaunitcirc,Q)]; % Initial achievable rate
Cprev = Cout;
iter_time = 0;
tic
while iIter<maxIter
iIter = iIter+1;
q_Q = gracov(Hdir,H2,H1,myomegaunitcirc,Q); % gradient w.r.t. Q
g_RIS = gradRIS(Hdir,H2,H1,myomegaunitcirc,Q); % gradient w.r.t. RIS
for iLineSearch = 0:30
% Updated covariance (Q) matrix, line 3 of Algorithm 1
Qnew = Q + stepsize*q_Q;
Qnew = cov_mat_proj_modified(Qnew,Pt*c^2);
% Updated RIS phase shifts, line 4 of Algorithm 1
yunitcirc = myomegaunitcirc + stepsize*g_RIS;
myomegaunitcircnext = projectontounitcircle(yunitcirc)/c;
% New achievable rate
Cnew = RIScap(Hdir,H2,H1,myomegaunitcircnext,Qnew);
% Line-search procedure
if (((Cnew-Cprev) >= delta*(norm(Qnew-Q)^2+ ...
norm(myomegaunitcircnext-myomegaunitcirc)^2)) ...
|| (stepsize<1e-4) )
% If the step size satisfies (35c) OR it is too small:
% Obtained Q matrix and RIS phase shifts
myomegaunitcirc = myomegaunitcircnext;
Q = Qnew;
Cprev = Cnew;
break
else
% Reduce the step size
stepsize=stepsize*rho;
end
end
% New achievable rate
Cout = [Cout Cnew];
% Exection time of an iteration
iter_time = [iter_time toc];
end
end
% Calculation of gradient w.r.t. Q
function y = gracov(Hdir,H2,H1,myomega,Q)
Z = Hdir+H2*diag(myomega)*H1;
Nr = size(H2,1);
y = Z'*inv(eye(Nr)+Z*Q*Z')*Z;
end
% Calculation of gradient w.r.t. RIS
function y = gradRIS(Hdir,H2,H1,myomega,Q)
Z = Hdir+H2*diag(myomega)*H1;
Nr = size(H2,1);
y = diag(H2'*inv(eye(Nr)+Z*Q*Z')*Z*Q*H1');
end
% Achievable rate calculation
function y = RIScap(Hdir,H2,H1,myomega,Q)
Z = Hdir+H2*diag(myomega)*H1;
Nr = size(H2,1);
y = real(log(det(eye(Nr)+Z*Q*Z')))/log(2);
end
% RIS projection
function y = projectontounitcircle(x)
y = x./abs(x);
end
% Covarinace matrix projection
function Qnew = cov_mat_proj_modified(Qold,Pt)
[U,D] = eig(Qold);
Dnew = water_fill(Pt,real(diag(D))).';
Qnew = U*diag(Dnew)*U';
end
% Water-filling algorithm
function vect_out = water_fill(Pt,vect_in)
vect_in = vect_in.';
[sort_val,sort_idx] = sort(vect_in,'descend');
for n = length(vect_in):-1:1
water_level = (sum(sort_val(1:n))-Pt)/n;
di = sort_val(1:n)-water_level;
if di(:)>=0
break
end
end
vect_out = zeros(1,length(vect_in));
vect_out(sort_idx(1:n)) = di;
end