%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% All rights reserved by Krishna Pillai, http://www.dsplog.com
% The file may not be re-distributed without explicit authorization
% from Krishna Pillai.
% Checked for proper operation with Octave Version 3.0.0
% Author
: Krishna Pillai
% Email
:
[email protected]% Version
: 1.0
% Date
: 05 June 2008
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bit Error Rate for 16-QAM modulation using Gray modulation mapping
clear
N = 10^5; % number of symbols
M = 16;
% constellation size
k = log2(M); % bits per symbol
% defining the real and imaginary PAM constellation
% for 16-QAM
alphaRe = [-(2*sqrt(M)/2-1):2:-1 1:2:2*sqrt(M)/2-1];
alphaIm = [-(2*sqrt(M)/2-1):2:-1 1:2:2*sqrt(M)/2-1];
k_16QAM = 1/sqrt(10);
Eb_N0_dB
Es_N0_dB
= [0:15]; % multiple Es/N0 values
= Eb_N0_dB + 10*log10(k);
% Mapping for binary <--> Gray code conversion
ref = [0:k-1];
map = bitxor(ref,floor(ref/2));
[tt ind] = sort(map);
for ii = 1:length(Eb_N0_dB)
% symbol generation
% -----------------ipBit = rand(1,N*k,1)>0.5; % random 1's and 0's
ipBitReshape = reshape(ipBit,k,N).';
bin2DecMatrix = ones(N,1)*(2.^[(k/2-1):-1:0]) ; % conversion from binary
to decimal
% real
ipBitRe = ipBitReshape(:,[1:k/2]);
ipDecRe = sum(ipBitRe.*bin2DecMatrix,2);
ipGrayDecRe = bitxor(ipDecRe,floor(ipDecRe/2));
% imaginary
ipBitIm = ipBitReshape(:,[k/2+1:k]);
ipDecIm = sum(ipBitIm.*bin2DecMatrix,2);
ipGrayDecIm = bitxor(ipDecIm,floor(ipDecIm/2));
% mapping the Gray coded symbols into constellation
modRe = alphaRe(ipGrayDecRe+1);
modIm = alphaIm(ipGrayDecIm+1);
% complex constellation
mod = modRe + j*modIm;
s = k_16QAM*mod; % normalization of transmit power to one
% noise
% ----n = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % white guassian noise, 0dB
variance
y = s + 10^(-Es_N0_dB(ii)/20)*n; % additive white gaussian noise
% demodulation
% -----------y_re = real(y)/k_16QAM; % real part
y_im = imag(y)/k_16QAM; % imaginary part
% rounding to the nearest alphabet
ipHatRe = 2*floor(y_re/2)+1;
ipHatRe(find(ipHatRe>max(alphaRe)))
ipHatRe(find(ipHatRe<min(alphaRe)))
ipHatIm = 2*floor(y_im/2)+1;
ipHatIm(find(ipHatIm>max(alphaIm)))
ipHatIm(find(ipHatIm<min(alphaIm)))
= max(alphaRe);
= min(alphaRe);
= max(alphaIm);
= min(alphaIm);
% Constellation to Decimal conversion
ipDecHatRe = ind(floor((ipHatRe+4)/2+1))-1; % LUT based
ipDecHatIm = ind(floor((ipHatIm+4)/2+1))-1; % LUT based
% converting to binary string
ipBinHatRe = dec2bin(ipDecHatRe,k/2);
ipBinHatIm = dec2bin(ipDecHatIm,k/2);
% converting
ipBinHatRe =
ipBinHatRe =
ipBinHatRe =
binary string to number
ipBinHatRe.';
ipBinHatRe(1:end).';
reshape(str2num(ipBinHatRe).',k/2,N).' ;
ipBinHatIm = ipBinHatIm.';
ipBinHatIm = ipBinHatIm(1:end).';
ipBinHatIm = reshape(str2num(ipBinHatIm).',k/2,N).' ;
% counting errors for real and imaginary
nBitErr(ii) = size(find([ipBitRe- ipBinHatRe]),1) + size(find([ipBitIm ipBinHatIm]),1) ;
end
simBer = nBitErr/(N*k);
theoryBer = (1/k)*3/2*erfc(sqrt(k*0.1*(10.^(Eb_N0_dB/10))));
close all; figure
semilogy(Eb_N0_dB,theoryBer,'bs-','LineWidth',2);
hold on
semilogy(Eb_N0_dB,simBer,'mx-','LineWidth',2);
axis([0 15 10^-5 1])
grid on
legend('theory', 'simulation');
xlabel('Eb/No, dB')
ylabel('Bit Error Rate')
title('Bit error probability curve for 16-QAM modulation')
M = 16;
k = log2(M);
n = 3e4;
nSyms = n/k;
% Size of signal constellation
% Number of bits per symbol
% Number of bits to process
% Number of symbols
hMod = modem.qammod(M);
% Create a 16-QAM modulator
hMod.InputType = 'Bit';
% Accept bits as inputs
hMod.SymbolOrder = 'Gray';
% Accept bits as inputs
hDemod = modem.qamdemod(hMod); % Create a 16-QAM based on the modulator
x = randi([0 1],n,1); % Random binary data stream
tx = modulate(hMod,x);
EbNo = 0:10; % In dB
SNR = EbNo + 10*log10(k);
rx = zeros(nSyms,length(SNR));
bit_error_rate = zeros(length(SNR),1);
for i=1:length(SNR)
rx(:,i) = awgn(tx,SNR(i),'measured');
end
rx_demod = demodulate(hDemod,rx);
for i=1:length(SNR)
[~,bit_error_rate(i)] = biterr(x,rx_demod(:,i));
end
theoryBer = 3/(2*k)*erfc(sqrt(0.1*k*(10.^(EbNo/10))));
figure;
semilogy(EbNo,theoryBer,'-',EbNo, bit_error_rate, '^-');
grid on;
legend('theory', 'simulation');
xlabel('Eb/No, dB');
ylabel('Bit Error Rate');
title('Bit error probability curve for 16-QAM modulation');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Creative Commons
% Attribution-Noncommercial 2.5 India
% You are free:
% to Share to copy, distribute and transmit the work
% to Remix to adapt the work
% Under the following conditions:
% Attribution. You must attribute the work in the manner
% specified by the author or licensor (but not in any way
% that suggests that they endorse you or your use of the work).
% Noncommercial. You may not use this work for commercial purposes.
% For any reuse or distribution, you must make clear to others the
% license terms of this work. The best way to do this is with a
% link to this web page.
% Any of the above conditions can be waived if you get permission
% from the copyright holder.
% Nothing in this license impairs or restricts the author's moral rights.
% http://creativecommons.org/licenses/by-nc/2.5/in/
% Script for simulating 16-PSK transmission and reception and compare the
% simulated and theoretical symbol error probability
%
%
%
%
%
%
Checked for proper operation with Octave Version 3.0.0
Author
: Krishna
Email
:
[email protected]Version
: 1.0
Date
: 16 February 2007
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% symbol error rate for 16-PSK modulation
clear
N = 2*10^5; % number of symbols
M = 16;
thetaMpsk = [0:M-1]*2*pi/M; % reference phase values
Es_N0_dB
= [0:25]; % multiple Es/N0 values
ipPhaseHat = zeros(1,N);
for ii = 1:length(Es_N0_dB)
% symbol generation
% -----------------ipPhase = randsrc(1,N,thetaMpsk);
ip = exp(j*ipPhase);
s = ip; % normalization of energy to 1
% noise
% ----n = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % white guassian noise, 0dB
variance
y = s + 10^(-Es_N0_dB(ii)/20)*n; % additive white gaussian noise
% demodulation
% -----------% finding the phase from [-pi to +pi]
opPhase = angle(y);
% unwrapping the phase i.e. phase less than 0 are
% added 2pi
opPhase(find(opPhase<0)) = opPhase(find(opPhase<0)) + 2*pi;
% rounding the received phase to the closest
% constellation
ipPhaseHat = 2*pi/M*round(opPhase/(2*pi/M))
;
% as there is phase ambiguity for phase = 0 and 2*pi,
% changing all phases reported as 2*pi to 0.
% this is to enable comparison with the transmitted phase
ipPhaseHat(find(ipPhaseHat==2*pi)) = 0;
% counting errors
nErr(ii) = size(find([ipPhase- ipPhaseHat]),2); % couting the number of
errors
end
simBer = nErr/N;
theoryBer = erfc(sqrt(10.^(Es_N0_dB/10))*sin(pi/M));
close all
figure
semilogy(Es_N0_dB,theoryBer,'bs-','LineWidth',2);
hold on
semilogy(Es_N0_dB,simBer,'mx-','LineWidth',2);
axis([0 25 10^-5 1])
grid on
legend('theory', 'simulation');
xlabel('Es/No, dB')
ylabel('Symbol Error Rate')
title('Symbol error probability curve for 16-PSK modulation')