├── LS_CE.m ├── MMSE_CE.m ├── README.md ├── interpolate.m └── main.m /LS_CE.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaur1616/Channel-Estimation-OFDM-/bb17daf859473c439deef3812cdeb397e0acc437/LS_CE.m -------------------------------------------------------------------------------- /MMSE_CE.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaur1616/Channel-Estimation-OFDM-/bb17daf859473c439deef3812cdeb397e0acc437/MMSE_CE.m -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Channel-Estimation-OFDM- 2 | -Investigated the efficiency of different estimators to estimate and track channel parameters based on the Mean Squared Error (MSE) performance. The estimators employed in the simulation are LS and MMSE estimators and their performance in the transfer domain was evaluated. -MATLAB was used for the simulation of the communication link and analyzing the error between the estimated channel parameters and actual modeled channel parameters. 3 | -------------------------------------------------------------------------------- /interpolate.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaur1616/Channel-Estimation-OFDM-/bb17daf859473c439deef3812cdeb397e0acc437/interpolate.m -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear all; 3 | close all; 4 | 5 | Nfft=2048; 6 | Ng=512; 7 | Nofdm=2560; 8 | Nsym=100; 9 | Nps=4; %Pilot Spacing 10 | Np=Nfft/Nps; %Number of pilots per OFDM symbol 11 | Nbps=4; 12 | itr=10; 13 | nn=11; %No. of SNR observations 14 | 15 | %Initialising MSE arrays for different SNR observations: 16 | z_linin=zeros(1,nn); 17 | z_splin=zeros(1,nn); 18 | z_lindft=zeros(1,nn); 19 | z_spldft=zeros(1,nn); 20 | zmmse=zeros(1,nn); 21 | zmmse_dft=zeros(1,nn); 22 | 23 | for t=1:itr 24 | z=[]; 25 | z1=[]; 26 | z2=[]; 27 | z3=[]; 28 | zm=[]; 29 | zms=[]; 30 | snr1=[]; 31 | 32 | % 16 - QAM - Modulation Scheme 33 | M=16; 34 | hmod = modem.qammod('M',M, 'SymbolOrder','gray'); 35 | Es=1; 36 | A=sqrt(3/2/(M-1)*Es); % Signal energy and QAM normalization factor 37 | for nsym=1:Nsym 38 | Xp = 2*(randn(1,Np)>0)-1; % Pilot sequence generation 39 | msgint=randi(1,Nfft-Np,M); % bit generation 40 | dat_ser = A*modulate(hmod,msgint); 41 | end 42 | 43 | % serial to parllel conversion 44 | dat_par=dat_ser.'; 45 | 46 | % Pilot Insertion - Comb Type Arrangement 47 | counter = 0; 48 | loc = []; 49 | for i=1:Nfft 50 | if mod(i,Nps)==1 51 | X(i)=Xp(floor(i/Nps)+1); 52 | loc=[loc i]; 53 | counter = counter+1; 54 | else 55 | X(i) = dat_par(i-counter); 56 | end 57 | end 58 | 59 | % inverse discret Fourier transform (IFFT) 60 | X_ifft=ifft(X,Nfft); 61 | 62 | % Adding Cyclic Prefix - Guard interval 63 | guard=X_ifft(:,end-511:end); % this is the Cyclic Prefix part to be appended. 64 | ofdm_par=[guard X_ifft]; 65 | 66 | % parallel to serial - Generation of the OFDM Signal 67 | ofdm=ofdm_par.'; 68 | 69 | % Channel code 70 | dopjakes = doppler.jakes; 71 | 72 | dopgauss1 = doppler.bigaussian; 73 | dopgauss1.CenterFreqGaussian1 = -0.8; 74 | dopgauss1.CenterFreqGaussian2 = 0.4; 75 | dopgauss1.SigmaGaussian1 = 0.05; 76 | dopgauss1.SigmaGaussian2 = 0.1; 77 | dopgauss1.GainGaussian1 = sqrt(2*pi*(dopgauss1.SigmaGaussian1)^2); 78 | dopgauss1.GainGaussian2 = 1/10 * sqrt(2*pi*(dopgauss1.SigmaGaussian2)^2); 79 | 80 | dopgauss2 = doppler.bigaussian; 81 | dopgauss2.CenterFreqGaussian1 = 0.7; 82 | dopgauss2.CenterFreqGaussian2 = -0.4; 83 | dopgauss2.SigmaGaussian1 = 0.1; 84 | dopgauss2.SigmaGaussian2 = 0.15; 85 | dopgauss2.GainGaussian1 = sqrt(2*pi*(dopgauss1.SigmaGaussian1)^2); 86 | dopgauss2.GainGaussian2 = 1/10^1.5 * sqrt(2*pi*(dopgauss1.SigmaGaussian2)^2); 87 | 88 | fd=130; %Maximum Doppler Shift 89 | ts=(7/64)*10^-6; %Sampling Time 90 | 91 | chan = rayleighchan(ts, fd); %Rayleigh channel - Multifading Channel 92 | 93 | % Assign profile-specific properties to channel object. 94 | chan.PathDelays = [0.0 0.2 0.5 1.6 2.3 5.0] * 1e-6; 95 | chan.AvgPathGaindB = [-3 0 -2 -6 -8 -10]; 96 | chan.DopplerSpectrum = [dopjakes dopjakes dopjakes dopgauss1 dopgauss2 dopgauss2]; 97 | chan.StoreHistory = 1; 98 | chan.ResetBeforeFiltering = 0; 99 | chan.NormalizePathGains = 1; 100 | 101 | %Passing OFDM Signal through the created Channel 102 | chan_op = filter(chan,ofdm); 103 | XFG=fft(chan_op); 104 | 105 | %Channel Covariance Matrix for MMSE estimation 106 | x_test=randn(1,6); 107 | X_test=fft(x_test,Nfft); 108 | y_test=filter(chan,x_test); 109 | Y_test=fft(y_test,Nfft); 110 | H1=Y_test/X_test; 111 | h=ifft(H1,6); 112 | H=fft(h,Nfft); 113 | ch_length=length(h); 114 | 115 | %Reception at the receiver end for various SNR ranging from 5dB - 25dB: 116 | for SNR =5:2:25 117 | %AWGN Modelling 118 | snr1=[snr1 SNR]; 119 | n1=ones(2560,1); 120 | n1=n1*0.000000000000000001i;%Just to ensure that the function awgn adds 'complex gaussian noise'.. 121 | noise=awgn(n1,SNR); 122 | variance=var(noise); 123 | N=fft(noise); 124 | 125 | Y_rec=XFG+N; 126 | y_ser=ifft(Y_rec); 127 | 128 | % serial to parallel conversion 129 | y_par=y_ser.'; 130 | 131 | % guard interval 132 | y = y_par(Ng+1:Nofdm); 133 | 134 | % FFT 135 | Y = fft(y); 136 | 137 | % channel estimation 138 | 139 | %LS Estimator with Linear Interpolator 140 | H_est = LS_CE(Y,Xp,loc,Nfft,Nps,'linear'); 141 | err=(H-H_est)*(H-H_est)'; 142 | z=[z err/(Nfft*Nsym)]; 143 | 144 | %LS Estimator with Linear Interpolator - DFT Based 145 | h_est = ifft(H_est); 146 | h_DFT = h_est(1:ch_length); 147 | H_DFT = fft(h_DFT,Nfft); 148 | err=(H-H_DFT)*(H-H_DFT)'; 149 | z3=[z3 err/(Nfft*Nsym)]; 150 | 151 | %LS Estimator with Spline Cubic Interpolator 152 | H_est = LS_CE(Y,Xp,loc,Nfft,Nps,'spline'); 153 | err=(H-H_est)*(H-H_est)'; 154 | z1=[z1 err/(Nfft*Nsym)]; 155 | 156 | %LS Estimator with Spline Cubic Interpolator - DFT Based 157 | h_est = ifft(H_est); 158 | h_DFT = h_est(1:ch_length); 159 | H_DFT = fft(h_DFT,Nfft); 160 | err=(H-H_DFT)*(H-H_DFT)'; 161 | z2=[z2 err/(Nfft*Nsym)]; 162 | 163 | % MMSE Estimator 164 | H_est = MMSE_CE(Y,Xp,loc,Nfft,Nps,h,SNR); 165 | err=(H-H_est)*(H-H_est)'; 166 | zm=[zm err/(Nfft*Nsym)]; 167 | 168 | % MMSE Estimator - DFT Based 169 | h_est = ifft(H_est); 170 | h_DFT = h_est(1:ch_length); 171 | H_DFT = fft(h_DFT,Nfft); 172 | err=(H-H_DFT)*(H-H_DFT)'; 173 | zms=[zms err/(Nfft*Nsym)]; 174 | end 175 | 176 | z_linin=z_linin+z; 177 | z_splin=z_splin+z1; 178 | z_lindft=z_lindft+z2; 179 | z_spldft=z_spldft+z2; 180 | zmmse=zmmse+zm; 181 | zmmse_dft=zmmse_dft+zms; 182 | end 183 | 184 | 185 | figure(1) 186 | semilogy(snr1,(1/itr)*z_linin,'r+:', snr1,(1/itr)*z_splin,'bo:', snr1,(1/itr)*z_lindft,'--xg', snr1,(1/itr)*z_spldft,'--sc'); 187 | legend('LS - Linear Interpolation','LS - Spline Cubic Interpolation','LS - Linear Interpolation(DFT)','LS - Spline Cubic Interpolation(DFT)'); 188 | xlabel('SNR'); 189 | ylabel('MSE'); 190 | grid on 191 | hold on 192 | 193 | figure(2) 194 | semilogy(snr1,(1/itr)*zmmse,'r+:',snr1,(1/itr)*zmmse_dft,'bo:'); 195 | xlabel('SNR'); 196 | ylabel('MSE'); 197 | legend('MMSE','MMSE - DFT Based'); 198 | hold on 199 | grid on 200 | 201 | 202 | figure(3) 203 | semilogy(snr1,(1/itr)*z_linin,'r+:', snr1,(1/itr)*z_splin,'bo:', snr1, (1/itr)*zmmse,'--xg'); 204 | xlabel('SNR'); 205 | ylabel('MSE'); 206 | legend('LS - Linear Interpolation','LS - Spline Cubic Interpolation','MMSE'); 207 | hold on 208 | grid on --------------------------------------------------------------------------------