QPSK simulation with AWGN and BER/SER - matlab

I have a matlab code of QPSK simulation over baseband with AWGN noise, I'm calculating BER over each SNR value and plotting it along with
Theoretical BER.
When I'm generating SNR values in dB from 1 to 20 the code only computes simulated BER values from 0 to 10, why is this happening?
% QPSK MODULATION AND BER ESTIMATION IN AWGN CHANNEL
clc; clear all; close all;
N=1e6; % Number of bits transmited
SNRdB= 0:1:20; % SNR for simulation
SNRlin=10.^(SNRdB/10);
BER = zeros(1,length(SNRlin));% simulated BER
SER = zeros(1,length(SNRlin));% simulated SER
b1 = rand(1,N) > 0.5;
b2 = rand(1,N) > 0.5;
% QPSK symbol mapping
I = (2*b1) - 1;
Q = (2*b2) - 1;
S = I + 1j*Q;
N0 = 1./SNRlin; % Variance
for k = 1:length(SNRdB)
noise = sqrt(N0(k)/2)*(randn(1,N) + 1j*randn(1,N)); % AWGN noise
sig_Rx = S + noise; % Recived signal
% For BER calculation
sig_I = real(sig_Rx); % I component
sig_Q = imag(sig_Rx); % Q component
bld_I = sig_I > 0; % I decision
bld_Q = sig_Q > 0; % Q decision
b1_error = (bld_I ~= b1); % Inphase bit error
b2_error = (bld_Q ~= b2); % Quadrature bit error
Error_bit = sum(b1_error) + sum(b2_error); % Total bit error
BER(k) = sum(Error_bit)/(2*N); % Simulated BER
% For SER calculation
error_symbol = or(b1_error, b2_error); % if bit in I or bit in Q either wrong than error
SER(k) = sum(error_symbol)/N;
end
BER_theo = 2*qfunc(sqrt(2*SNRlin)); % Theoretical BER
SER_theo = 2*qfunc(sqrt(2*SNRlin)) - (qfunc(sqrt(2*SNRlin))).^2; % Theoretical SER
figure(1);
semilogy(SNRdB, BER_theo,'r-')
hold on
semilogy(SNRdB, BER,'k*')
xlabel('SNR[dB]')
ylabel('Bit Error Rate');
legend('Theoretical', 'Simulated');
title(['Probability of Bit Error for QPSK Modulation']);
grid on;
hold off;
figure(2);
semilogy(SNRdB, SER_theo,'r-')
hold on
semilogy(SNRdB, SER,'k*')
xlabel('SNR[dB]')
ylabel('Symbol Error Rate');
legend('Theoretical', 'Simulated');
title(['Probability of symbol Error for QPSK Modulation']);
grid on;
hold off;
Here is my output plot:
BER and SER simulation results

Related

Failing to use interpolation instead of integration in chuncks with ODE45

