├── DataSet ├── TrainingDataSingleClusters.mat ├── TrainingDataSingleClustersNoFadingCascades.mat └── TrainingDataSingleClustersPart2.mat ├── GenerateTrainingSet ├── funComputesinr.m ├── funGenerateNetwork.m ├── funSimulateNetworkBinPowerlevel.m ├── generateTrainingSet.m └── parameters.m ├── README.md ├── decompose_kernel.m ├── funComputesinr.m ├── funGenerateNetwork.m ├── funLikelihood_data.m ├── funNeighbourL.m ├── funSimulateNetworkBinPowerlevel.m ├── generateTrainingSet.m ├── greedyMAP.m ├── greedy_lazy.m ├── greedy_sym.m ├── parameters.m ├── sample_dpp.m └── trainDPP.m /DataSet/TrainingDataSingleClusters.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stochastic-geometry/DPPL/92d54212890448b59517708a22f07685d93ec7b8/DataSet/TrainingDataSingleClusters.mat -------------------------------------------------------------------------------- /DataSet/TrainingDataSingleClustersNoFadingCascades.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stochastic-geometry/DPPL/92d54212890448b59517708a22f07685d93ec7b8/DataSet/TrainingDataSingleClustersNoFadingCascades.mat -------------------------------------------------------------------------------- /DataSet/TrainingDataSingleClustersPart2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stochastic-geometry/DPPL/92d54212890448b59517708a22f07685d93ec7b8/DataSet/TrainingDataSingleClustersPart2.mat -------------------------------------------------------------------------------- /GenerateTrainingSet/funComputesinr.m: -------------------------------------------------------------------------------- 1 | function SINR = funComputesinr(link_distance,P_alloc,N0,alpha) 2 | % Author: Chiranjib Saha and Harpreet S. Dhillon 3 | % This function computes the SINR seen by each receiver in the network. 4 | % Input: link_distance : NxN matrix 5 | % P_alloc: power allocation for each link 6 | % N0 : noise power 7 | % alpha: pathloss 8 | link_distance_eff = link_distance; 9 | pathloss = link_distance_eff.^(-alpha/2); 10 | Power = repmat(P_alloc',length(P_alloc),1); 11 | h = sqrt(Power).*pathloss; 12 | Total_power = diag(h*h'); 13 | serving_power=diag((abs(h).^2)); 14 | interference = Total_power-serving_power; 15 | %% sanity check 16 | if sum(interference<0)&& sum(S==1)>1 17 | keyboard; 18 | end 19 | SINR = serving_power./(N0+interference); 20 | %SINR = SINR'; 21 | end -------------------------------------------------------------------------------- /GenerateTrainingSet/funGenerateNetwork.m: -------------------------------------------------------------------------------- 1 | function [link_distance,tr_loc,rec_loc,S_max,maxrate] = funGenerateNetwork(N,diskRadius,N0,alpha) 2 | % Author: Chiranjib Saha and Harpreet S. Dhillion 3 | % 4 | % This function generates a network with N links and provides the optimal 5 | % subset of active links (E*). 6 | % Input: N = number of links, diskRadius = radius of simulation disk 7 | % N0 = noise power, alpha = pathloss exponent 8 | % Output: link_distance: NxN matrix of link distances 9 | % tr_loc : Nx2 matrix with coordinates of tx locations 10 | % rec_loc : Nx2 matrix with coordinates of rx locations 11 | % S_max: 1XN binary array with the active links indicated as `1' 12 | % maxrate: maximum rate at bps 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | addpath(genpath('.\ggplab\')); 15 | tolerance = 0.05; 16 | beta = 1.1; 17 | parameters; 18 | % Generate a network topology % 19 | [~,link_distance,tr_loc,rec_loc,~,~] = funSimulateNetworkBinPowerlevel(N,diskRadius,link_dist); 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | P_alloc_guess = ones(N,1); 22 | SINR_guess = funComputesinr(link_distance,P_alloc_guess,N0,alpha); 23 | G = link_distance.^-alpha; % this is the pathloss matrix 24 | G_empty_diag = G; 25 | G_empty_diag(logical(eye(size(G))))=0; 26 | % encode the variables vector 27 | loopcount = 0; 28 | min_var_arr =[]; 29 | while true 30 | fprintf('\n Solving GP, loop = %d',loopcount); 31 | loopcount = loopcount+1; 32 | % note that GP is free from initial guess hyperparameters. 33 | gpvar variables(2*N) 34 | objfunc = prod(variables(N+1:2*N).^(-(SINR_guess./(1+SINR_guess)))); 35 | constr = [ beta^-1*SINR_guess <= variables(N+1:2*N) ; 36 | variables(N+1:2*N) <= beta*SINR_guess ; 37 | (N0*diag(G).^-1.*variables(1:N).^-1 +... 38 | (G_empty_diag*variables(1:N)).*diag(G).^-1.*variables(1:N).^-1).*variables(N+1:2*N)<=ones(N,1); 39 | variables(1:N)<= ones(N,1)]; 40 | 41 | % solve the power control problem 42 | [min_var, solution, status] = gpsolve(objfunc, constr); 43 | assign(solution); 44 | SINR_guess = solution{2}(N+1:2*N); 45 | min_var_arr(loopcount) = min_var; 46 | fprintf('\n At iteration %d, min value computed = %f',loopcount,min_var); 47 | if loopcount>25 && min_var_arr(end-1)-min_var_arr(end)0.1)'; 55 | P_alloc_quant = (P_alloc<0.1)*0.01+~(P_alloc<0.1)*1; 56 | SINR = funComputesinr(link_distance,P_alloc,N0,alpha); 57 | SINR_quant = funComputesinr(link_distance,P_alloc_quant,N0,alpha); 58 | fprintf('\n Sum rate: GP = %f, quant = %f',sum(log2(1+SINR)),sum(log2(1+SINR_quant))); 59 | % 60 | maxrate = sum(log2(1+SINR_quant)); 61 | end 62 | 63 | -------------------------------------------------------------------------------- /GenerateTrainingSet/funSimulateNetworkBinPowerlevel.m: -------------------------------------------------------------------------------- 1 | function [H,link_distance,tr_loc,rec_loc,S_max,maxrate] = funSimulateNetworkBinPowerlevel(N,diskRadius,link_dist) 2 | % Author: Chiranjib Saha and Harpreet S. Dhillon 3 | % This function drops N links on a circular window of diskRadius 4 | % Output: H : NXN matrix with each entry being 1. This is a dummy output. 5 | % One can implement any fading gain here. 6 | % link_distance : NxN matrix with link distances 7 | % tr_loc , rec_loc : Nx2 matrix with tx and rx locations 8 | % S_max : empty matrix 9 | % maxrate : empty matix 10 | 11 | 12 | randangle = 2*pi*rand(N,1); 13 | randradius = (diskRadius/7)*sqrt(rand(N,1)); 14 | tr_loc = [randradius.*cos(randangle),randradius.*sin(randangle)]; 15 | randorient = 2*pi*rand(N,1); 16 | rec_loc = [tr_loc(:,1)+link_dist.*cos(randorient),tr_loc(:,2)+link_dist.*sin(randorient)]; 17 | 18 | %%%%%%%%%%%%%% Code dump: can be uncommented for plotting purposes 19 | %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | % figure; 21 | % hold on; 22 | % for linkcount = 1:N 23 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',1); 24 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',1,'MarkerFaceColor','blue'); 25 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',1,'MarkerFaceColor','red'); 26 | % end 27 | %keyboard; 28 | % figure; 29 | % axis square; 30 | % for linkcount = 1:N 31 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',1); 32 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','blue'); 33 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','red'); 34 | % end 35 | % 36 | % plot([tr_loc(:,1)';rec_loc(:,1)'],[tr_loc(:,2)';rec_loc(:,2)'],'k'); 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | % Channel Generation %% 39 | H = ones(N,N);% randn(N,N)+1j*randn(N,N); % generate complex gaussian channel 40 | % make H symmetric 41 | %H = triu(H); 42 | %H = H + transpose(H); 43 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | % figure 45 | % alpha = 1; 46 | % hold on; 47 | % for linkcount = 1:N 48 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',0.2); 49 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','blue'); 50 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','red'); 51 | % end 52 | % box on; 53 | % axis('square'); 54 | %H = exprnd(1,N,N); 55 | link_distance= pdist2(rec_loc,tr_loc,'euclidean'); % link_distance(i,j) = ||Tr(j)- Rx(i)|| i.e. Row i corresponds to all distances from Txs to Rec i 56 | S_max = []; 57 | maxrate = []; 58 | 59 | 60 | -------------------------------------------------------------------------------- /GenerateTrainingSet/generateTrainingSet.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stochastic-geometry/DPPL/92d54212890448b59517708a22f07685d93ec7b8/GenerateTrainingSet/generateTrainingSet.m -------------------------------------------------------------------------------- /GenerateTrainingSet/parameters.m: -------------------------------------------------------------------------------- 1 | % This file contains all the necessary parameter values of the network 2 | 3 | % path-loss coefficient 4 | alpha = 2; 5 | % Radius of simulation disc 6 | diskradius = 10; 7 | % Chooses the Gaussian kernel for the S matrix 8 | choiceKernel =1; 9 | % Noise variance 10 | N0 = 0.0005; 11 | % Average number of links 12 | N_av = 20; 13 | % link distance 14 | link_dist =1; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Determinantal Point Process Learning (DPPL) 2 | ### Matlab scripts for the paper "Machine Learning meets Stochastic Geometry: Determinantal Subset Selection for Wireless Networks" 3 | #### Authors: Chiranjib Saha and Harpreet S. Dhillon 4 | ##### Email for correspondence: csaha@vt.edu 5 | 6 | Link to the paper: https://arxiv.org/pdf/1905.00504.pdf 7 | 8 | This repository contains the matlab scripts of DPPL proposed in the paper "Machine Learning meets Stochastic Geometry: 9 | Determinantal Subset Selection for Wireless 10 | Networks". 11 | 12 | Run "TrainDPP.m" to generate the results. 13 | Under the folder "GenerateTrainingSet", use generateTrainingSet.m to generate new training sets. 14 | 15 | Please cite the following paper if the code is reused. 16 | ``` 17 | @article{saha2019load, 18 | title={Machine Learning meets Stochastic Geometry: {D}eterminantal Subset Selection for Wireless Networks}, 19 | author={Saha, Chiranjib and Dhillon, Harpreet S}, 20 | note={available online: arxiv.org/abs/1905.00504}, 21 | year={2019} 22 | } 23 | ``` 24 | **Acknowledgements.** 25 | This repository reuses codes from the following sources. 26 | - ggplab: A Matlab toolbox for geometric programming (link: https://web.stanford.edu/~boyd/ggplab/) 27 | Note: please download the matlab scripts of geometric programming from this link and put the folder in "GenerateTrainingSet" 28 | - hpaulkeeler/DetPoisson_MATLAB: A github repositoty for determinantal point process 29 | - Codes for the paper -- 30 | Gillenwater, J., Kulesza, A., & Taskar, B. (2012). Near-optimal map inference for determinantal point processes. In Advances in Neural Information Processing Systems (pp. 2735-2743). 31 | Link of source code: http://jgillenw.com/dpp-map.html 32 | 33 | -------------------------------------------------------------------------------- /decompose_kernel.m: -------------------------------------------------------------------------------- 1 | function L = decompose_kernel(M) 2 | L.M = M; 3 | [V,D] = eig(M); 4 | L.V = real(V); 5 | L.D = real(diag(D)); -------------------------------------------------------------------------------- /funComputesinr.m: -------------------------------------------------------------------------------- 1 | function SINR = funComputesinr(link_distance,P_alloc,N0,alpha) 2 | 3 | link_distance_eff = link_distance; 4 | pathloss = link_distance_eff.^(-alpha/2); 5 | Power = repmat(P_alloc',length(P_alloc),1); 6 | h = sqrt(Power).*pathloss; 7 | Total_power = diag(h*h'); 8 | serving_power=diag((abs(h).^2)); 9 | interference = Total_power-serving_power; 10 | %% sanity check 11 | if sum(interference<0)&& sum(S==1)>1 12 | keyboard; 13 | end 14 | SINR = serving_power./(N0+interference); 15 | %SINR = SINR'; 16 | end -------------------------------------------------------------------------------- /funGenerateNetwork.m: -------------------------------------------------------------------------------- 1 | function [link_distance,tr_loc,rec_loc,S_max,maxrate] = funGenerateNetwork(N,diskRadius) 2 | addpath(genpath('.\ggplab\')); 3 | tolerance = 0.05; 4 | beta = 1.1; 5 | N0= 0.0005; 6 | alpha = 2; 7 | link_dist =1; 8 | % Generate a network topology % 9 | [~,link_distance,tr_loc,rec_loc,~,~] = funSimulateNetworkBinPowerlevel(N,diskRadius,N0,alpha,link_dist,'no_search'); 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | P_alloc_guess = ones(N,1); 12 | SINR_guess = funComputesinr(link_distance,P_alloc_guess,N0,alpha); 13 | G = link_distance.^-alpha; % this is the pathloss matrix 14 | G_empty_diag = G; 15 | G_empty_diag(logical(eye(size(G))))=0; 16 | % encode the variables vector 17 | loopcount = 0; 18 | min_var_arr =[]; 19 | while true 20 | fprintf('\n Solving GP, loop = %d',loopcount); 21 | loopcount = loopcount+1; 22 | % note that GP is free from initial guess hyperparameters. 23 | gpvar variables(2*N) 24 | objfunc = prod(variables(N+1:2*N).^(-(SINR_guess./(1+SINR_guess)))); 25 | constr = [ beta^-1*SINR_guess <= variables(N+1:2*N) ; 26 | variables(N+1:2*N) <= beta*SINR_guess ; 27 | (N0*diag(G).^-1.*variables(1:N).^-1 +... 28 | (G_empty_diag*variables(1:N)).*diag(G).^-1.*variables(1:N).^-1).*variables(N+1:2*N)<=ones(N,1); 29 | variables(1:N)<= ones(N,1)]; 30 | 31 | % solve the power control problem 32 | [min_var, solution, status] = gpsolve(objfunc, constr); 33 | assign(solution); 34 | SINR_guess = solution{2}(N+1:2*N); 35 | min_var_arr(loopcount) = min_var; 36 | fprintf('\n At iteration %d, min value computed = %f',loopcount,min_var); 37 | if loopcount>25 && min_var_arr(end-1)-min_var_arr(end)0.1)'; 45 | P_alloc_quant = (P_alloc<0.1)*0.01+~(P_alloc<0.1)*1; 46 | SINR = funComputesinr(link_distance,P_alloc,N0,alpha); 47 | SINR_quant = funComputesinr(link_distance,P_alloc_quant,N0,alpha); 48 | fprintf('\n Sum rate: GP = %f, quant = %f',sum(log2(1+SINR)),sum(log2(1+SINR_quant))); 49 | % 50 | maxrate = sum(log2(1+SINR_quant)); 51 | % plotNetwork(tr_loc,rec_loc,N,S_max); 52 | end 53 | 54 | -------------------------------------------------------------------------------- /funLikelihood_data.m: -------------------------------------------------------------------------------- 1 | function logLikelihood=funLikelihood_data(T,TrainingDataSet,diskradius,choiceKernel,param,alpha) 2 | % Code imported from the repository : https://github.com/hpaulkeeler/DetPoisson_MATLAB 3 | 4 | 5 | 6 | 7 | logLikelihoodVector=zeros(T,1); 8 | 9 | 10 | 11 | 12 | %Loop through all training/learning samples 13 | for tt=1:T 14 | %Create L matrix (ie for Phi) based on nearest neighbours 15 | Total_power = ( TrainingDataSet{tt}.link_distance.^(-alpha/2)).^2; 16 | tr_loc = TrainingDataSet{tt}.tr_loc; 17 | rec_loc = TrainingDataSet{tt}.rec_loc; 18 | [L,S]=funNeighbourL(Total_power,TrainingDataSet{tt}.link_distance,tr_loc,rec_loc,diskradius,choiceKernel,param(end),param(1:end-1)); 19 | %Create sub L matrix (ie for Psi) 20 | index = find(TrainingDataSet{tt}.S_max>0); 21 | subL=L(index,index); 22 | logLikelihoodVector(tt)=(log(det(subL))-log(det(L+eye(size(L))))); 23 | end 24 | logLikelihood=sum(logLikelihoodVector); 25 | end -------------------------------------------------------------------------------- /funNeighbourL.m: -------------------------------------------------------------------------------- 1 | % function L=funNeighbourL(xx,yy,lambda,choiceKernel,sigma,theta,N,M) 2 | % This function file creates an L(-ensemble-)matrix, as detailed in the 3 | % paper by Blaszczyszyn and Keeler[1](Section IV). 4 | % 5 | % The quality features or covariates (q_x in the above paper) are based on 6 | % the nearest neighbour distances. The similiarirty matrix (S in the paper) 7 | % which creates replusion among the points, can be formed from either 8 | % Gaussian or Cauchy kernel function. 9 | % 10 | % INPUTS: 11 | % xx and yy are the x and y values of the underlying discrete state space, 12 | % which is usually a realization of a point process on a bounded continuous 13 | % 2-D space such as a square or a disk. 14 | % 15 | % lambda is the point intensity/density (ie average number of points per 16 | % unit area) of the point process, which is used to rescale the distances. 17 | % 18 | % choiceKernel is a variable that takes value 1 (for Gaussian) or 2 (for 19 | % Cauchy) to select the kernel function. 20 | % 21 | % sigma is a parameter of kernel function. 22 | % 23 | % theta is a fitting parameters for the quality features/covariates. 24 | % 25 | % N is the number of neighbouring points. 26 | % 27 | % M is the number of distances between neighbour points. M is optional, but 28 | % when used, M must be equal to zero or N-1. 29 | % 30 | % OUTPUTS: 31 | % An L-ensemble kernel matrix for a determinantal point process on a 32 | % discrete space; see [1] for details. 33 | % 34 | % Author: H.P. Keeler, Inria/ENS, Paris, and University of Melbourne, 35 | % Melbourne, 2018. 36 | % 37 | % References: 38 | % [1] Blaszczyszyn and Keeler, Determinantal thinning of point processes 39 | % with network learning applications, 2018. 40 | 41 | function [L,SMatrix]=funNeighbourL(Total_power,link_distance,tr_loc,rec_loc,diskradius,choiceKernel,sigma,theta) 42 | theta=theta(:); 43 | 44 | alpha=1; %an additional parameter for the Cauchy kernel 45 | 46 | %START - Creation of L matrix 47 | sizeL=size(Total_power,1); %width/height of L (ie cardinality of state space) 48 | %START -- Create q (ie quality feature/covariage) vector 49 | % theta = [theta0,theta1,theta2] ? 50 | %zeroth term 51 | thetaFeature=theta(1)*ones(sizeL,1); 52 | 53 | 54 | 55 | % Serving_power = diag(Total_power); %%%% First feature 56 | % thetaFeature=thetaFeature ... 57 | % +sum(theta(2).*Serving_power,2)./10; %%%%% ADDING some regularization here to make values stable 58 | % 59 | dummy = Total_power; 60 | dummy(logical(eye(size(Total_power))))=-999; 61 | dummy_sort = sort(dummy,2,'descend'); 62 | Best_interference_power = dummy_sort(1); %%%% check this line % I think the max will operate on rows 63 | thetaFeature=thetaFeature ... 64 | +sum(theta(2).*Best_interference_power,2); %%ADDING some regularization here to make values stable 65 | 66 | Best_2_interference_power = dummy_sort(2); %%%% check this line % I think the max will operate on rows 67 | thetaFeature=thetaFeature ... 68 | +sum(theta(3).*Best_2_interference_power,2); 69 | 70 | qVector=exp(thetaFeature/100); %find q vector (ie feature/covariate values) 71 | %END -- Create q vector 72 | 73 | %START - Create similarity matrix S 74 | % if sigma~=0 75 | % %all squared distances of x/y difference pairs 76 | %rrDiffSquared=link_distance.^2; 77 | %rrDiffSquared = rrDiffSquared+ rrDiffSquared'; 78 | xxDiff=bsxfun(@minus,tr_loc(:,1),tr_loc(:,1)'); yyDiff=bsxfun(@minus,tr_loc(:,2),tr_loc(:,2)'); 79 | ttDiffSquared=(xxDiff.^2+yyDiff.^2)./diskradius^2; 80 | 81 | xxDiff=bsxfun(@minus,rec_loc(:,1),rec_loc(:,1)'); yyDiff=bsxfun(@minus,rec_loc(:,2),rec_loc(:,2)'); 82 | rrDiffSquared=(xxDiff.^2+yyDiff.^2)./diskradius^2; 83 | if choiceKernel==1 84 | % %%Gaussian kernel 85 | SMatrix=(1./1)*exp(-(ttDiffSquared+rrDiffSquared)/sigma^2); 86 | elseif choiceKernel==2 87 | % 88 | % %%Cauchy kernel 89 | SMatrix=1./(1+(ttDiffSquared+rrDiffSquared)/sigma^2).^(alpha+1/2); 90 | % end 91 | else 92 | SMatrix=eye(sizeL); 93 | end 94 | 95 | % v_mat = Total_power'; 96 | % v_mat_mag = sqrt(sum(v_mat.^2)); 97 | % M = repmat(v_mat_mag,size(v_mat,1),1); 98 | % v_mat_norm = v_mat./M; 99 | % SMatrix = v_mat_norm'*v_mat_norm; 100 | %repmat(sqrt(diag(v_mat*v_mat')),1,size(v_mat,2)) 101 | % v_mat = v_mat./repmat(sqrt(diag(v_mat*v_mat')),1,size(v_mat,2)); 102 | % SMatrix = abs(v_mat*v_mat'); % getting rid of the sign 103 | 104 | 105 | %SMatrix = 0.5 * (SMatrix + transpose(SMatrix)); 106 | %END - Create similarity matrix S with Gaussian kernel 107 | 108 | %START Create L matrix 109 | qMatrix=repmat(qVector',size(SMatrix,1),1); %q diagonal matrix 110 | L=(qMatrix').*SMatrix.*qMatrix; 111 | %END Create L matrix 112 | 113 | end -------------------------------------------------------------------------------- /funSimulateNetworkBinPowerlevel.m: -------------------------------------------------------------------------------- 1 | function [H,link_distance,tr_loc,rec_loc,S_max,maxrate] = funSimulateNetworkBinPowerlevel(N,diskRadius,N0,alpha,link_dist,mode) 2 | GenerateNewTopology = 1; 3 | % % Drop few transreceivers 4 | %N = 12; % number of links in network 5 | %diskRadius = 50; 6 | if GenerateNewTopology ==1 7 | randangle = 2*pi*rand(N,1); 8 | randradius = (diskRadius/7)*sqrt(rand(N,1)); 9 | tr_loc = [randradius.*cos(randangle),randradius.*sin(randangle)]; 10 | randorient = 2*pi*rand(N,1); 11 | rec_loc = [tr_loc(:,1)+link_dist.*cos(randorient),tr_loc(:,2)+link_dist.*sin(randorient)]; 12 | % TWO clusters 13 | % tr_loc(1:N/2,1)= tr_loc(1:N/2,1)+diskRadius/2; 14 | % tr_loc(N/2+1:N,1)= tr_loc(N/2+1:N,1)-diskRadius/2; 15 | % rec_loc(1:N/2,1)= rec_loc(1:N/2,1)+diskRadius/2; 16 | % rec_loc(N/2+1:N,1)= rec_loc(N/2+1:N,1)-diskRadius/2; 17 | % Three clusters 18 | % randangle = 2*pi*rand(N,1); 19 | % randradius = (diskRadius/7)*sqrt(rand(N,1)); 20 | % tr_loc = [randradius.*cos(randangle),randradius.*sin(randangle)]; 21 | % randorient = 2*pi*rand(N,1); 22 | % rec_loc = [tr_loc(:,1)+link_dist.*cos(randorient),tr_loc(:,2)+link_dist.*sin(randorient)]; 23 | % % 24 | % tr_loc(1:N/3,1)= tr_loc(1:N/3,1)+diskRadius/2; 25 | % tr_loc(N/3+1:2*N/3,1)= tr_loc(N/3+1:2*N/3,1)-diskRadius/2; 26 | % tr_loc(2*N/3+1:N,2)= tr_loc(2*N/3+1:N,2)+diskRadius/2; 27 | % % 28 | % rec_loc(1:N/3,1)= rec_loc(1:N/3,1)+diskRadius/2; 29 | % rec_loc(N/3+1:2*N/3,1)= rec_loc(N/3+1:2*N/3,1)-diskRadius/2; 30 | % rec_loc(2*N/3+1:N,2)= rec_loc(2*N/3+1:N,2)+diskRadius/2; 31 | 32 | % save Topology; 33 | else 34 | load Topology; 35 | end 36 | % figure; 37 | % hold on; 38 | % for linkcount = 1:N 39 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',1); 40 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',1,'MarkerFaceColor','blue'); 41 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',1,'MarkerFaceColor','red'); 42 | % end 43 | %keyboard; 44 | % figure; 45 | % axis square; 46 | % for linkcount = 1:N 47 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',1); 48 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','blue'); 49 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','red'); 50 | % end 51 | % 52 | % plot([tr_loc(:,1)';rec_loc(:,1)'],[tr_loc(:,2)';rec_loc(:,2)'],'k'); 53 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | % Channel Generation %% 55 | H = ones(N,N);% randn(N,N)+1j*randn(N,N); % generate complex gaussian channel 56 | % make H symmetric 57 | %H = triu(H); 58 | %H = H + transpose(H); 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | % figure 61 | % alpha = 1; 62 | % hold on; 63 | % for linkcount = 1:N 64 | % patchline([tr_loc(linkcount,1)';rec_loc(linkcount,1)'],[tr_loc(linkcount,2)';rec_loc(linkcount,2)'],'edgecolor','k','edgealpha',0.2); 65 | % scatter(tr_loc(linkcount,1),tr_loc(linkcount,2),'filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','blue'); 66 | % scatter(rec_loc(linkcount,1),rec_loc(linkcount,2),'ro','filled','MarkerFaceAlpha',3/8,'MarkerFaceColor','red'); 67 | % end 68 | % box on; 69 | % axis('square'); 70 | %H = exprnd(1,N,N); 71 | link_distance= pdist2(rec_loc,tr_loc,'euclidean'); % link_distance(i,j) = ||Tr(j)- Rx(i)|| i.e. Row i corresponds to all distances from Txs to Rec i 72 | if strcmp(mode,'search') 73 | for iteration = 1: 2^N-1 74 | S = decimalToBinaryVector(iteration,N); 75 | S(S==0) = (0.01); % assign lower transmit power 76 | % H_eff = (S'*S).*H; 77 | % delete zero rows and columns 78 | %H_eff( all(~abs(H_eff),2), : ) = []; 79 | %H_eff(:, all(~abs(H_eff),1), : ) = []; 80 | % link_distance_eff = link_distance; 81 | % pathloss = link_distance_eff.^(-alpha/2); 82 | % h = H_eff.*pathloss; 83 | % Total_power = diag(h*h'); 84 | % serving_power=diag((abs(h).^2)); 85 | % interference = Total_power-serving_power; 86 | % %% sanity check 87 | % if sum(interference<0)&& sum(S==1)>1 88 | % keyboard; 89 | % end 90 | % SINR = serving_power./(N0+interference); 91 | P_alloc = S; 92 | SINR = funComputesinr(link_distance,P_alloc',N0,alpha); 93 | %logsumrate(iteration) = sum(log(log2(1+SINR))); 94 | sumrate(iteration) = sum(log2(1+SINR)); 95 | end 96 | % find maximum 97 | %[maxrate,maxindex] = max(logsumrate); 98 | [maxrate,maxindex] = max(sumrate); 99 | S_max = decimalToBinaryVector(maxindex,N); 100 | S_max = S_max>0; 101 | else 102 | S_max = []; 103 | maxrate = []; 104 | end 105 | 106 | 107 | -------------------------------------------------------------------------------- /generateTrainingSet.m: -------------------------------------------------------------------------------- 1 | clear all;close all; 2 | parameters; 3 | %N = poissrnd(N_av); 4 | for tt = 1:T 5 | N = poissrnd(N_av); 6 | [link_distance,tr_loc,rec_loc,S_max,maxrate] = funGenerateNetwork(N,diskradius); 7 | %TrainingData.H = H; 8 | TrainingData.link_distance = link_distance; 9 | TrainingData.S_max = S_max; 10 | TrainingData.tr_loc = tr_loc; 11 | TrainingData.rec_loc = rec_loc; 12 | TrainingData.maxrate = maxrate; 13 | TrainingDataSet{tt} = TrainingData; 14 | fprintf('\ncompleted %f percent',tt/T*100); 15 | end 16 | 17 | save('TrainingData','TrainingDataSet','diskRadius'); -------------------------------------------------------------------------------- /greedyMAP.m: -------------------------------------------------------------------------------- 1 | % Approximates the MAP of the specified DPP by starting from the empty set 2 | % and iteratively adding the next best element to the selected set. This 3 | % is the greedy algorithm of Nemhauser and Wolsey (1978). See readme.txt 4 | % in this folder for a description of inputs and output. 5 | function C = greedyMAP(L, varargin) 6 | nvars = numel(varargin); 7 | assert(nvars == 0 || nvars == 1); 8 | 9 | % Greedily add elements one at a time. 10 | C = []; 11 | N = size(L, 1); 12 | U = 1:N; 13 | num_left = N; 14 | while numel(U) > 0 15 | % Compute the determinant with each remaining unused element added to 16 | % the chosen set. 17 | scores = diag(L); 18 | 19 | % Select the max-scoring addition to the chosen set. 20 | [max_score, max_loc] = max(scores); 21 | if max_score < 1 22 | break; 23 | end 24 | C = [C; U(max_loc)]; 25 | U(max_loc) = []; 26 | 27 | % Compute the new kernel, conditioning on the current selection. 28 | inc_ids = [1:max_loc-1 max_loc+1:num_left]; 29 | L = inv(L + diag([ones(max_loc - 1, 1); 0; ones(num_left - max_loc, 1)])); 30 | num_left = num_left - 1; 31 | L = inv(L(inc_ids, inc_ids)) - eye(num_left); 32 | 33 | % If enforcing 1:1, throw away any unchosen pairs that would now 34 | % violate 1:1 if chosen. 35 | if nvars == 1 36 | chosen_uv = uv(:, max_loc); 37 | uv(:, max_loc) = []; 38 | violators = find((uv(1, :) == chosen_uv(1)) | (uv(2, :) == chosen_uv(2))); 39 | U(violators) = []; 40 | uv(:, violators) = []; 41 | L(violators, :) = []; 42 | L(:, violators) = []; 43 | num_left = num_left - numel(violators); 44 | end 45 | end 46 | 47 | % The below code is slow due to the need to compute many determinants; 48 | % while it often improves the return value of this function, it still does 49 | % not allow greedy to beat softmax probability-wise, and comes with a high 50 | % efficiency penalty. 51 | % 52 | % % In the unconstrained case, we can also try greedily deleting elements. 53 | % if nvars == 1 54 | % return; 55 | % end 56 | % C_up = C; 57 | % C = 1:N; 58 | % prev_score = det(L_saver); 59 | % scores = zeros(N, 1); 60 | % while numel(C) > 0 61 | % for i = 1:numel(C) 62 | % proposal = C([1:i-1 i+1:end]); 63 | % scores(i) = det(L_saver(proposal, proposal)); 64 | % end 65 | % 66 | % [max_score, max_loc] = max(scores); 67 | % if max_score <= prev_score 68 | % break; 69 | % end 70 | % prev_score = max_score; 71 | % C = C([1:max_loc-1 max_loc+1:end]); 72 | % end 73 | % 74 | % if det(L_saver(C_up, C_up)) > prev_score 75 | % C = C_up; 76 | % end 77 | -------------------------------------------------------------------------------- /greedy_lazy.m: -------------------------------------------------------------------------------- 1 | function X = greedy_lazy(A) 2 | N = size(A,1); 3 | deltas = inf * ones(1,N); 4 | X = []; 5 | Y = 1:N; 6 | i = 0; 7 | cg_iter = 30; 8 | while 1 9 | i = i + 1; 10 | bestimprov = 0; 11 | [~,order] = sort(deltas,'descend'); 12 | for test = order 13 | if ismember(Y(test), X) 14 | deltas(test) = -inf; 15 | end 16 | if deltas(test) >= bestimprov 17 | improv = logdet_margin_cg(A,X,Y(test),cg_iter); 18 | deltas(test) = improv; 19 | bestimprov = max(bestimprov, improv); 20 | elseif deltas(test) > -inf 21 | break; 22 | end 23 | end 24 | argmax = find(deltas == max(deltas),1); 25 | if deltas(argmax) >= 0 26 | X = [X Y(argmax)]; 27 | else 28 | break; 29 | end 30 | end 31 | end 32 | 33 | 34 | -------------------------------------------------------------------------------- /greedy_sym.m: -------------------------------------------------------------------------------- 1 | % Approximates the MAP of the specified DPP by starting from the empty set 2 | % and iterating *once* through the items, adding as specified in Buchbinder 3 | % et al. (2012). See readme.txt in this folder for a description of inputs 4 | % and output. 5 | function S = greedy_sym(L) 6 | % Initialize. 7 | N = size(L,1); 8 | S = []; 9 | 10 | % Iterate through items. 11 | for i = 1:N 12 | lift0 = obj(L,[S i]) - obj(L,S); 13 | lift1 = obj(L,[S (i+1):N]) - obj(L,[S i:N]); 14 | 15 | if lift0 > lift1 16 | S = [S i]; 17 | end 18 | end 19 | 20 | function f = obj(L, S) 21 | f = log(det(L(S, S))); -------------------------------------------------------------------------------- /parameters.m: -------------------------------------------------------------------------------- 1 | % This file contains all the necessary parameter values of the network 2 | 3 | % path-loss coefficient 4 | alpha = 2; 5 | % Radius of simulation disc 6 | diskradius = 10; 7 | % Chooses the Gaussian kernel for the S matrix 8 | choiceKernel =1; 9 | % Noise variance 10 | N0 = 0.0005; 11 | % Average number of links 12 | N_av = 20; 13 | % link distance 14 | link_dist =1; -------------------------------------------------------------------------------- /sample_dpp.m: -------------------------------------------------------------------------------- 1 | function Y = sample_dpp(L,k) 2 | % sample a set Y from a dpp. L is a decomposed kernel, and k is (optionally) 3 | % the size of the set to return. 4 | 5 | if ~exist('k','var') 6 | % choose eigenvectors randomly 7 | D = L.D ./ (1+L.D); 8 | v = find(rand(length(D),1) <= D); 9 | else 10 | % k-DPP 11 | v = sample_k(L.D,k); 12 | end 13 | k = length(v); 14 | V = L.V(:,v); 15 | 16 | % iterate 17 | Y = zeros(k,1); 18 | for i = k:-1:1 19 | 20 | % compute probabilities for each item 21 | P = sum(V.^2,2); 22 | P = P / sum(P); 23 | 24 | % choose a new item to include 25 | Y(i) = find(rand <= cumsum(P),1); 26 | 27 | % choose a vector to eliminate 28 | j = find(V(Y(i),:),1); 29 | Vj = V(:,j); 30 | V = V(:,[1:j-1 j+1:end]); 31 | 32 | % update V 33 | V = V - bsxfun(@times,Vj,V(Y(i),:)/Vj(Y(i))); 34 | 35 | % orthogonalize 36 | for a = 1:i-1 37 | for b = 1:a-1 38 | V(:,a) = V(:,a) - V(:,a)'*V(:,b)*V(:,b); 39 | end 40 | V(:,a) = V(:,a) / norm(V(:,a)); 41 | end 42 | 43 | end 44 | 45 | Y = sort(Y); -------------------------------------------------------------------------------- /trainDPP.m: -------------------------------------------------------------------------------- 1 | % Author: Chiranjib Saha and Harpreet S. Dhillon 2 | % Main code for "Machine Learning meets Stochastic Geometry: 3 | % Determinantal Subset Selection for Wireless Networks" 4 | 5 | 6 | % Train the DPP model 7 | %%%%%%%%%%%%%%%%%%%%% 8 | 9 | clear all; close all; 10 | addpath(genpath('.\DataSet\')); 11 | parameters; 12 | % load the training data 13 | load TrainingDataSingleClusters; 14 | 15 | % Set the size of the training set 16 | T =50; 17 | TrainingCollection = {TrainingDataSet{1:T}}; 18 | 19 | 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | booleOptSigma = 1; % this option enables the parameterization of S 22 | theta = [1,1,1]; 23 | sigma = 1; 24 | param = [theta, sigma]; 25 | funMax_theta=@(param)funLikelihood_data(T,TrainingCollection,diskradius,choiceKernel,param,alpha); 26 | funMin=@(theta)(-1*funMax_theta(theta)); %define function to be minimized 27 | 28 | % Initial values of the parameters 29 | if choiceKernel==3 30 | thetaGuess = [10,1,1]; 31 | else 32 | thetaGuess = [10,1,1,1]; 33 | end 34 | 35 | options=optimset('Display','iter'); %options for fminsearch 36 | thetaMax=fminunc(funMin,thetaGuess,options); %minimize function 37 | 38 | if booleOptSigma 39 | sigma=thetaMax(end); %retrive sigma values from theta 40 | thetaMax=thetaMax(1:end-1); 41 | end 42 | % Display the trained parameters 43 | sigma 44 | thetaMax 45 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 46 | % End of DPP training%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47 | % learn the activation probability 48 | p_a_1= 0; 49 | p_a_2 = 0; 50 | for tt = 1: T 51 | p_a_1 = p_a_1+ TrainingCollection{tt}.S_max(1); 52 | p_a_2 = p_a_2+TrainingCollection{tt}.S_max(end); 53 | end 54 | p_a_1 = p_a_1/T; 55 | p_a_2 = p_a_2/T; 56 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 57 | 58 | 59 | %% Start of Testing %% 60 | load('TrainingDataSingleClustersPart2.mat'); 61 | TestSet = TrainingDataSet; 62 | numbSim =size(TestSet,2); 63 | for ss=1:numbSim 64 | % Read the dataset %% 65 | link_distance = TestSet{ss}.link_distance; 66 | tr_loc = TestSet{ss}.tr_loc; 67 | rec_loc = TestSet{ss}.rec_loc; 68 | S_max = TestSet{ss}.S_max; 69 | maxrate = TestSet{ss}.maxrate; 70 | N = size(TestSet{ss}.link_distance,2); 71 | %%%%%%%%%%%%%%%%%%%%%% 72 | Total_power= (link_distance.^(-alpha/2)).^2; 73 | [L,~] = funNeighbourL(Total_power,link_distance,tr_loc,rec_loc,diskradius,choiceKernel,sigma,thetaMax); 74 | S = sample_dpp(decompose_kernel(L)); 75 | 76 | P_alloc_DPP_sample = 0.01*ones(1,N); 77 | P_alloc_DPP_sample(S) = 1; 78 | 79 | 80 | SINR = funComputesinr(link_distance,P_alloc_DPP_sample',N0,alpha); 81 | sumrate_Random_DPP(ss) = sum(log2(1+SINR)); 82 | 83 | S_MAP = greedy_sym(L); 84 | P_alloc_MAP = 0.01*ones(1,N); 85 | P_alloc_MAP(S_MAP) = 1; 86 | SINR = funComputesinr(link_distance,P_alloc_MAP',N0,alpha); 87 | sumrate_MAP(ss) = sum(log2(1+SINR)); 88 | 89 | S = rand(1,N)