Useful Codes
Useful Codes
Useful Codes
*********************************
OFDM LSE Channel Estimation
by Hamid Ramezani
26 Nov 2006 (Updated 01 Apr 2016)
the performance of LSE channel estimation will be evaluated based on bit error r
ate in received data
-----------------------------------------------------------------------------------------------------------% in this Mfile, I want to investigate the performance of LSE algorithm in
% OFDM channel estimation
%
% for further information see the
%
[Xiaodong Cai and Georgios B. Giannakis,
%
Error Probability Minimizing Pilots for
%
OFDM with M-PSK Modulation over Rayliegh-Fading
%
Channels, IEEE Transactions on Vehicular
%
technology, vol. 53, No. 1, pp 146-155, Jan. 2004.]
% initialize
clear
clc
% parameter definition
N = 256;
P = 256/8;
S = N-P;
GI = N/4;
M = 2;
pilotInterval = 8;
L = 16;
nIteration = 500;
%
%
%
%
%
%
%
% location of pilots
% location of data
% energy in pilot symbols in comparison
% to energy in data symbols
% fft matrix
F = exp(2*pi*sqrt(-1)/N .* meshgrid([0:N-1],[0:N-1])...
.* repmat([0:N-1]',[1,N]));
for( i = 1 : length(SNR_V))
SNR = SNR_V(i)
for(k = 1 : nIteration)
% generating random channel coefficients
h(1:L,1) =
random('Normal',0,1,L,1) + ...
j * random('Normal',0,1,L,1);
h = h./sum(abs(h));
% normalization
% Tr Data
TrDataBit = randint(N,1,M);
TrDataMod = qammod(TrDataBit,M);
TrDataMod(Ip) = Ep * TrDataMod(Ip);
TrDataIfft = ifft(TrDataMod,N);
TrDataIfftGi = [TrDataIfft(N- GI + 1 : N);TrDataIfft];
% tx Data
TxDataIfftGi = filter(h,1,TrDataIfftGi);
% channel effect
% adding awgn noise
TxDataIfftGiNoise = awgn(TxDataIfftGi ...
, SNR - db(std(TxDataIfftGi))); % normalization to signal power
TxDataIfft = TxDataIfftGiNoise(GI+1:N+GI);
TxDataMod = fft(TxDataIfft,N);
% Channel estimation
Spilot = TrDataMod(Ip); % trnasmitted pilots
Ypilot = TxDataMod(Ip); % received pilots
G = (Ep * length(Ip))^-1 ...
* ctranspose(sqrt(Ep)*diag(Spilot)*ctranspose(F(1:L,Ip)));
hHat = G*Ypilot;
TxDataBit
= qamdemod(TxDataMod./(fft(hHat,N)),M);
F = dftmtx(nFFT)/sqrt(nFFT);
MC = 1500;
EsNodB = 0:5:40;
snr = 10.^(EsNodB/10);
beta = 17/9;
M = 16;
modObj = modem.qammod(M);
demodObj = modem.qamdemod(M);
L = 5;
ChEstLS = zeros(1,length(EsNodB));
ChEstMMSE = zeros(1,length(EsNodB));
TD_ChEstMMSE = zeros(1,length(EsNodB));
TDD_ChEstMMSE = zeros(1,length(EsNodB));
TDQabs_ChEstMMSE = zeros(1,length(EsNodB));
for ii = 1:length(EsNodB)
disp('EsN0dB is :'); disp(EsNodB(ii));tic;
ChMSE_LS = 0;
ChMSE_LMMSE=0;
TDMSE_LMMSE =0;
TDDMSE_LMMSE=0;
TDQabsMSE_LMMSE =0;
for mc = 1:MC
% Random channel taps
g = randn(L,1)+1i*randn(L,1);
g = g/norm(g);
H = fft(g,nFFT);
% generation of symbol
X = randi([0 M-1],nFFT,1); %BPSK symbols
XD = modulate(modObj,X)/sqrt(10); % normalizing symbol power
x = F'*XD;
xout = [x(nFFT-nCP+1:nFFT);x];
% channel convolution and AWGN
y = conv(xout,g);
nt =randn(nFFT+nCP+L-1,1) + 1i*randn(nFFT+nCP+L-1,1);
No = 10^(-EsNodB(ii)/10);
y = y + sqrt(No/2)*nt;
% Receiver processing
y = y(nCP+1:NT);
Y = F*y;
% frequency doimain LS channel estimation
HhatLS = Y./XD;
ChMSE_LS = ChMSE_LS + ((H -HhatLS)'*(H-HhatLS))/nFFT;
% Frequency domain LMMSE estimation
Rhh = H*H';
W = Rhh/(Rhh+(beta/snr(ii))*eye(nFFT));
HhatLMMSE = W*HhatLS;
ChMSE_LMMSE = ChMSE_LMMSE + ((H -HhatLMMSE)'*(H-HhatLMMSE))/nFFT;
% Time domain LMMSE estimation
ghatLS = ifft(HhatLS,nFFT);
Rgg = g*g';
WW = Rgg/(Rgg+(beta/snr(ii))*eye(L));
ghat = WW*ghatLS(1:L);
TD_HhatLMMSE = fft(ghat,nFFT);%
TDMSE_LMMSE = TDMSE_LMMSE + ((H -TD_HhatLMMSE)'*(H-TD_HhatLMMSE))/nFFT;
clear
close all
clc
randn('seed',1214)
rand('seed',12524)
%
%
%
%
%
% ofdm parameters
ofdm.N = 128;
% number of subcarriers
ofdm.B = 1;
% number of block in each channel realiz
ation
ofdm.M = 4;
% Modulation order (M=4)
ofdm.T = 1e-7;
% OFDM sample time
ofdm.GI = 16;
% length of gaurd interval
ofdm.TS = ofdm.N*ofdm.T;
% OFDM symbol time (not considering gaur
d interval)
ofdm.TT = (ofdm.N+ofdm.GI)*ofdm.T; % OFDM symbol time (considering gaurd in
terval)
ofdm.PP = 1:10:ofdm.N;
% Pilot locations in the subcarriers
ofdm.DP = setxor(1:ofdm.N,ofdm.PP);% Data locations in the subcarriers
ofdm.NP = length(ofdm.PP);
% number subcarriers which carry data
% channel parameters
chan.L
= 3;
chan.fd
= .1;
chan.Nt
= 128;
ictionary
chan.Gain = (0:1/(chan.Nt):1)*0;
[~,chan.Delay] = sort([0,rand(1,chan.Nt)]);
r each ta[
chan.snrdB = 15;
tion
chan.snrdBV = 5:2:30;
tion for sweep
% loop parameters
loop.End1 = 1e2;
loop.End2 = length(chan.snrdBV);
loop.Sparse = zeros(loop.End1,loop.End2);
BER using sparse method
loop.LSE
= zeros(loop.End1,loop.End2);
BER using LSE method
% number of iterations
% length of inner loop
% memory allocation for the
% memory allocation for the
% building dictionary (please check different papers to learn how to build the d
ictionary)
chan.tau_p = linspace(0,ofdm.GI*ofdm.T - ofdm.GI*ofdm.T./chan.Nt,chan.Nt);
chan.Gamma = exp(-sqrt(-1)*2*pi.*repmat(((1:ofdm.N).'),1,chan.Nt)./ofdm.TS.*
repmat(chan.tau_p,ofdm.N,1));
% fft matrix for LSE estimation (please check the following link for LSE channel
estimation :
% http://www.mathworks.com/matlabcentral/fileexchange/13127-ofdm-lse-channel-est
imation )
F = exp(2*pi*sqrt(-1)/ofdm.N .* meshgrid(0:ofdm.N-1,0:ofdm.N-1)...
.* repmat((0:ofdm.N-1)',[1,ofdm.N]));
%% Loop
for cnt1 = 1 : loop.End1
for cnt2 = 1 : loop.End2
% loop parameters
chan.snrdB = chan.snrdBV(cnt2);
% Data generation
data = randi([0 ofdm.M-1],ofdm.N,ofdm.B);
% modulation
if ofdm.M == 4
dataMod = qammod(data,ofdm.M)/sqrt(2);
else
error('Not defined')
end
% pilot insertion
ofdm.Pilot = ones(ofdm.NP,1);% or randsrc(ofdm.NP,ofdm.B,[-1 1]).*exp(-s
qrt(-1)*pi*rand(ofdm.NP,ofdm.B));
dataMod(ofdm.PP,:) = ofdm.Pilot;
% ifft operation
dataIFFT = sqrt(ofdm.N)*ifft(dataMod);
% adding gaurd interval
dataIFFTGI = [dataIFFT((ofdm.N-ofdm.GI+1):ofdm.N,:);dataIFFT;];
% channel (rayleigh and gaussian noise)
ch = rayleighchan(ofdm.T,chan.fd,chan.tau_p(chan.Delay(1:chan.L)),chan.G
ain(chan.Delay(1:chan.L)));
dataChann = awgn(filter(ch,dataIFFTGI(:)),chan.snrdB );
% reshaping the signal
dataChann = reshape(dataChann,ofdm.N+ofdm.GI,ofdm.B);
% Guard interval removal
dataRx
= dataChann((ofdm.GI+1):(ofdm.N+ofdm.GI),:);
% ofdm demodulation
dataRxFFT =1/sqrt(ofdm.N)*fft(dataRx);
%% Saprse Channel estimation
H_Sparse = zeros(ofdm.N,ofdm.B);
lambda1 = ofdm.NP*10^(-chan.snrdB/10)/sum(abs(ch.pathGains));
for b = 1 : ofdm.B
y = dataRxFFT(ofdm.PP,b);
A = chan.Gamma(ofdm.PP,:).*repmat(ofdm.Pilot(:,b),1,chan.Nt);
cvx_begin quiet
variable x(chan.Nt) complex
% sparse minimization formula (A is built from dictionary, y
is received data and x is the channel coeff at pilot locations)
minimize( quad_form(y-A*x,eye(ofdm.NP))+lambda1*norm(x,1) )
cvx_end
% building channel at all location (simply from the dictionar)
H_Sparse(:,b) = chan.Gamma*x;
end
dataRxMod_Sparse = dataRxFFT(ofdm.DP,:)./H_Sparse(ofdm.DP,:);
dataRxDeMod_Sparse = qamdemod(dataRxMod_Sparse,ofdm.M);
[~,BER_Sparse] = biterr(dataRxDeMod_Sparse,data(ofdm.DP,:),ofdm.M);
%% LSE
H_LSE = zeros(ofdm.N,ofdm.B);
for b = 1 : ofdm.B
H_LSE(:,b) = ofdm.N/ofdm.NP * fft(ifft(dataRxFFT(ofdm.PP,b)./dataMo
d(ofdm.PP,b)),ofdm.N);
end
dataRxMod_LSE = dataRxFFT(ofdm.DP,:)./H_LSE(ofdm.DP,:);
dataRxDeMod_LSE = qamdemod(dataRxMod_LSE,ofdm.M);
[~,BER_LSE] = biterr(dataRxDeMod_LSE,data(ofdm.DP,:),ofdm.M);
% saving the output
loop.Sparse(cnt1,cnt2) = BER_Sparse;
loop.LSE(cnt1,cnt2)
= BER_LSE;
end
disp([num2str(round(cnt1/loop.End1*100)),'% has been done'])
end
%% Figure
f1 = figure(1);
semilogy(chan.snrdBV,mean(loop.Sparse,1),'b-o')
hold on
semilogy(chan.snrdBV,mean(loop.LSE,1),'r.-')
hold off
legend('Sparse','LSE')
grid on
********************************************************************************
*********************************************
OFDM Trasnmitter and Receiver (Matlab Code)
by Ihsan Ullah
17 Oct 2009
OFDM code with 16-QAM modulation. Can be easily Understood and modified.
----------------------------------------------------------------------------------------------------------------------% OFDM Code
% Author: Ihsan Ullah,
%
Ms-55 Electrical,
%
College of EME,
%
NUST Pakistan
% No.of Carriers: 64
% coding used: Convolutional coding
% Single frame size: 96 bits
% Total no. of Frames: 100
% Modulation: 16-QAM
% No. of Pilots: 4
% Cylic Extension: 25%(16)
close all
clear all
clc
%%
% Generating and coding data
t_data=randint(9600,1)';
x=1;
si=1; %for BER rows
%%
for d=1:100;
data=t_data(x:x+95);
x=x+96;
k=3;
n=6;
s1=size(data,2); % Size of input matrix
j=s1/k;
%%
% Convolutionally encoding data
constlen=7;
codegen = [171 133];
% Polynomial
trellis = poly2trellis(constlen, codegen);
codedata = convenc(data, trellis);
%%
%Interleaving coded data
s2=size(codedata,2);
j=s2/4;
matrix=reshape(codedata,j,4);
intlvddata = matintrlv(matrix',2,2)'; % Interleave.
intlvddata=intlvddata';
%%
% Binary to decimal conversion
dec=bi2de(intlvddata','left-msb');
%%
%16-QAM Modulation
M=16;
y = qammod(dec,M);
% scatterplot(y);
%%
% Pilot insertion
lendata=length(y);
pilt=3+3j;
nofpits=4;
k=1;
for i=(1:13:52)
pilt_data1(i)=pilt;
for j=(i+1:i+12);
pilt_data1(j)=y(k);
k=k+1;
end
end
pilt_data1=pilt_data1'; % size of pilt_data =52
pilt_data(1:52)=pilt_data1(1:52);
% upsizing to 64
pilt_data(13:64)=pilt_data1(1:52); % upsizing to 64
for i=1:52
pilt_data(i+6)=pilt_data1(i);
end
%%
% IFFT
ifft_sig=ifft(pilt_data',64);
%%
% Adding Cyclic Extension
cext_data=zeros(80,1);
cext_data(1:16)=ifft_sig(49:64);
for i=1:64
cext_data(i+16)=ifft_sig(i);
end
%%
% Channel
% SNR
o=1;
for snr=0:2:50
ofdm_sig=awgn(cext_data,snr,'measured'); % Adding white Gaussian Noise
% figure;
% index=1:80;
% plot(index,cext_data,'b',index,ofdm_sig,'r'); %plot both signals
% legend('Original Signal to be Transmitted','Signal with AWGN');
%%
%
RECEIVER
%%
%Removing Cyclic Extension
for i=1:64
rxed_sig(i)=ofdm_sig(i+16);
end
%%
% FFT
ff_sig=fft(rxed_sig,64);
%%
% Pilot Synch%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:52
synched_sig1(i)=ff_sig(i+6);
end
k=1;
for i=(1:13:52)
for j=(i+1:i+12);
synched_sig(k)=synched_sig1(j);
k=k+1;
end
end
% scatterplot(synched_sig)
%%
% Demodulation
dem_data= qamdemod(synched_sig,16);
%%
% Decimal to binary conversion
bin=de2bi(dem_data','left-msb');
bin=bin';
%%
% De-Interleaving
deintlvddata = matdeintrlv(bin,2,2); % De-Interleave
deintlvddata=deintlvddata';
deintlvddata=deintlvddata(:)';
%%
%Decoding data
n=6;
k=3;
decodedata =vitdec(deintlvddata,trellis,5,'trunc','hard'); % decoding datausing
veterbi decoder
rxed_data=decodedata;
%%
% Calculating BER
rxed_data=rxed_data(:)';
errors=0;
c=xor(data,rxed_data);
errors=nnz(c);
% for i=1:length(data)
%
%
%
if rxed_data(i)~=data(i);
%
errors=errors+1;
%
%
end
% end
BER(si,o)=errors/length(data);
o=o+1;
end % SNR loop ends here
si=si+1;
end % main data loop
%%
% Time averaging for optimum results
for col=1:25;
ber(1,col)=0;
for row=1:100;
ber(1,col)=ber(1,col)+BER(row,col);
end
end
ber=ber./100;
%%
figure
i=0:2:48;
semilogy(i,ber);
title('BER vs SNR');
ylabel('BER');
xlabel('SNR (dB)');
grid on
********************************************************************************
*******************************