I have written this code to integrate voltage V and gating conductances m, n and h in 30ms with injection of current from ms 10 to 20. So basically Current I is a vector that has 0 values until 10ms, 1 values until 20ms and 0 values until 30ms. The code works well and it shows the behaviour I want to see.
I'm trying to implement the same code with interpolation instead of integration in chunks. However, I'm failing to do so.
This is the integration with interpolation, which is giving the incorrect result:
myode = #(T,y0) [((1/Cm)*interp1(t, I, T, 'linear','extrap')-(INa+IK+Il)); % Normal case
alpham(y0(1,1))*(1-y0(2,1))-betam(y0(1,1))*y0(2,1);
alphan(y0(1,1))*(1-y0(3,1))-betan(y0(1,1))*y0(3,1);
alphah(y0(1,1))*(1-y0(4,1))-betah(y0(1,1))*y0(4,1)];
[time,V] = ode45(myode, t, y0, I);
This is the correct one, in chunks:
[time,V] = ode45(#ODEMAT, [t(chunk), t(chunk+1)], y);
%%% Calls ODEMAT, in which theres' the integration (extensive code posted below):
dydt = [((1/Cm)*(I(chunk)-(INa+IK+Il))); % Normal case
alpham(V)*(1-m)-betam(V)*m;
alphan(V)*(1-n)-betan(V)*n;
alphah(V)*(1-h)-betah(V)*h];
This is the code with the integration in chunks:
function Z2_chunks ()
%% Initial values
V=-60; % Initial Membrane voltage
m1=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n1=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h1=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m1;n1;h1];
t = [1:30];
I = [zeros(1,10),ones(1,10),zeros(1,10)];
% Plotting purposes (set I(idx) equal to last value of I)
idx = numel(t);
I(idx) = 0.1;
chunks = numel(t) - 1;
for chunk = 1:chunks
if chunk == 1
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y=[V;m;n;h];
else
y = V(end, :); % Final position is initial value for next interval
end
[time,V] = ode45(#ODEMAT, [t(chunk), t(chunk+1)], y);
if chunk == 1
def_time = time;
def_v = V;
else
def_time = [def_time; time];
def_v = [def_v; V];
end
end
OD = def_v(:,1);
ODm = def_v(:,2);
ODn = def_v(:,3);
ODh = def_v(:,4);
time = def_time;
%% Plots
%% Voltage
figure
subplot(3,1,1)
plot(time,OD);
legend('ODE45 solver');
xlabel('Time (ms)');
ylabel('Voltage (mV)');
title('Voltage Change for Hodgkin-Huxley Model');
%% Current
subplot(3,1,2)
stairs(t,I)
ylim([0 5*max(I)])
legend('Current injected')
xlabel('Time (ms)')
ylabel('Ampere')
title('Current')
%% Gating variables
subplot(3,1,3)
plot(time,[ODm,ODn,ODh]);
legend('ODm','ODn','ODh');
xlabel('Time (ms)')
ylabel('Value')
title('Gating variables')
function [dydt] = ODEMAT(t,y)
%% Constants
ENa=55; % mv Na reversal potential
EK=-72; % mv K reversal potential
El=-49; % mv Leakage reversal potential
%% Values of conductances
gbarl=0.003; % mS/cm^2 Leakage conductance
gbarNa=1.2; % mS/cm^2 Na conductance
gbarK=0.36; % mS/cm^2 K conductancence
Cm = 0.01; % Capacitance
% Values set to equal input values
V = y(1);
m = y(2);
n = y(3);
h = y(4);
gNa = gbarNa*m^3*h;
gK = gbarK*n^4;
gL = gbarl;
INa=gNa*(V-ENa);
IK=gK*(V-EK);
Il=gL*(V-El);
dydt = [((1/Cm)*(I(chunk)-(INa+IK+Il))); % Normal case
alpham(V)*(1-m)-betam(V)*m;
alphan(V)*(1-n)-betan(V)*n;
alphah(V)*(1-h)-betah(V)*h];
end
end
This is the code with the integration with interpolation. As you can see, the plots are really different:
function Z1_interpol ()
%% Initial values
V=-60; % Initial Membrane voltage
m1=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n1=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h1=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m1;n1;h1];
t = [1:30];
I = [zeros(1,10),ones(1,10),zeros(1,10)];
% Plotting purposes (set I(idx) equal to last value of I)
idx = numel(t);
I(idx) = 0.1;
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y=[V;m;n;h];
%% Constants
ENa=55; % mv Na reversal potential
EK=-72; % mv K reversal potential
El=-49; % mv Leakage reversal potential
%% Values of conductances
gbarl=0.003; % mS/cm^2 Leakage conductance
gbarNa=1.2; % mS/cm^2 Na conductance
gbarK=0.36; % mS/cm^2 K conductancence
Cm = 0.01; % Capacitance
%% Initial values
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m;n;h];
gNa = gbarNa*m^3*h;
gK = gbarK*n^4;
gL = gbarl;
INa=gNa*(V-ENa);
IK=gK*(V-EK);
Il=gL*(V-El);
myode = #(T,y0) [((1/Cm)*interp1(t, I, T, 'linear','extrap')-(INa+IK+Il)); % Normal case
alpham(y0(1,1))*(1-y0(2,1))-betam(y0(1,1))*y0(2,1);
alphan(y0(1,1))*(1-y0(3,1))-betan(y0(1,1))*y0(3,1);
alphah(y0(1,1))*(1-y0(4,1))-betah(y0(1,1))*y0(4,1)];
[time,V] = ode45(myode, t, y0, I);
OD=V(:,1);
ODm=V(:,2);
ODn=V(:,3);
ODh=V(:,4);
time = time;
%% Plots
%% Voltage
figure
subplot(3,1,1)
plot(time,OD);
legend('ODE45 solver');
xlabel('Time (ms)');
ylabel('Voltage (mV)');
title('Voltage Change for Hodgkin-Huxley Model');
%% Current
subplot(3,1,2)
stairs(t,I)
ylim([0 5*max(I)])
legend('Current injected')
xlabel('Time (ms)')
ylabel('Ampere')
title('Current')
%% Gating variables
subplot(3,1,3)
plot(time,[ODm,ODn,ODh]);
legend('ODm','ODn','ODh');
xlabel('Time (ms)')
ylabel('Value')
title('Gating variables')
end

