├── OFDM.m └── waterfilling.m /OFDM.m: -------------------------------------------------------------------------------- 1 | %% Characteristics & Transmitter 2 | c =[1 1]; 3 | N = length(c); 4 | L=512; % Subcarriers 5 | P0 = 1000; % Transmit power 6 | Lx = 100; % simulate Lx blocks 7 | G = abs(fft(c,L)); % L point FFT of channel 8 | SNR = (G.^2); % SNR for a channel, with noise variance 1. 9 | D = waterfilling(SNR,P0); 10 | Diag = diag(D); 11 | T = dftmtx(L)/sqrt(L); % L-point DFT matrix, scaled to be unitary 12 | x = randn(1,L*Lx); XX = zeros(L,Lx); % signal 13 | XX(:) = x; % demultiplex 14 | XX2 = Diag*XX; 15 | X = T'*XX2; % IDFT 16 | S = [X(end-N+2:end,:); X]; % cyclic prefix 17 | s = S(:); % multiplex 18 | %% Noisy and Dispersive Channel 19 | v = 0.0 * (randn(Lx*(L+N-1),1) + 1i*randn(Lx*(L+N-1),1))/sqrt(2); 20 | r = filter(c,1,s) + v; % transmission over channel 21 | %% OFDM Receiver and Equaliser 22 | R= zeros(L+N-1,Lx); 23 | R(:) = r; % demultiplex 24 | R2 = T*R(N:end,:); % prefix removal and DFT 25 | S_hat = pinv(Diag)*pinv(diag(fft(c,L)))*R2; % ZF equalisation 26 | %% MSE 27 | for i= 1:Lx, 28 | MSE(:,i) = sum((S_hat(:,i) - XX(:,i)).^2)/L; 29 | end 30 | -------------------------------------------------------------------------------- /waterfilling.m: -------------------------------------------------------------------------------- 1 | function D = waterfilling(SNR,P0); 2 | % D = waterfilling(SNR,P0); 3 | % 4 | % Perform waterfilling to maximise the capacity of a system with 5 | % subchannels with given SNRs under a constraint P0 for the transmit 6 | % power. 7 | % 8 | % Input parameters: 9 | % SNR column vector of subchannel SNRs 10 | % P0 total transmit power budget 11 | % 12 | % Output parameter: 13 | % D column vector containing optimised subchannel gains 14 | % applicable at the transmitter's precoder. 15 | % 16 | % S. Weiss, UoS, 2/5/2007 17 | 18 | L = length(SNR); % number of subchannels 19 | epsilon = 10^(-14); % avoid division by zero 20 | 21 | % order the inverse subchannel SNRs from smallest to largest 22 | [SNRinv,Index] = sort(1./(SNR+epsilon)); 23 | 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | % part 1: 26 | % determine how many subchannels K<=L can be supported 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | K=L; % first consider taking all (K=L) subchannels 29 | mu = SNRinv(K); 30 | P = sum(mu-SNRinv); 31 | while (P>P0), 32 | K=K-1; 33 | mu = SNRinv(K); 34 | P = sum((mu-SNRinv).*((mu-SNRinv)>0)); 35 | end; 36 | % K now contains the number of subchannels that can be "covered by 37 | % water" (i.e. utilised for transmission) 38 | 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | % part 2: 41 | % P is the power required to service the K strongest subchannels, 42 | % i.e. water just reaches up to the Kth subchannel. 43 | % The remaining (P0-P) is uniformly poored across these K subchannels. 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | mu = mu + (P0-P)/K; 46 | SNRinv = SNRinv(:); % enforce column vector 47 | D2 = max(zeros(L,1), mu-SNRinv); 48 | 49 | % turn power into gain and re-order subchannels 50 | D(Index) = sqrt(D2); 51 | --------------------------------------------------------------------------------