Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
91 lines
2.1 KiB
Matlab
Executable File
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;
|
|
|
|
|