Matlab : What is the BER performance of Constant Modulus Algorithm and issue in filter function

I need help in plotting the Bit error curve or the symbol error curve for BPSK modulation scheme for varying Signal to Noise ratios or Eb/N0. The plot should show the simulated versus the theoretical curve, but I cannot figure out how to mitigate the problems when using the Constant Modulus Algorithm as an Equalizer which are:
(1)
Error using *
Inner matrix dimensions must agree.
Error in BER_BPSK_CMA (line 50)
yy = w'*x;
(2) I want to use the filter function instead of conv in order to model a moving average channel model, chanOut = filter(ht,1,s). But, when I use filter, I am getting an error. How can I use filter function here?
(3) Bit error rate calculation
UPDATED Code with the Problem 1 solved. However, I am still unable to use filter and unsure if BER curve is proper or not.
Below is the code I wrote:
% Script for computing the BER for BPSK modulation in 3 tap ISI
% channel
clear
N = 10^2; % number of bits or symbols
Eb_N0_dB = [0:15]; % multiple Eb/N0 values
K = 3; %number of users
nTap = 3;
mu = 0.001;
ht = [0.2 0.9 0.3];
L = length(ht);
for ii = 1:length(Eb_N0_dB)
% Transmitter
ip = rand(1,N)>0.5; % generating 0,1 with equal probability
s = 2*ip-1; % BPSK modulation 0 -> -1; 1 -> 0
% Channel model, multipath channel
chanOut = conv(s,ht);
% chanOut = filter(ht,1,s); %MA
n = 1/sqrt(2)*[randn(1,N+length(ht)-1) + j*randn(1,N+length(ht)-1)]; % white gaussian noise, 0dB variance
% Noise addition
y = chanOut + 10^(-Eb_N0_dB(ii)/20)*n; % additive white gaussian noise
%CMA
Le =20; %Equalizer length
e = zeros(N,1); % error
w = zeros(Le,1); % equalizer coefficients
w(Le)=1; % actual filter taps are flipud(w)!
yd = zeros(N,1);
r = y';
% while(1)
for i = 1:N-Le,
x = r(i:Le+i-1);
%x = r(i:(Le+i-1));
yy = w'*x;
yd(i)= yy;
e(i) = yy^2 - 1;
mse_signal(ii,i) = mean(e.*e);
w = w - mu * e(i) * yy * x;
end
sb=w'*x; % estimate symbols (perform equalization)
% receiver - hard decision decoding
ipHat = real(sb)>0;
% counting the errors
nErr_CMA(ii) = size(find([ip- ipHat]),2);
% calculate SER
end
simBer_CMA = nErr_CMA/N;
theoryBer = 0.5*erfc(sqrt(10.^(Eb_N0_dB/10))); % theoretical ber
for i=1:length(Eb_N0_dB),
tmp=10.^(i/10);
tmp=sqrt(tmp);
theoryBer(i)=0.5*erfc(tmp);
end
figure
semilogy(theoryBer,'b'),grid;
hold on;
semilogy(Eb_N0_dB,simBer_CMA,'r-','Linewidth',2);
%axis([0 14 10^-5 0.5])
grid on
legend('sim-CMA');
xlabel('Eb/No, dB');
ylabel('Bit Error Rate');
title('Bit error probability curve for BPSK in ISI with CMA equalizer');
There's an error in these three lines:
sb=w'*x; % estimate symbols (perform equalization)
% receiver - hard decision decoding
ipHat = real(sb)>0;
they worked inside the while loop but you are now performing a post-estimation, so the correct lines are:
sb=conv(w,y); % estimate symbols (perform equalization)
% receiver - hard decision decoding
ipHat = real(sb(Le+1:end-1))>0; % account for the filter delay
There is still some issue with the output... but I can't go further in the analisys.
Your first problem is easily solved: change the line to
x = y(i:(Le+i-1));
Your call of filter looks OK. Which error do you get?
Maybe this is a place to start looking.
Or here (would Fig. 4 be the type of plot you're after?)

phase assignment in an OFDM signal

I have an OFDM signal which is giving me half the power spectrum (half the bandwidth) I am meant to have. I am been told the phase assignment is what is causing it but I have been twitching on it for days.... still not having the right answer
prp=1e-6;
fstep=1/prp;
M = 4; % QPSK signal constellation
k = log2(M); % bits per symbol
fs=4e9;
Ns=floor(prp*fs);
no_of_data_points = (Ns/2);
no_of_points=no_of_data_points;
no_of_ifft_points = (Ns); % 256 points for the FFT/IFFT
no_of_fft_points = (Ns);
nsamp = 1; % Oversampling rate
fl = 0.5e9;
fu = 1.5e9;
Nf=(fu-fl)/fstep;
phin=zeros(Nf,1);
dataIn = randint(no_of_data_points*k*2,1,2); % Generate vector of binary
data_source = randsrc(1, no_of_data_points*k*2, 0:M-1);
qpsk_modulated_data= modulate(modem.qammod(M),data_source);
modu_data= qpsk_modulated_data(:)/sqrt(2);
[theta, rho] = cart2pol(real(modu_data), imag(modu_data));
A=angle(modu_data);
theta=radtodeg(theta);
figure(3);
plot(modu_data,'o');%plot constellation without noise
axis([-2 2 -2 2]);
grid on;
xlabel('real'); ylabel('imag');
%% E:GENERTION
phin = zeros(Nf,1);
phin(1:Nf,1)=theta(1:Nf);
No = fl/fstep;
Vn = zeros(Ns,1);
for r = 1:Nf
Vn(r+No,1) = 1*phin(r,1);
% Vn(r+No,2) = 1*phin(r,2);
end
%%
%------------------------------------------------------
%E. Serial to parallel conversion
%------------------------------------------------------
par_data = reshape(Vn,2,no_of_data_points);
%%
% F. IFFT Transform each period's spectrum (represented by a row of
% time domain via IFFT
time_domain_matrix =ifft(par_data.',Ns);
You are only considering the real part of the signal.

QPSK constellation Diagram

Below is my MATLAB code for QPSK commnication:
clc;
clear all;
close all;
data=[0 1 0 1 1 1 0 0 1 1]; % information
%Number_of_bit=1024;
%data=randint(Number_of_bit,1);
figure(1)
stem(data, 'linewidth',3), grid on;
title(' Information before Transmiting ');
axis([ 0 11 0 1.5]);
data_NZR=2*data-1; % Data Represented at NZR form for QPSK modulation
s_p_data=reshape(data_NZR,2,length(data)/2); % S/P convertion of data
br=10.^6; %Let us transmission bit rate 1000000
f=br; % minimum carrier frequency
T=1/br; % bit duration
t=T/99:T/99:T; % Time vector for one bit information
% XXXXXXXXXXXXXXXXXXXXXXX QPSK modulation XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
y=[];
y_in=[];
y_qd=[];
for(i=1:length(data)/2)
y1=s_p_data(1,i)*cos(2*pi*f*t); % inphase component
y2=s_p_data(2,i)*sin(2*pi*f*t) ;% Quadrature component
y_in=[y_in y1]; % inphase signal vector
y_qd=[y_qd y2]; %quadrature signal vector
y=[y y1+y2]; % modulated signal vector
end
Tx_sig=y; % transmitting signal after modulation
tt=T/99:T/99:(T*length(data))/2;
figure(2)
subplot(3,1,1);
plot(tt,y_in,'linewidth',3), grid on;
title(' wave form for inphase component in QPSK modulation ');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
subplot(3,1,2);
plot(tt,y_qd,'linewidth',3), grid on;
title(' wave form for Quadrature component in QPSK modulation ');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
subplot(3,1,3);
plot(tt,Tx_sig,'r','linewidth',3), grid on;
title('QPSK modulated signal (sum of inphase and Quadrature phase signal)');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
I am unable to understand which values to use to generate the phase constellation diagram for my code? What way in my code I can generate the correct phase constellation diagram?
============== UPDATE ==============
clc;
clear all;
close all;
data=[0 0 1 1 0 1 1 0 1 1 1 0]; % information
figure(1)
stem(data, 'linewidth',3), grid on;
title(' Information before Transmiting ');
axis([ 0 11 0 1.5]);
data_NZR=2*data-1; % Data Represented at NZR form for QPSK modulation
s_p_data=reshape(data_NZR,2,length(data)/2); % S/P convertion of data
br=10.^6; %Let us transmission bit rate 1000000
f=br; % minimum carrier frequency
T=1/br; % bit duration
t=T/99:T/99:T; % Time vector for one bit information
y=[];
y_in=[];
y_qd=[];
d=zeros(1,length(data)/2);
for i=1:length(data)/2
p=data(2*i);
imp=data(2*i - 1);
y1=s_p_data(1,i)*cos(2*pi*f*t); % inphase component
y2=s_p_data(2,i)*sin(2*pi*f*t) ;% Quadrature component
y_in=[y_in y1]; % inphase signal vector
y_qd=[y_qd y2]; %quadrature signal vector
y=[y y1+y2]; % modulated signal vector
if (imp == 0) && (p == 0)
d(i)=exp(j*pi/4);%45 degrees
end
if (imp == 1)&&(p == 0)
d(i)=exp(j*3*pi/4);%135 degrees
end
if (imp == 1)&&(p == 1)
d(i)=exp(j*5*pi/4);%225 degrees
end
if (imp == 0)&&(p == 1)
d(i)=exp(j*7*pi/4);%315 degrees
end
end
Tx_sig=y; % transmitting signal after modulation
qpsk=d;
tt=T/99:T/99:(T*length(data))/2;
figure(2)
subplot(3,1,1);
plot(tt,y_in,'linewidth',3), grid on;
title(' wave form for inphase component in QPSK modulation ');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
subplot(3,1,2);
plot(tt,y_qd,'linewidth',3), grid on;
title(' wave form for Quadrature component in QPSK modulation ');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
subplot(3,1,3);
plot(tt,Tx_sig,'r','linewidth',3), grid on;
title('QPSK modulated signal (sum of inphase and Quadrature phase signal)');
xlabel('time(sec)');
ylabel(' amplitude(volt0');
figure(3);
plot(d,'o');%plot constellation without noise
axis([-2 2 -2 2]);
grid on;
xlabel('real'); ylabel('imag');
title('QPSK constellation');
The QPSK symbol alphabet has four complex symbols. A set of random QPSK symbols can be created by generating an array of random integer numbers in 1..4 and mapping these numbers to complex symbols:
num_symbols = 1e4;
int_symbols = randi([1, 4], 1, num_symbols);
A = sqrt(2);
qpsk_symbols = zeros(size(int_symbols));
qpsk_symbols(int_symbols == 1) = A + 1i*A;
qpsk_symbols(int_symbols == 2) = A - 1i*A;
qpsk_symbols(int_symbols == 3) = - A + 1i*A;
qpsk_symbols(int_symbols == 4) = - A - 1i*A;
tx_sig = qpsk_symbols;
tx_sig could be the transmitted signal in a communication system. To plot the constellation diagram, use the real part as x-values and the imaginary part as y-values in the plot command. Additionally, use '.' as linestyle, so that every value is just represented by a dot, without line connections:
fh1 = figure;
plot_lims = [-3 3];
plot(real(qpsk_symbols), imag(qpsk_symbols), '.');
xlim(plot_lims);
ylim(plot_lims);
title('QPSK constellation without noise');
xlabel('real part');
ylabel('imaginary part');
This produces
which shows four distinct points. Adding noise makes this more interesting:
snr = 15; %// in dB
rx_sig = awgn(tx_sig, snr, 'measured');
fh2 = figure;
plot(real(rx_sig), imag(rx_sig), '.');
xlim(plot_lims);
ylim(plot_lims);
title(['QPSK constellation at an SNR of ' num2str(snr) ' dB']);
xlabel('real part');
ylabel('imaginary part');
which produces
This could be the received signal in a communications system neglecting inter-symbol interference and other frequency-selective components. (so-called AWGN channel for additive white gaussian noise).

MATLAB - FM Modulation

I am trying to Frequency modulate a sine signal using Matlab. I have written the following code for the same:
fc = 5000; %Carrier Frequency
fs = 1000; %Signal Frequency
t = 0:0.00001:0.002;
x = sin(2*pi*fs*t);
dev = 50;
subplot(2,1,1);
plot(t,x);
y = fmmod(x,fc,fs,dev);
subplot(2,1,2);
plot(t,y);
It is able to display the first plot command but not the second one. It throws an error: `fmmod' undefined near line 10 column 5. What is wrong in the above code?
The following function will generate a FM modulated signal - it's not as good (flexible, etc) as fmmod but if you don't have the Comm System Toolbox this may be a good alternative.
function [s t] = makeFM( x, Fc, Fs, strength )
% for a signal x that modulates a carrier at frequency Fc
% produce the FM modulated signal
% works for 1 D input only
% no error checking
x = x(:);
% sampling points in time:
t = ( 0 : numel( x ) - 1 )' / Fs;
% integrate input signal
integratedX = cumsum( x ) / Fs;
s = cos( 2 * pi * ( Fc * t + strength * integratedX ));
Put this in your path and call it with similar arguments to the fmmod function (but without optional parameters):
fc = 5000; %Carrier Frequency
fs = 1000; %Signal Frequency
t = 0:0.00001:0.002;
x = sin( 2*pi*fs*t );
dev = 50;
subplot(2,1,1);
plot(t,x);
y = makeFM(x, fc, 2.5*fc, dev); % note sampling frequency must be > carrier frequency!
subplot(2,1,2);
plot(t,y);
Let me know how that works for you.
I guess this is more simple approach
clc;
clear all;
close all;
fm=input('Message Frequency=');
fc=input('Carrier Frequency=');
mi=input('Modulation Index=');
t=0:0.0001:0.1;
m=sin(2*pi*fm*t);
subplot(3,1,1);
plot(t,m);
xlabel('Time');
ylabel('Amplitude');
title('Message Signal');
grid on;
c=sin(2*pi*fc*t);
subplot(3,1,2);
plot(t,c);
xlabel('Time');
ylabel('Amplitude');
title('Carrier Signal');
grid on;
y=sin(2*pi*fc*t+(mi.*sin(2*pi*fm*t)));%Frequency changing w.r.t Message
subplot(3,1,3);
plot(t,y);
xlabel('Time');
ylabel('Amplitude');
title('FM Signal');
grid on;