├── APK_K_Ary.m ├── Alternating_main.m ├── ComMethods_1Bit.m ├── DiscreteAndApk_Time_TraMode.m ├── Discretization2Bit.m ├── Exhaustive_Search_AND_DaS_1Bit.m ├── LICENSE ├── Main.m ├── Opt_absWZ.m ├── Opt_absWZ2.m ├── Opt_wHRw.m ├── README.md ├── TestingManopt1Norm.m ├── TestingManopt2Norm.m ├── discrete.m ├── discretization1Bit.m ├── esra.m ├── sdr.m ├── test_max_Ax_1.m └── test_max_Ax_2.m /APK_K_Ary.m: -------------------------------------------------------------------------------- 1 | function [w,optvalue]=APK_K_Ary(h,bit) 2 | % method from Yaowen Zhang in "Configuring intelligent reflecting surface with performance 3 | % guarantees: Optimal beamforming" 4 | % z is a complex column vector. The software is to solve max |W^T Z|, where W is 5 | % on unit circle uniformly. 6 | % 7 | 8 | % Author(s): Jialong Lu, Rujing Xiong 9 | % Date: 02-10-2022 10 | 11 | %% check input argument 12 | 13 | if ~iscolumn(h) 14 | error('H must be a column vector.') 15 | end 16 | % initialization data 17 | N=length(h); 18 | R=h*h'; 19 | h=conj(h); 20 | Phi=zeros(N,1); 21 | W=zeros(N-1,3); 22 | W_max=zeros(N-1,1); 23 | g=zeros(1,3); 24 | % record the phase 25 | for i=1:N 26 | Phi(i,1)=angle(h(i,1)); 27 | end 28 | %calculate w 29 | for j=1:3 30 | Phi_centre=angle(exp(1i*(Phi(N,1)+(j-2)*pi/(2^bit)))); 31 | for k=1:N-1 32 | for l=0:(2^bit)-1 33 | if Phi_centre-pi/(2^bit)<=angle(exp(1i*(Phi(k)+l*pi/(2^(bit-1)))))&&angle(exp(1i*(Phi(k)+l*pi/(2^(bit-1)))))<=Phi_centre+pi/(2^bit) 34 | W(k,j)=exp(1i*l*pi/(2^(bit-1))); 35 | end 36 | end 37 | end 38 | end 39 | % choose the optimal w 40 | for j=1:3 41 | d=h(N,1); 42 | for k=1:N-1 43 | d=d+h(k,1)*W(k,j); 44 | end 45 | g(j)=abs(d); 46 | end 47 | [~,p]=max(g); 48 | for j=1:N-1 49 | W_max(j,1)=W(j,p); 50 | end 51 | w=[W_max;1]; 52 | optvalue=abs(w'*h); 53 | 54 | -------------------------------------------------------------------------------- /Alternating_main.m: -------------------------------------------------------------------------------- 1 | %% Author: Rujing Xiong, Tiebin Mi 2 | % CreatTime: 2024.02.20 3 | % Complete: 4 | % Modified: 5 | % E-mail: Rujing@hust.edu.cn 6 | % Description: Alternating inner product maximization approach, mainly for 7 | % p-norm ||Aw||_p(p is 2 within this code), while A is a matrix with 8 | % rank-M, but not rank-1 9 | % 10 | % 11 | clear all 12 | clc 13 | tic 14 | 15 | N = 100; 16 | M = 16; 17 | numBits = 1; 18 | 19 | A = randn(M,N)+1i*randn(M,N); 20 | 21 | epli = 1; 22 | R = A'*A; 23 | 24 | %%%%%%%%%%%%%% Proposed Alternating Maximization %%%%%%%%%%%%%% 25 | W = exp(1i*randn(N,1)); % W can be selected randomly, also can be selected through some optimization methods, such as a quantized version from continuous solution. 26 | while epli>1e-10 27 | fval_1 = norm(A*W,2); 28 | Z = ((A*W)/norm(A*W,2)); % Z为M*1 29 | W = (A'*Z)/norm(A'*Z); 30 | fval_2 = norm (A*W,2); 31 | epli = abs(fval_2-fval_1); 32 | end 33 | disp(fval_2); 34 | epli = 1; % recover epli for the proceeding of next loop 35 | 36 | while epli>1e-10 37 | fval_1 = norm(A*W,2); 38 | Z = ((A*W)/norm(A*W,2)); % Z为M*1 39 | Temp = A'*Z; 40 | W = Opt_absWZ(Temp,numBits); 41 | fval_2 = norm (A*W,2); 42 | epli = abs(fval_2-fval_1); 43 | end 44 | disp(fval_2); 45 | y_my = fval_2; 46 | w_my = W; 47 | 48 | %%%%%%%%%%%%%%% Random %%%%%%%%%%%%%%%%%%%%%%%%%% 49 | rand = 100000; 50 | w_rand = exp(1i*randn(N,rand)); 51 | Y = A*w_rand; 52 | column_norms = vecnorm(Y); 53 | [y_rand,index] = max(column_norms); 54 | % ww = w_rand(:,index); 55 | % ww = Discretization2Bit(ww); 56 | % y_value2 = norm(A*ww); 57 | disp(y_rand); 58 | 59 | %%%%%%%%%%%%%%%% Manopt %%%%%%%%%%%%%%%%%%%%%%%%%% 60 | manifold = complexcirclefactory(N); 61 | problem.M = manifold; 62 | problem.cost = @(w) -w'*R*w; % 63 | problem.grad = @(w) manifold.egrad2rgrad(w,-2*R*w); 64 | [w_man,wcost,info,options] = steepestdescent(problem); 65 | %w_man = Discretization2Bit(w_man); 66 | w_man = discrete(w_man,numBits,N); 67 | y_man = norm(A*w_man); 68 | 69 | %%%%%%%%%%%%%%%% SDR %%%%%%%%%%%%%%%%%%%%%%%%%%% 70 | w_sdr = sdr(N-1,R,1); 71 | w_sdr = discrete(w_sdr,numBits,N); 72 | y_sdr = norm(A*w_sdr); 73 | 74 | %%%%%%%%%%%%%%%% Successive refinement %%%%%%%%% 75 | w_esra = esra(A,numBits); 76 | y_esra = norm(A*w_esra); 77 | %%%%%%%%%%%%%%%% Exhaustive search %%%%%%%%%%%%%%%%%%%% 78 | w_ex = 0:1:2^N-1; 79 | w_ex = dec2bin(w_ex,N); 80 | W_ex = (w_ex == '1'); 81 | W_ex = double(W_ex); 82 | W_ex(W_ex==0) = -1; 83 | Y_ex = A*(W_ex.'); 84 | norm_Y = vecnorm(Y_ex); %2-norm of each row in Y 85 | %norm_Y = diag(norm_Y);%取对角线上的每一个元素 86 | [y_ex,w_index] = max(norm_Y); 87 | w_ex = W_ex(w_index,:); 88 | toc 89 | -------------------------------------------------------------------------------- /ComMethods_1Bit.m: -------------------------------------------------------------------------------- 1 | %% author:Rujing Xiong 2 | % time: 2022.6.05 created 3 | % description :Comparison of SNR Performance among Different Methods, including APX, Man, SDR, DaS 4 | % with los 5 | %linear array 6 | 7 | clear all 8 | clc; tic 9 | 10 | sigma2 = 1; % noise。 11 | T = 1; % Transmitter antennas 12 | N = 10:5:50; 13 | y_square_APX = zeros(1,length(N)); 14 | y_square_Man = zeros(1,length(N)); 15 | y_square_SDR = zeros(1,length(N)); 16 | y_square_DaS = zeros(1,length(N)); 17 | 18 | 19 | loop = 1000; 20 | count = 1; 21 | y_APX = zeros(loop,length(N)); 22 | y_Man = zeros(loop,length(N)); 23 | y_SDR = zeros(loop,length(N)); 24 | y_DaS = zeros(loop,length(N)); 25 | 26 | for m = 1:loop 27 | for t = 1:length(N) 28 | H = (randn(N(t),T)+1i*randn(N(t),T)).*2; %AP-RIS 29 | Hr = (randn(N(t),1)+1i*randn(N(t),1));%RIS-USER 30 | G = (randn(1,T)+1i*randn(1,T)).*sqrt(1/2); %LOS 31 | % G = zeros(1,T); 32 | 33 | Phi = diag(Hr)*H; 34 | 35 | R = [Phi*Phi',Phi*G';G*Phi',G*G']; 36 | 37 | %%% APX 38 | w_m = zeros(2,2*N(t)+2); 39 | y_star= zeros(2,2*N(t)+2); 40 | x_star = zeros(1,N(t)); 41 | g_ystar = zeros(1,2*N(t)+2); 42 | V_V = zeros(1,N(t)+1); 43 | 44 | h_m = [diag(Hr)*H;G]'; 45 | Re_hm = real(h_m); 46 | Im_hm = imag(h_m); 47 | V = [Re_hm;Im_hm]; 48 | v_0 = V(:,1); 49 | 50 | R1 = h_m'*h_m; 51 | 52 | Phi_ = angle(h_m); 53 | y_minus = exp(1i*(Phi_-pi/2)); 54 | y_plus = exp(1i*(Phi_+pi/2)); 55 | 56 | angle_ym = angle(y_minus); 57 | angle_yp = angle(y_plus); 58 | angle_all = [angle_ym,angle_yp]; 59 | 60 | y_pie = exp(1i*angle_all+0.001); % all y' which will move in the interior 61 | re_ypie = real(y_pie); 62 | im_ypie = imag(y_pie); 63 | y_bold = [re_ypie;im_ypie]; 64 | 65 | y_endpoint = exp(1i*angle_all); % all y' which on the endpoint 66 | re_yendpoint = real(y_endpoint); 67 | im_yendpoint = imag(y_endpoint); 68 | y_end = [re_yendpoint;im_yendpoint]; 69 | 70 | V_V(1,:) = V.'*y_bold(:,1); 71 | index_plus = find(V_V(1,:)>0|V_V(1,:)==0); 72 | index_minus = find(V_V(1,:)<0); 73 | 74 | w_m(:,1) = sum(V(:,index_plus),2)-sum(V(:,index_minus),2); % sum by clown; 75 | 76 | for h = 2:(2*N(t)+2) 77 | V_V(h,:) = V.'*y_bold(:,h); 78 | index_n2p = find(sign(V_V(h,:))>0 & sign(V_V(h-1,:))<0); %negative to positive 79 | index_p2n = find(sign(V_V(h,:))<0 & sign(V_V(h-1,:))>0); %positive to negative 80 | 81 | w_m(:,h) = w_m(:,h-1)+ sum(V(:,index_n2p),2)-sum(V(:,index_p2n),2); 82 | end 83 | for h = 1:(2*N(t)+2) 84 | g_y1 = w_m(:,h).'*y_bold(:,h); 85 | g_y2 = w_m(:,h).'*y_end(:,h); 86 | if g_y1>=g_y2 87 | y_star(:,h) = y_bold(:,h); 88 | else 89 | y_star(:,h) = y_end(:,h); 90 | end 91 | g_ystar(h) = w_m(:,h).'*y_star(:,h); 92 | end 93 | index_y = find(max(g_ystar)); 94 | y_final = y_star(:,index_y); 95 | for n = 1:N(t) 96 | x_star(n) = sign(V(:,1).'*y_final*V(:,n+1).'*y_final); % V is a matrix with dimension:2 x (N+1) 97 | end 98 | theta = acos(x_star); 99 | w_APX = exp(1i*theta); 100 | w_APX = w_APX.'; 101 | y_square_APX(t) = [1;w_APX]'*R1*[1;w_APX]; 102 | 103 | 104 | 105 | %%%Manopt 106 | manifold = complexcirclefactory(N(t)+1); 107 | problem.M = manifold; 108 | problem.cost = @(w) -w'*R*w; % 109 | problem.grad = @(w) manifold.egrad2rgrad(w,-2*R*w); 110 | %problem.grad = @(w) manifold.egrad2rgrad(w,-R.'*conj(w));%The mapping used here is a first-order orthogonal projection. detailed in "https://www.manopt.org/tutorial.html" 111 | %[w,wcost,info,options] = steepestdescent(problem); % at a random point on the manifold 112 | %[w,wcost,info,options] = conjugategradient(problem); 113 | [w,wcost,info,options] = barzilaiborwein(problem); %Barzilai Borwein 114 | w = w./w(N(t)+1); 115 | w_2 = discretization1Bit(w); 116 | y_square_Man(t) = w_2'*R*w_2; 117 | w_Man = w_2(1:N(t)); 118 | 119 | 120 | 121 | %%%SDR 122 | f_tmp = 0; 123 | r_tmp = zeros(N(t),1); % r=[];The initialization of the three "tmp" variables cannot be placed outside the loop. They should be initialized whenever the value of "N" changes 124 | w_tmp = zeros(N(t),1); 125 | 126 | %CVX 127 | for k=1:count 128 | r = (randn(N(t)+1,1)+1i*randn(N(t)+1,1)).*sqrt(1/2); % (N,1) 129 | cvx_begin 130 | variable V(N(t)+1,N(t)+1) symmetric semidefinite % 131 | maximize( real(trace(R*V))) 132 | subject to 133 | diag(V) == 1; 134 | cvx_end 135 | 136 | [U,Sigma] = eig(V); 137 | w = U*Sigma^(1/2)*r; % (N*1) 138 | f = w'*R*w; %The number of random trials is given by 'count'. Obtain the beamforming vector w and Gaussian random vector r that correspond to the maximum value of f. 139 | if f>f_tmp 140 | f_tmp = max(f,f_tmp); 141 | r_tmp = r; 142 | w_tmp = w; 143 | end 144 | end 145 | w_tmp = w_tmp./w_tmp(N(t)+1); 146 | theta_opt = angle(w_tmp); 147 | w_sdr = exp(1i*theta_opt); 148 | w_SDR = discretization1Bit(w_sdr); 149 | % W = diag(w_SDR); 150 | y_square_SDR(t) = w_SDR'*R*w_SDR; 151 | 152 | %%%DaS 153 | [Z,eigs_R] = eig(R,'vector'); 154 | [eigs_R,index] = sort(eigs_R,'descend'); 155 | Z = Z(:,index); %Arrange the vectors in Z according to their corresponding eigenvalues. 156 | Z_S = Z(:,1); %The eigenvector corresponding to the maximum eigenvalue 157 | %% 158 | Phi_i = angle(Z_S); 159 | Phi_i(Phi_i>-pi & Phi_i<-pi/2) = Phi_i(Phi_i>-pi & Phi_i<-pi/2)+2*pi; 160 | I_1 = find(Phi_i>-pi/2 & Phi_ipi/2 & Phi_i<3*pi/2); 162 | Phi_i_hat = Phi_i; 163 | Phi_i_hat(I_2) = Phi_i_hat(I_2)-pi; 164 | [Phi_i_hat,i_index] = sort(Phi_i_hat); %In ascending order 165 | %% with Los 166 | W_hat = ones(N(t)+1,N(t)+1); 167 | for k = 1:N(t)+1 168 | W_hat(k,i_index(k+1:N(t)+1)) = -1; 169 | end 170 | for j = 1:N(t)+1 171 | W_hat(j,I_2) = -1*W_hat(j,I_2); 172 | end 173 | W = W_hat; 174 | W = W.';%Each w in W should be a column vector 175 | for e = 1:N(t)+1 176 | W(:,e) = W(:,e)./W(N(t)+1,e);%normalization 177 | end 178 | Y = W'*R*W; 179 | Y = diag(Y);%Take the elements on the diagonal 180 | [y_square_DaS(t),w_index] = max(Y); 181 | w_1 = W(:,w_index); 182 | w_DaS = w_1(1:N(t)); 183 | end 184 | y_APX(m,:) = sqrt(y_square_APX); 185 | y_Man(m,:) = sqrt(y_square_Man); 186 | y_SDR(m,:) = sqrt(y_square_SDR); 187 | y_DaS(m,:) = sqrt(y_square_DaS); 188 | X = sprintf('The loop have completed %d times.',m); 189 | disp(X); 190 | end 191 | yAPX = mean(y_APX,1); 192 | yMan = mean(y_Man,1); 193 | ySDR = mean(y_SDR,1); 194 | yDaS = mean(y_DaS,1); 195 | 196 | SNR_APX = 10*log10(1+yAPX.^2./sigma2); 197 | SNR_Man = 10*log10(1+yMan.^2./sigma2); 198 | SNR_SDR = 10*log10(1+ySDR.^2./sigma2); 199 | SNR_DaS = 10*log10(1+yDaS.^2./sigma2); 200 | 201 | figure 202 | hold on 203 | plot(N,SNR_APX,'-kd','LineWidth',2); 204 | hold on 205 | plot(N,SNR_Man,'-.bo','LineWidth',2); 206 | hold on 207 | plot(N,SNR_SDR,'--g*','LineWidth',2); 208 | hold on 209 | plot(N,SNR_DaS,'-rs','LineWidth',2); 210 | hold on 211 | xlabel('N','Interpreter','latex','Fontsize',16); 212 | ylabel('SNR(dB)','Interpreter','latex','Fontsize',16); 213 | legend('Solved by APX','Solved by Manopt','Solved by SDR','Solved by Proposed DaS','Interpreter','latex','Fontsize',12); 214 | hold on ; 215 | grid on; 216 | box on; 217 | -------------------------------------------------------------------------------- /DiscreteAndApk_Time_TraMode.m: -------------------------------------------------------------------------------- 1 | %% Author: Rujing Xiong 2 | % Time: 2022.07.16 3 | % Complete:2022.07.29 4 | % Modified:2022.07.30 5 | % E-mail: Rujing@hust.edu.cn 6 | % Description: Reappear the DiscreteOptimization in paper 'Configuring intelligent reflecting surface with performance guarantees: Optimal beamforming' 7 | % And execution-time Comparison 8 | %% SNR with N 9 | clc 10 | clear 11 | tic 12 | %sigma2 = 1; %noise 13 | T = 1; %number of Tx 14 | N = 100; 15 | loop = 100; 16 | for h = 1:loop 17 | for t = 1:length(N) 18 | w_m = zeros(2,2*N(t)+2); 19 | y_star= zeros(2,2*N(t)+2); 20 | x_star = zeros(1,N(t)); 21 | g_ystar = zeros(1,2*N(t)+2); 22 | V_V = zeros(1,N(t)+1); 23 | H = (randn(N(t),T)+1i*randn(N(t),1)).*2; %AP-RIS 24 | Hr = (randn(N(t),1)+1i*randn(N(t),1)).*1;%RIS-USER 25 | % Hr = [3*ones(N(t)/3,1); 1*ones(N(t)/3,1);5*ones(N(t)/3,1)];%RIS-USER 26 | 27 | G = (randn(1,T)+1i*randn(1,T)).*sqrt(1/2).*1; %LOS 28 | 29 | % Phi = diag(Hr)*H; 30 | h_m = [diag(Hr)*H;G]'; 31 | Re_hm = real(h_m); 32 | Im_hm = imag(h_m); 33 | V = [Re_hm;Im_hm]; 34 | v_0 = V(:,1); 35 | 36 | R = h_m'*h_m; 37 | 38 | Phi_ = angle(h_m); 39 | y_minus = exp(1i*(Phi_-pi/2)); 40 | y_plus = exp(1i*(Phi_+pi/2)); 41 | 42 | angle_ym = angle(y_minus); 43 | angle_yp = angle(y_plus); 44 | angle_all = [angle_ym,angle_yp]; 45 | 46 | y_pie = exp(1i*angle_all+0.001); % all y' which will move in the interior 47 | re_ypie = real(y_pie); 48 | im_ypie = imag(y_pie); 49 | y_bold = [re_ypie;im_ypie]; 50 | 51 | y_endpoint = exp(1i*angle_all); % all y' which on the endpoint 52 | re_yendpoint = real(y_endpoint); 53 | im_yendpoint = imag(y_endpoint); 54 | y_end = [re_yendpoint;im_yendpoint]; 55 | 56 | 57 | 58 | V_V(1,:) = V.'*y_bold(:,1); 59 | index_plus = find(V_V(1,:)>0|V_V(1,:)==0); 60 | index_minus = find(V_V(1,:)<0); 61 | 62 | 63 | w_m(:,1) = sum(V(:,index_plus),2)-sum(V(:,index_minus),2); % sum by clown; 64 | 65 | for m = 2:(2*N(t)+2) 66 | V_V(m,:) = V.'*y_bold(:,m); 67 | index_n2p = find(sign(V_V(m,:))>0 & sign(V_V(m-1,:))<0); %negative to positive 68 | index_p2n = find(sign(V_V(m,:))<0 & sign(V_V(m-1,:))>0); %positive to negative 69 | 70 | w_m(:,m) = w_m(:,m-1)+ sum(V(:,index_n2p),2)-sum(V(:,index_p2n),2); 71 | end 72 | for m = 1:(2*N(t)+2) 73 | g_y1 = w_m(:,m).'*y_bold(:,m); 74 | g_y2 = w_m(:,m).'*y_end(:,m); 75 | if g_y1>=g_y2 76 | y_star(:,m) = y_bold(:,m); 77 | else 78 | y_star(:,m) = y_end(:,m); 79 | end 80 | g_ystar(m) = w_m(:,m).'*y_star(:,m); 81 | end 82 | index_y = find(max(g_ystar)); 83 | y_final = y_star(:,index_y); 84 | 85 | for n = 1:N(t) 86 | x_star(n) = sign(V(:,1).'*y_final*V(:,n+1).'*y_final); % V is a matrix with dimension:2 x (N+1) 87 | end 88 | theta = acos(x_star); 89 | w = exp(1i*theta); 90 | w = w.'; 91 | end 92 | X = sprintf('The loop have completed %d times.',h); 93 | disp(X); 94 | end 95 | toc 96 | %% Author: Rujing Xiong 97 | % Time: 2022.07.16 98 | % Complete:2022.07.29 99 | % Modified:2022.07.30 100 | % E-mail: Rujing@hust.edu.cn 101 | % Description: Reappear the DiscreteOptimization in paper 'Configuring intelligent reflecting surface with performance guarantees: Optimal beamforming' 102 | % And execution-time Comparison 103 | %% SNR with N 104 | clc 105 | clear 106 | tic 107 | sigma2 = 1; %noise 108 | T = 1; %number of Tx 109 | N = 100; 110 | 111 | y_square = zeros(1,length(N)); 112 | 113 | loop = 100; 114 | y_luo = zeros(loop,length(N)); % luo's method 115 | y_my = zeros(loop,length(N)); % my method 116 | 117 | for h = 1:loop 118 | for t = 1:length(N) 119 | w_m = zeros(2,2*N(t)+2); 120 | y_star= zeros(2,2*N(t)+2); 121 | x_star = zeros(1,N(t)); 122 | g_ystar = zeros(1,2*N(t)+2); 123 | V_V = zeros(1,N(t)+1); 124 | H = (randn(N(t),T)+1i*randn(N(t),1)).*2; %AP-RIS 125 | Hr = (randn(N(t),1)+1i*randn(N(t),1)).*1;%RIS-USER 126 | % Hr = [3*ones(N(t)/3,1); 1*ones(N(t)/3,1);5*ones(N(t)/3,1)];%RIS-USER 127 | 128 | G = (randn(1,T)+1i*randn(1,T)).*sqrt(1/2).*1; %LOS 129 | 130 | % Phi = diag(Hr)*H; 131 | h_m = [diag(Hr)*H;G]'; 132 | Re_hm = real(h_m); 133 | Im_hm = imag(h_m); 134 | V = [Re_hm;Im_hm]; 135 | v_0 = V(:,1); 136 | 137 | R = h_m'*h_m; 138 | [Z,eigs_R] = eig(R,'vector'); 139 | [eigs_R,index_z] = sort(eigs_R,'descend'); 140 | Z = Z(:,index_z); %The corresponding eigenvectors are sorted in descending order too. 141 | Z_S = Z(:,1); %Taking the eigenvector corresponding to the largest eigenvalue 142 | % 143 | Phi_i = angle(Z_S); 144 | Phi_i(Phi_i>-pi & Phi_i<-pi/2) = Phi_i(Phi_i>-pi & Phi_i<-pi/2)+2*pi; 145 | I_1 = find(Phi_i>-pi/2 & Phi_ipi/2 & Phi_i<3*pi/2); 147 | Phi_i_hat = Phi_i; 148 | Phi_i_hat(I_2) = Phi_i_hat(I_2)-pi; 149 | [Phi_i_hat,i_index] = sort(Phi_i_hat); % sort by increasing order 150 | % 151 | % 152 | W_hat = ones(N(t)+1,N(t)+1); 153 | for k = 1:N(t)+1 154 | W_hat(k,i_index(k+1:N(t)+1)) = -1; 155 | end 156 | for j = 1:N(t)+1 157 | W_hat(j,I_2) = -1*W_hat(j,I_2); 158 | end 159 | W = W_hat; 160 | W = W.';% every w in W is a column vector 161 | for e = 1:N(t)+1 162 | W(:,e) = W(:,e)./W(N(t)+1,e);%each w keeps the last element 1 163 | end 164 | Y = W'*R*W; 165 | Y = diag(Y);% get the diagonal elements 166 | [y_square(t),w_index] = max(Y); 167 | w_opt = W(:,w_index); 168 | w_my = w_opt(1:N(t)); 169 | end 170 | X = sprintf('The loop have completed %d times.',h); 171 | disp(X); 172 | end 173 | toc -------------------------------------------------------------------------------- /Discretization2Bit.m: -------------------------------------------------------------------------------- 1 | %Function of 2-bits quantization for RIS 2 | function [Angle] = Discretization(w) 3 | Angle = angle(w); 4 | Angle = Angle.*180/pi; 5 | 6 | Angle(Angle>360) = Angle(Angle>360)-360; %predeal 7 | Angle(Angle<0) = Angle(Angle<0)+360; 8 | Angle(Angle>360) = Angle(Angle>360)-360; %predeal 9 | Angle(Angle<0) = Angle(Angle<0)+360; 10 | 11 | 12 | Angle(Angle>315 | Angle<=45) = 1;%0 13 | Angle(Angle>45 & Angle<=135) = 1i; 14 | Angle(Angle>135 & Angle<=225) = -1; 15 | Angle(Angle>225 & Angle<=315) = -1i; 16 | -------------------------------------------------------------------------------- /Exhaustive_Search_AND_DaS_1Bit.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RujingXiong/RIS_Optimization/81e2090e76f6538343d70121ad633dea2afc388f/Exhaustive_Search_AND_DaS_1Bit.m -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 RujingXiong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Main.m: -------------------------------------------------------------------------------- 1 | %% Author: Rujing Xiong, Tiebin Mi 2 | % CreatTime: 2022.10.07 3 | % Complete:2022.10.07 4 | % Modified: 5 | % Modified: 6 | % E-mail: Rujing@hust.edu.cn 7 | % Description: DiscreteOptimization for 2-bit RIS, compare with Manopt, for multi-bit 8 | % Based on traditional channel model, Mi's code 9 | % SNR with N(t) 2bit and multi bit 10 | clc 11 | clear 12 | tic 13 | sigma2 = 1; %noise 14 | T = 1; %number of Tx 15 | B = 2; % number of bits 16 | N = 100:100:1000; 17 | 18 | y_square = zeros(1,length(N)); 19 | 20 | loop = 1000; 21 | y_my = zeros(loop,length(N)); % my method (proposed DaS) 22 | y_man = zeros(loop,length(N)); % Manopt-discrete 23 | y_Man = zeros(loop,length(N)); % Manopt 24 | y_apk = zeros(loop,length(N)); % apk 25 | y_sdr = zeros(loop,length(N)); % SDR-SDP-discrete 26 | 27 | for h = 1:loop 28 | for t = 1:length(N) 29 | U = zeros(N(t),2^B*N(t)); 30 | H = (randn(N(t),T)+1i*randn(N(t),1)).*0.5; %AP-RIS 31 | Hr = (randn(N(t),1)+1i*randn(N(t),1));%RIS-USER 32 | Phi = diag(Hr)*H; 33 | R = Phi*Phi'; 34 | 35 | [Z,eigs_R] = eig(R,'vector'); 36 | [eigs_R,index_z] = sort(eigs_R,'descend'); 37 | Z = Z(:,index_z); %The corresponding eigenvectors are sorted in descending order too. 38 | Z_S = Z(:,1); %Taking the igenvector corresponding to the largest eigenvalue 39 | 40 | % proposed DaS 41 | [w_opt,opt_my] = Opt_absWZ(Z_S,B); 42 | y_my(h,t) = w_opt'*R*w_opt; 43 | 44 | % Manopt 45 | manifold = complexcirclefactory(N(t)); 46 | problem.M = manifold; 47 | problem.cost = @(w) -w'*R*w; % 48 | problem.grad = @(w) manifold.egrad2rgrad(w,-2*R*w); 49 | [w,wcost,info,options] = steepestdescent(problem); % at a random point on the manifold 50 | %[w,wcost,info,options] = conjugategradient(problem);% 51 | %[w,wcost,info,options] = barzilaiborwein(problem); %Barzilai Borwein 52 | %y_Man(h,t) = w'*R*w; % under continue phase shift 53 | %w = Discretization2Bit(w); 54 | w = discretization1Bit(w); 55 | y_man(h,t) =w'*R*w; % under discrete phase shift 56 | 57 | % APX 58 | [w_apk,opt_apk] = APK_K_Ary(Z_S,B); 59 | y_apk(h,t) = w_apk'*R*w_apk; 60 | 61 | % CVX 62 | f_tmp = 0; 63 | r_tmp = zeros(N,1); % 64 | w_tmp = zeros(N,1); 65 | count = 10; 66 | for k=1:count 67 | r = (randn(N,1)+1i*randn(N,1)).*sqrt(1/2); % (N,1) 68 | cvx_begin 69 | variable V(N,N) symmetric semidefinite % 70 | maximize( real(trace(R*V))) 71 | subject to 72 | diag(V) == 1; 73 | cvx_end 74 | 75 | [U,Sigma] = eig(V); 76 | w = U*Sigma^(1/2)*r; % (N*1) 77 | f = w'*R*w; % 78 | if f>f_tmp 79 | f_tmp = max(f,f_tmp); 80 | r_tmp = r; 81 | w_tmp = w; % 82 | end 83 | end 84 | % [m,index]=max(f); 85 | % r_opt = r(:,index); 86 | % w_opt = w(:,index); 87 | % theta_opt = angle(w_opt); 88 | % w_opt = exp(1i*theta_opt); % 89 | % W = diag(w_opt); 90 | theta_opt = angle(w_tmp); 91 | w_sdr = exp(1i*theta_opt); 92 | w_sdr = discretization1Bit(w_sdr); 93 | y_sdr(h,t) = w_sdr'*R*w_sdr; 94 | end 95 | X = sprintf('The loop have completed %d times.',h); 96 | disp(X); 97 | end % end loop 98 | 99 | y_meanMy = mean(y_my,1); 100 | SNR_my = 10*log10(1+y_meanMy./sigma2); 101 | 102 | y_meanMan = mean(y_Man,1); 103 | SNR_Man = 10*log10(1+y_meanMan./sigma2); 104 | 105 | y_meanman = mean(y_man,1); 106 | SNR_man = 10*log10(1+y_meanman./sigma2); 107 | 108 | y_meanapk = mean(y_apk,1); 109 | SNR_apk = 10*log10(1+y_meanapk./sigma2); 110 | 111 | y_meansdr = mean(y_sdr,1); 112 | SNR_sdr = 10*log10(1+y_meansdr./sigma2); 113 | 114 | figure 115 | hold on 116 | plot(N,SNR_Man,'-rs','LineWidth',1); 117 | hold on 118 | plot(N,SNR_man,'-gs','LineWidth',1); 119 | hold on 120 | plot(N,SNR_my,'--cd','LineWidth',1); 121 | hold on 122 | plot(N,SNR_apk,'--bx','LineWidth',1); 123 | hold on 124 | plot(N,SNR_sdr,'--gd','LineWidth',1); 125 | xlabel('N','Interpreter','latex','Fontsize',15); 126 | ylabel('SNR(dB)','Interpreter','latex','Fontsize',15); 127 | legend('Manopt','Discrete Manopt','Proposed method','APK','SDR-SDP','Interpreter','latex','Fontsize',15); 128 | hold on ; 129 | grid on; 130 | hold on; 131 | box on; 132 | % title('Gains on Signal power'); 133 | toc 134 | 135 | % figure 136 | % hold on 137 | % plot(N,SNR1,'-gs','LineWidth',1); 138 | % hold on 139 | % plot(N,SNR2,'--cd','LineWidth',1); 140 | % hold on 141 | % plot(N,SNR3,'-bx','LineWidth',1); 142 | % hold on 143 | % plot(N,SNR4,'-bs','LineWidth',1); 144 | % hold on 145 | % plot(N,SNR5,'--gd','LineWidth',1); 146 | % hold on 147 | % plot(N,SNR6,'-cx','LineWidth',1); 148 | % hold on 149 | % plot(N,SNR7,'-g+','LineWidth',1); 150 | % hold on 151 | % plot(N,SNR8,'--b+','LineWidth',1); 152 | % hold on 153 | % plot(N,SNR0,'-rs','LineWidth',1); 154 | % xlabel('N','Interpreter','latex','Fontsize',15); 155 | % ylabel('SNR(dB)','Interpreter','latex','Fontsize',15); 156 | % legend('1-bit','2-bit','3-bit','4-bit','5-bit','6-bit','7-bit','8-bit','Manopt','Interpreter','latex','Fontsize',15); 157 | % hold on ; 158 | % grid on; 159 | % hold on; 160 | % box on; 161 | % toc 162 | 163 | % figure 164 | % hold on 165 | % plot(N,SNR1,'-gs','LineWidth',1); 166 | % hold on 167 | % plot(N,SNR2,'--cd','LineWidth',1); 168 | % hold on 169 | % plot(N,SNR3,'-bx','LineWidth',1); 170 | % hold on 171 | % plot(N,SNR4,'-bs','LineWidth',1); 172 | % hold on 173 | % plot(N,SNR5,'--gd','LineWidth',1); 174 | % hold on 175 | % plot(N,SNR0,'-rs','LineWidth',1); 176 | % xlabel('N','Interpreter','latex','Fontsize',15); 177 | % ylabel('SNR(dB)','Interpreter','latex','Fontsize',15); 178 | % legend('1-bit','2-bit','3-bit','4-bit','5-bit','Manopt','Interpreter','latex','Fontsize',15); 179 | % hold on ; 180 | % grid on; 181 | % hold on; 182 | % box on; 183 | % toc 184 | 185 | %set(gca,'yticklabel',{'5%','6%','7%','8%','9%','10%'})%set ylabel in 100% 186 | -------------------------------------------------------------------------------- /Opt_absWZ.m: -------------------------------------------------------------------------------- 1 | function [W, valueOpt] = Opt_absWZ(Z,numBits) 2 | % Syntex: [W, valueOpt] = Opt_absWZ(Z,numBits) 3 | % Z is a complex vector. The software is to solve max |W^H Z|, where W is 4 | % on unit circle uniformly. 5 | 6 | 7 | % Author(s): Tiebin Mi, Rujing Xiong 8 | % Date: 09-29-2022 9 | 10 | %% check input argument 11 | if ~exist('Z','var') 12 | error('The Z is empty.') 13 | end 14 | 15 | if ~exist('numBits','var') 16 | warning('The numBits is empty. Set numBits=4 by default.') 17 | numBits = 4; 18 | end 19 | 20 | if ~isvector(Z) 21 | error('Z must be a vector.') 22 | end 23 | 24 | %% 25 | numElements = length(Z); 26 | 27 | angleWeightRange = 2*pi/2^numBits; 28 | 29 | %% 30 | thetaZ = mod(angle(Z),2*pi); 31 | 32 | thetaZNormalized = mod(thetaZ,angleWeightRange); 33 | 34 | [~, indexThetaZ] = sort(thetaZNormalized,'ascend'); 35 | 36 | %% 37 | thetaZShift = round((thetaZ-thetaZNormalized)/angleWeightRange); 38 | thetaZShifting = repmat(thetaZShift.',2^numBits*numElements,1); 39 | 40 | %% 41 | angleWeightNormalized = zeros(numElements*2^numBits,numElements); 42 | 43 | for iPart = 1:1:2^numBits 44 | angleWeightNormalized((iPart-1)*numElements+indexThetaZ, indexThetaZ) = (iPart-1)*ones(numElements,numElements) + triu(ones(numElements,numElements)).'; 45 | end 46 | 47 | angleWeightNormalized = angleWeightNormalized - thetaZShifting; 48 | angleWeightNormalized = mod(angleWeightNormalized,2^numBits); 49 | 50 | %% 51 | weightChecked = exp(1i*angleWeightRange.*angleWeightNormalized); 52 | 53 | [valueOpt, indexOpt] = max(abs(weightChecked*Z)); 54 | 55 | %% 56 | W = weightChecked(indexOpt,:)'; 57 | 58 | end -------------------------------------------------------------------------------- /Opt_absWZ2.m: -------------------------------------------------------------------------------- 1 | function [W, valueOpt] = Opt_absWZ2(Z,numBits) 2 | % Syntex: [W, valueOpt] = Opt_absWZ(Z,numBits) 3 | % Z is a complex vector. The software is to solve max |W^T Z|, where W is 4 | % on unit circle uniformly. 5 | 6 | 7 | % Author(s): Tiebin Mi, Rujing Xiong 8 | % Date: 09-29-2022 9 | 10 | %% check input argument 11 | if ~exist('Z','var') 12 | error('The Z is empty.') 13 | end 14 | 15 | if ~exist('numBits','var') 16 | warning('The numBits is empty. Set numBits=4 by default.') 17 | numBits = 4; 18 | end 19 | 20 | if ~isvector(Z) 21 | error('Z must be a vector.') 22 | end 23 | 24 | %% 25 | numElements = length(Z); 26 | 27 | angleWeightRange = 2*pi/2^numBits; 28 | 29 | %% 30 | thetaZ = mod(angle(Z),2*pi); 31 | 32 | thetaZNormalized = mod(thetaZ,angleWeightRange); 33 | 34 | [~, indexThetaZ] = sort(thetaZNormalized,'ascend'); 35 | 36 | %% 37 | thetaZShift = round((thetaZ-thetaZNormalized)/angleWeightRange); 38 | thetaZShifting = repmat(thetaZShift.',2^numBits*numElements,1); 39 | 40 | %% 41 | angleWeightNormalized = zeros(numElements*2^numBits,numElements); 42 | 43 | for iPart = 1:1:2^numBits 44 | angleWeightNormalized((iPart-1)*numElements+indexThetaZ, indexThetaZ) = (iPart-1)*ones(numElements,numElements) + triu(ones(numElements,numElements)).'; 45 | end 46 | 47 | angleWeightNormalized = angleWeightNormalized - thetaZShifting; 48 | angleWeightNormalized = mod(angleWeightNormalized,2^numBits); 49 | 50 | %% 51 | weightChecked = exp(1i*angleWeightRange.*angleWeightNormalized); 52 | 53 | [valueOpt, indexOpt] = max(abs(weightChecked*Z)); 54 | 55 | %% 56 | W = weightChecked(indexOpt,:).'; 57 | 58 | end -------------------------------------------------------------------------------- /Opt_wHRw.m: -------------------------------------------------------------------------------- 1 | function[w_opt, valueOpt] = Opt_wHRw(R,B) 2 | %% Author: Rujing Xiong, Tiebin Mi 3 | % CreatTime: 2022.09.26 4 | % Complete:2022.09.26 5 | % Modified: 2022.09.30 modified for multi-bit 6 | % E-mail: Rujing@hust.edu.cn 7 | % Description: DiscreteOptimization for 2-bit RIS, multi-bit 8 | % Based on traditional channel model 9 | % R is rank-one 10 | %% check input argument 11 | if ~exist('R','var') 12 | error('The Z is empty.') 13 | end 14 | 15 | if ~exist('B','var') 16 | warning('The numBits is empty. Set numBits=4 by default.') 17 | B = 4; 18 | end 19 | %% 20 | [Z,eigs_R] = eig(R,'vector'); 21 | [~,index_z] = sort(eigs_R,'descend'); 22 | Z = Z(:,index_z); %The corresponding eigenvectors are sorted in descending order too. 23 | z = Z(:,1); %Taking the igenvector corresponding to the largest eigenvalue 24 | 25 | N = length(z); 26 | U = zeros(N,2^B*N); 27 | 28 | theta_ori = angle(z); % the angle of eigenvector 29 | theta_temp = angle(z); 30 | theta_ori = mod(theta_ori,2*pi);% into(0,2*pi] 31 | 32 | 33 | theta_tilde = repmat(theta_ori,1,2^B); 34 | partition_maxrix = 0:2*pi/2^B:(2*pi-2*pi/2^B); 35 | 36 | theta_tilde = theta_tilde + partition_maxrix;%compute theta_tilde 37 | 38 | theta_tilde = mod(theta_tilde,2*pi);% devote theta_tilde (0,2*pi] 39 | theta_tilde = sort(theta_tilde,2); % sort each row, select the smallest candidate from the four 40 | 41 | theta = theta_tilde(:,1);% take the first column as initialization 42 | 43 | [theta,index_t] = sort(theta); % sort theta_tilde. Note! need to record the first N(t) elements' index. Because it include the solution index imformation 44 | 45 | U_ = repmat(theta,1,2^B*N); % repeat the row of theta_tilde once, the column 4*N(t) times to obtain U. 46 | %theta_hat = sort(reshape(theta_tilde,2^B*N(t),1))+pi/4; 47 | 48 | 49 | triu_temp = triu( (2*pi/2^B)*ones(N) );% a upper triangular matrix which element is 2*pi/2^B 50 | triu_temp = repmat(triu_temp,1,2^B) ;% repeat the upper triangular 2^B times by row 51 | U_partition_temp = kron(( 0:1:(2^B-1) ).*(2*pi/2^B),ones(N) ); %calculate the kronecker product; 52 | U_partition = U_partition_temp + triu_temp; 53 | U_hat = U_partition + U_; 54 | 55 | for i = 1:N 56 | U(index_t(i),:) = U_hat(i,:);%Thereby, set U is completed. 57 | end 58 | 59 | temp = repmat(theta_temp,1,2^B*N); 60 | Tau = U-temp;% Tau is the matrix that each colum of U minus theta_ori; each column of Tau is the angles of a candidate w. 61 | 62 | Tau = cos(Tau)+1i*sin(Tau);%above tau in Tau is phase. 63 | %Tau = conj(Tau); 64 | Y = Tau'*R*Tau; 65 | Y = diag(Y);% get the diagonal elements 66 | [~,Tau_index] = max(Y); 67 | w_opt = Tau(:,Tau_index); 68 | w_opt = conj(w_opt); 69 | valueOpt =w_opt'*R*w_opt; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Optimal Discrete Beamforming of RIS-Aided Wireless Communications: An Inner Product Maximization Approach 2 | ## Description 3 | 1. The main branch is for the discrete optimizaion problem with quadratic forms ($w^HRw$) or 2-norms $||Aw||_2$, where the matrix R ( or A) is with rank-1. The approach is called DaS method !!! 4 | 2. The For-lowrank branch code is used to achieve the global optimum in maximizing quadratic forms ($w^HRw$) or 2-norms $||Aw||_2$ where the matrix R ( or A) is M, M is not 1. w is the discrete phase configuration vector. 5 | ## Reference 1 6 | The main code is associated with the published paper entitled "Optimal Discrete Beamforming of RIS-Aided Wireless Communications: An Inner Product Maximization Approach". If you are interested in our work, please reference it using 7 | ``` 8 | @inproceedings{xiong2024optimal, 9 | title={Optimal discrete beamforming of RIS-aided wireless communications: An inner product maximization approach}, 10 | author={Xiong, Rujing and Dong, Xuehui and Mi, Tiebin and Wan, Kai and Qiu, Robert Caiming}, 11 | booktitle={2024 IEEE Wireless Communications and Networking Conference (WCNC)}, 12 | pages={1--6}, 13 | year={2024}, 14 | organization={IEEE} 15 | } 16 | ``` 17 | 18 | ## Description 2 19 | The special code "Alternating_main" in main branch is the Alternating inner product maximization approach, mainly for solving p-norm $||Aw||_p$ (p is 2 within this code) maximization problems, while A is a matrix with rank-M. This approach features high efficiency and is based on the optimal discrete optimization with rank-1 scenarios (DaS method), as stated as above reference 1. 20 | 21 | ## Reference 2 22 | This code is associated with the paper-- 23 | Xiong R, Mi T, Lu J, et al. Optimal Beamforming of RIS-Aided Wireless Communications: An Alternating Inner Product Maximization Approach[J]. arXiv preprint arXiv:2405.06442, 2024. If you are interested in our work, please reference it using 24 | ``` 25 | @misc{xiong2024optimal, 26 | title={Optimal Beamforming of RIS-Aided Wireless Communications: An Alternating Inner Product Maximization Approach}, 27 | author={Rujing Xiong and Tiebin Mi and Jialong Lu and Ke Yin and Kai Wan and Fuhai Wang and Robert Caiming Qiu}, 28 | year={2024}, 29 | eprint={2405.06442}, 30 | archivePrefix={arXiv}, 31 | primaryClass={cs.IT}, 32 | url={https://arxiv.org/abs/2405.06442}, 33 | } 34 | ``` 35 | 36 | -------------------------------------------------------------------------------- /TestingManopt1Norm.m: -------------------------------------------------------------------------------- 1 | clear all;close all;clc; 2 | 3 | %% Generate random data. 4 | numBits = 1; 5 | 6 | stepAngle = 2*pi/2^numBits; 7 | 8 | n = 100; 9 | 10 | m = 10; 11 | 12 | p = 1; 13 | 14 | numTrials = 20000; 15 | 16 | %% Create the problem structure. 17 | 18 | manifold = complexcirclefactory(n); 19 | problem.M = manifold; 20 | 21 | costContinuous = zeros(numTrials, 1); 22 | costRounded = zeros(numTrials, 1); 23 | costLifting = zeros(numTrials, 1); 24 | 25 | f = waitbar(0,'please wait...'); 26 | 27 | for iTrial = 1:1:numTrials 28 | 29 | waitbar(iTrial/numTrials,f,'please wait...'); 30 | 31 | A = randn(m,n) + 1i*randn(m,n); 32 | 33 | % Define the problem cost function and its Euclidean gradient. 34 | problem.cost = @(x) -norm(A*x, 1); 35 | problem.egrad = @(x) -A'*sign(A*x); % notice the 'e' in 'egrad' for Euclidean 36 | 37 | [x, xcost, info, options] = trustregions(problem); 38 | 39 | xAlternatingRounded = exp(1i*stepAngle.*round(angle(x)./stepAngle)); 40 | 41 | [xLifting, costList2] = Lift_max_Ax_p(A, p, xAlternatingRounded, numBits); 42 | 43 | costContinuous(iTrial) = norm(A*x, p); 44 | costRounded(iTrial) = norm(A*xAlternatingRounded, p); 45 | costLifting(iTrial) = norm(A*xLifting, p); 46 | 47 | end 48 | 49 | close(f) 50 | 51 | mean(costLifting - costRounded) 52 | 53 | %% 54 | nameWorkspace = strcat('WS_1Norm-', datestr(now,'mmmm-dd-HH-MM-SS'), '.mat'); 55 | 56 | save(nameWorkspace) 57 | 58 | 59 | %% 60 | relativeLiftingGain = abs(costLifting-costRounded)./abs(costContinuous-costRounded); 61 | 62 | 63 | %% 64 | figure(1) 65 | histogram(costLifting-costRounded, 'Normalization','count') 66 | xlim([-0.5, 30]) 67 | 68 | xlabel('$|| A e^{j \mathbf{\Omega}_{lift} } ||_1 - || A e^{j \mathbf{\Omega}_{round} } ||_1$','Interpreter','latex','FontSize',12) 69 | ylabel('Count','FontSize',12) 70 | grid on 71 | 72 | % exportgraphics(gcf, 'Lifting_1Norm_20000.pdf') 73 | 74 | %% 75 | figure(2) 76 | histogram(relativeLiftingGain, 'Normalization','count') 77 | grid on 78 | xlim([0, 0.50]) 79 | xline(median(relativeLiftingGain),'-r','LineWidth',2) 80 | 81 | xlabel('$\frac{|| A e^{j \mathbf{\Omega}_{lifted} } ||_1 - || A e^{j \mathbf{\Omega}_{rounded} } ||_1}{|| A e^{j \mathbf{\Omega}_{unrounded} } ||_1 - || A e^{j \mathbf{\Omega}_{rounded} } ||_1}$','Interpreter','latex') 82 | ylabel('Count') 83 | 84 | % exportgraphics(gcf, 'Lifting_1Norm_20000_Percent.pdf') 85 | 86 | matlab2tikz('file1.tex'); -------------------------------------------------------------------------------- /TestingManopt2Norm.m: -------------------------------------------------------------------------------- 1 | clear all;close all;clc; 2 | 3 | %% Generate random data. 4 | numBits = 1; 5 | 6 | stepAngle = 2*pi/2^numBits; 7 | 8 | n = 100; 9 | 10 | m = 10; 11 | 12 | p = 2; 13 | 14 | numTrials = 20000; 15 | 16 | 17 | %% 18 | manifold = complexcirclefactory(n); 19 | problem.M = manifold; 20 | 21 | costContinuous = zeros(numTrials, 1); 22 | costRounded = zeros(numTrials, 1); 23 | costLifting = zeros(numTrials, 1); 24 | 25 | f = waitbar(0,'please wait...'); 26 | 27 | for iTrial = 1:1:numTrials 28 | 29 | waitbar(iTrial/numTrials,f,'please wait...'); 30 | 31 | A = randn(m,n) + 1i*randn(m,n); 32 | 33 | A_A = A'*A; 34 | 35 | % Define the problem cost function and its Euclidean gradient. 36 | problem.cost = @(x) -x'*(A_A*x); 37 | problem.egrad = @(x) -2*A_A*x; % notice the 'e' in 'egrad' for Euclidean 38 | 39 | [x, xcost, info, options] = trustregions(problem); 40 | 41 | xAlternatingRounded = exp(1i*stepAngle.*round(angle(x)./stepAngle)); 42 | 43 | [xLifting, costList2] = Lift_max_Ax_p(A, p, xAlternatingRounded, numBits); 44 | 45 | 46 | costContinuous(iTrial) = norm(A*x, p); 47 | costRounded(iTrial) = norm(A*xAlternatingRounded, p); 48 | costLifting(iTrial) = norm(A*xLifting, p); 49 | 50 | end 51 | 52 | close(f) 53 | 54 | mean(costLifting - costRounded) 55 | 56 | %% 57 | nameWorkspace = strcat('WS_2Norm-', datestr(now,'mmmm-dd-HH-MM-SS'), '.mat'); 58 | 59 | save(nameWorkspace) 60 | 61 | %% 62 | relativeLiftingGain = abs(costLifting-costRounded)./abs(costContinuous-costRounded); 63 | 64 | %% 65 | figure(1) 66 | histogram(costLifting-costRounded, 'Normalization','count') 67 | grid on 68 | xlim([-0.3, 9]) 69 | 70 | xlabel('$|| A e^{j \mathbf{\Omega}_{lift} } ||_2 - || A e^{j \mathbf{\Omega}_{round} } ||_2$','Interpreter','latex','FontSize',12) 71 | ylabel('Count','FontSize',12) 72 | 73 | % exportgraphics(gcf, 'Lifting_2Norm_20000.pdf') 74 | 75 | %% 76 | figure(2) 77 | histogram(relativeLiftingGain, 'Normalization','count') 78 | grid on 79 | xlim([0, 0.50]) 80 | xline(median(relativeLiftingGain),'-r','LineWidth',2) 81 | 82 | 83 | xlabel('$\frac{|| A e^{j \mathbf{\Omega}_{lifted} } ||_2 - || A e^{j \mathbf{\Omega}_{rounded} } ||_2}{|| A e^{j \mathbf{\Omega}_{unrounded} } ||_2 - || A e^{j \mathbf{\Omega}_{rounded} } ||_2}$','Interpreter','latex') 84 | ylabel('Count') 85 | 86 | %matlab2tikz('file1.tex'); 87 | 88 | % exportgraphics(gcf, 'Lifting_2Norm_20000_Percent.pdf') -------------------------------------------------------------------------------- /discrete.m: -------------------------------------------------------------------------------- 1 | function [opt] = discrete(w,B,n) 2 | for i=1:1:n 3 | for j=0:1:2^B-1 4 | if distance(angle(w(i,1)),j*2*pi/2^B) < pi/2^B 5 | w(i,1) = exp(1i*j*pi/2^(B-1)); 6 | end 7 | end 8 | end 9 | opt = w; -------------------------------------------------------------------------------- /discretization1Bit.m: -------------------------------------------------------------------------------- 1 | % Function of 1-bit quantization for RIS 2 | function [Angle] = discretization1Bit(w) 3 | Angle = angle(w); 4 | Angle = Angle.*180/pi; 5 | Angle(Angle>-180 & Angle<-90) = Angle(Angle>-180 & Angle<-90)+360; 6 | Angle(Angle>-90 & Angle<=90) = 1; 7 | Angle(Angle>90 & Angle<=270) = -1; 8 | -------------------------------------------------------------------------------- /esra.m: -------------------------------------------------------------------------------- 1 | function [w] = esra(A,B) 2 | %求解max(||Aw||2),B为bit数 3 | [~,N] = size(A); 4 | omega = 2*pi/(2^B); 5 | w = exp(1i*omega.*randi(2^B,N,1)); 6 | deta = [0,1]; 7 | deta(1) = norm(A*w); 8 | while(deta(2) > 0) 9 | for i = 1:N 10 | w1 = w; 11 | w1(i,1) = 0; 12 | aaa = w1'*(A')*A*w1; 13 | w1(i,1) = 1; 14 | bbb = w1'*(A')*A*w1 - aaa; 15 | for j = 1:2^B 16 | if distance(angle(bbb)+j*omega,angle(aaa)) <= omega/2 17 | w(i,1) = exp(1i*omega*j); 18 | end 19 | end 20 | end 21 | deta(2) = abs(deta(1)-norm(A*w)); 22 | deta(1) = norm(A*w); 23 | end 24 | 25 | -------------------------------------------------------------------------------- /sdr.m: -------------------------------------------------------------------------------- 1 | function w_sdr = sdr(N,R,count) 2 | f_tmp = 0; 3 | r_tmp = zeros(N,1); % r=[]; 4 | w_tmp = zeros(N,1); 5 | for k=1:count 6 | r = (randn(N+1,1)+1i*randn(N+1,1)).*sqrt(1/2); % (N,1) 7 | cvx_begin 8 | variable V(N+1,N+1) symmetric semidefinite %变量是一个(N)*(N)的对称半正定矩阵 9 | maximize( real(trace(R*V))) 10 | subject to 11 | diag(V) == 1; 12 | cvx_end 13 | 14 | [U,Sigma] = eig(V); 15 | w = U*Sigma^(1/2)*r; % (N*1) 16 | f = w'*R*w; %随机次数为count次,找到其中最大的f对应的波束赋形向量w和高斯随机向量r 17 | if f>f_tmp 18 | f_tmp = max(f,f_tmp); 19 | r_tmp = r; 20 | w_tmp = w; %求解出来的w_tmp为啥比w_的维度要小10的倍数个元素 21 | end 22 | end 23 | % [m,index]=max(f); 24 | % r_opt = r(:,index); 25 | % w_opt = w(:,index); 26 | % theta_opt = angle(w_opt); 27 | % w_opt = exp(1i*theta_opt); % 使其满足恒模约束 28 | % W = diag(w_opt); 29 | w_tmp = w_tmp./w_tmp(N+1); 30 | theta_opt = angle(w_tmp); 31 | w_sdr = exp(1i*theta_opt); -------------------------------------------------------------------------------- /test_max_Ax_1.m: -------------------------------------------------------------------------------- 1 | clear all;clc; 2 | 3 | %% 4 | numBits = 2; 5 | 6 | stepAngle = 2*pi/2^numBits; 7 | 8 | n = 100; 9 | 10 | m = 30; 11 | 12 | A = randn(m,n) + 1i*randn(m,n); 13 | 14 | 15 | load('A.mat'); 16 | 17 | %% 18 | w_k = exp(1i*2*pi*rand(1))*ones(n,1); 19 | 20 | w_k1 = exp(1i*2*pi*rand(n,1)); 21 | 22 | 23 | iIter = 0; 24 | 25 | costValue = []; 26 | 27 | while abs(norm(A*w_k1,1) - norm(A*w_k,1))/norm(A*w_k1,1) > 1e-6 28 | 29 | iIter = iIter + 1; 30 | 31 | w_k = w_k1; 32 | 33 | z_k = exp(1i*angle(A*w_k)); 34 | w_k1 = exp(1i*angle(A'*z_k)); 35 | 36 | 37 | % z_k = A*w_k./norm(A*w_k); 38 | % w_k1 = exp(1i*angle(A'*z_k)); 39 | 40 | costValue(iIter) = norm(A*w_k1,1); 41 | 42 | end 43 | 44 | %% 45 | w_k1_Quant = exp(1i*stepAngle.*round(angle(w_k1)./stepAngle)); 46 | 47 | iIter = iIter+1; 48 | 49 | costValue(iIter) = norm(A*w_k1_Quant,1); 50 | 51 | %% 52 | w_k = exp(1i*2*pi*rand(1))*ones(n,1); 53 | 54 | w_k1 = w_k1_Quant; 55 | k = 1; 56 | while k<15 57 | %while 1e10*abs(norm(A*w_k1,1) - norm(A*w_k,1))/norm(A*w_k1,1) > 1e-10 58 | 59 | iIter = iIter + 1; 60 | 61 | w_k = w_k1; 62 | 63 | z_k = exp(1i*angle(A*w_k)); 64 | w_k1 = Opt_absWZ(A'*z_k, numBits); 65 | 66 | % z_k = exp(1i*2*pi*rand(1))*exp(1i*angle(A*w_k)); 67 | % w_k1 = Opt_absWZ(A'*z_k, numBits); 68 | 69 | norm(A*w_k1,1) 70 | 71 | costValue(iIter) = norm(A*w_k1,1); 72 | k = k+1; 73 | end 74 | 75 | 76 | %% 77 | figure 78 | plot(costValue, 'Marker', 'square', 'LineWidth', 1, 'LineStyle', '-', 'Color', [0 0 1]); 79 | grid on 80 | xlim([1, length(costValue)]) 81 | % ylim([400, 480]) 82 | 83 | xlabel('$k$','Interpreter','latex') 84 | ylabel('$|| A e^{j \mathbf{\Omega} } ||_1$','Interpreter','latex') 85 | 86 | 87 | %% 88 | % matlab2tikz('file2.tex'); -------------------------------------------------------------------------------- /test_max_Ax_2.m: -------------------------------------------------------------------------------- 1 | clear all;clc; 2 | 3 | %% 4 | numBits = 2; 5 | 6 | stepAngle = 2*pi/2^numBits; 7 | 8 | n = 100; 9 | 10 | m = 30; 11 | 12 | A = randn(m,n) + 1i*randn(m,n); 13 | 14 | 15 | load('A.mat'); 16 | 17 | %% 18 | w_k = exp(1i*2*pi*rand(1))*ones(n,1); 19 | 20 | w_k1 = exp(1i*2*pi*rand(n,1)); 21 | 22 | 23 | iIter = 0; 24 | 25 | costValue = []; 26 | 27 | while abs(norm(A*w_k1) - norm(A*w_k))/norm(A*w_k1) > 1e-6 28 | 29 | iIter = iIter + 1; 30 | 31 | w_k = w_k1; 32 | 33 | z_k = exp(1i*2*pi*rand(1))*A*w_k./norm(A*w_k); 34 | w_k1 = exp(1i*angle(A'*z_k)); 35 | 36 | 37 | % z_k = A*w_k./norm(A*w_k); 38 | % w_k1 = exp(1i*angle(A'*z_k)); 39 | 40 | costValue(iIter) = norm(A*w_k1); 41 | 42 | end 43 | 44 | %% 45 | w_k1_Quant = exp(1i*stepAngle.*round(angle(w_k1)./stepAngle)); 46 | 47 | iIter = iIter+1; 48 | 49 | costValue(iIter) = norm(A*w_k1_Quant); 50 | 51 | %% 52 | w_k = exp(1i*2*pi*rand(1))*ones(n,1); 53 | 54 | w_k1 = w_k1_Quant; 55 | k = 1; 56 | while k<15 57 | %while abs(norm(A*w_k1) - norm(A*w_k))/norm(A*w_k1) > 1e-30 58 | 59 | iIter = iIter + 1; 60 | 61 | w_k = w_k1; 62 | 63 | z_k = exp(1i*2*pi*rand(1))*A*w_k./norm(A*w_k); 64 | w_k1 = Opt_absWZ(A'*z_k, numBits); 65 | 66 | % z_k = A*w_k./norm(A*w_k); 67 | % w_k1 = Opt_absWZ(A'*z_k, numBits); 68 | 69 | norm(A*w_k1) 70 | 71 | costValue(iIter) = norm(A*w_k1); 72 | k = k+1; 73 | end 74 | 75 | 76 | %% 77 | figure; 78 | plot(costValue, 'Marker', 'square', 'LineWidth', 1, 'LineStyle', '-', 'Color', [0 0 1]); 79 | grid on 80 | xlim([1, length(costValue)]) 81 | % ylim([400, 480]) 82 | 83 | xlabel('$k$','Interpreter','latex') 84 | ylabel('$|| A e^{j \mathbf{\Omega} } ||_1$','Interpreter','latex') 85 | %annotation('doublearrow',[0.3,0.5],[0.7,0.9],'LineStyle','-','color','c','LineWidth',2,'HeadStyle','Plain') 86 | 87 | % exportgraphics(gcf, 'Lifting_2.pdf'); 88 | % matlab2tikz('file3.tex'); --------------------------------------------------------------------------------