Files
openairinterface5g/openair1/EMOS/MATLAB/MAC_to_BC/waterfill_block.m
T
2013-06-25 09:05:02 +00:00

91 lines
2.1 KiB
Matlab
Executable File

%Block Diagonal Waterfilling
%Authors: Nihar Jindal, Wonjong Rhee, Sriram Vishwanath, Syed Jafar, Andrea
%Goldsmith
%Date: 6/20/05
function [capacity, Ex] = waterfill_block(H, P);
%Returns optimal covariance matrix and capacity for
%block diagonal channel H, where H(:,:,1) is first channel, H(:,:,2) is 2nd
%etc.
%Function Inputs
%H: triply indexed channel
% H(:,:,k) refers to the UPLINK channel of the kth receiver
% H(:,:,k) is an (M x N) matrix
%P: power in linear units
%Function Outputs
%capacity: Capacity in bps/Hz
%Ex: triply indexed matrices containing the capacity achieving
% covariance matrices
% Ex(:,:,k) is the (N x N) covariance of user k
%Other Variables
%M: # of base station antennas in downlink channel
%N: # of terminal antennas in downlink channel
[M,N,K] = size(H);
for index = 1:K
%Perform SVD of channel
v = svd(H(:,:,index)' * H(:,:,index));
%Create vector with all singular values
if (index == 1)
s = v;
else
s = [s; v];
end;
end;
channels = length(s);
s = real(s);
%Eliminate zeroes
s = max(s, 1e-10);
noise_vector = 1./s;
unsortedN = noise_vector;
%Put noise variances in increasing order
noise_vector = sort(noise_vector);
last = channels; %index of worst channel allocated non-zero power
loop = 1;
%Find channels allocated non-zero power
while (loop)
water = noise_vector(last); %water level
power = sum(max(water - noise_vector, 0));
if (power > P)
last = last - 1;
else
loop = 0;
end;
end;
%Calculate optimal water level
water = 1/last * (P + sum(noise_vector(1:last)));
capacity = 0;
Ex = zeros(N,N,K);
%Compute covariance matrix for each user
for index = 1:K
%Take svd of channel
[u,v,w] = svd(H(:,:,index)' * H(:,:,index));
s = svd(H(:,:,index)' * H(:,:,index));
s = real(s);
%eliminate zeroes
s = max(s, 1e-10);
noise_vector = 1./s;
Ex(:,:,index) = u * diag(max((water- noise_vector),0)) * u';
capacity = capacity + real(log2(det(eye(M) + H(:,:,index) *Ex(:,:,index)* H(:,:,index)')));
end;