IT++ Logo
Simulation of QPSK modulation on an AWGN channel

In this example we will introduce a few new features compared to the BPSK example. We will use the it_ifile class to store the results of the simulation. We will use the Real_Timer class to measure the execution time of our program. Furthermore we will use one of the channel classes, the AWGN_Channel. We will also show how to read the results in to Matlab with the load_it function. The program is as follows:

#include <itpp/itcomm.h>
using namespace itpp;
//These lines are needed for use of cout and endl
using std::cout;
using std::endl;
int main()
{
//Declarations of scalars and vectors:
int i, Number_of_bits;
double Ec, Eb;
vec EbN0dB, EbN0, N0, noise_variance, bit_error_rate; //vec is a vector containing double
bvec transmitted_bits, received_bits; //bvec is a vector containing bits
cvec transmitted_symbols, received_symbols; //cvec is a vector containing double_complex
//Declarations of classes:
QPSK qpsk; //The QPSK modulator class
AWGN_Channel awgn_channel; //The AWGN channel class
it_file ff; //For saving the results to file
BERC berc; //Used to count the bit errors
Real_Timer tt; //The timer used to measure the execution time
//Reset and start the timer:
tt.tic();
//Init:
Ec = 1.0; //The transmitted energy per QPSK symbol is 1.
Eb = Ec / 2.0; //The transmitted energy per bit is 0.5.
EbN0dB = linspace(0.0, 9.0, 10); //Simulate for 10 Eb/N0 values from 0 to 9 dB.
EbN0 = inv_dB(EbN0dB); //Calculate Eb/N0 in a linear scale instead of dB.
N0 = Eb * pow(EbN0, -1.0); //N0 is the variance of the (complex valued) noise.
Number_of_bits = 100000; //One hundred thousand bits is transmitted for each Eb/N0 value
//Allocate storage space for the result vector.
//The "false" argument means "Do not copy the old content of the vector to the new storage area."
bit_error_rate.set_size(EbN0dB.length(), false);
//Randomize the random number generators in it++:
//Iterate over all EbN0dB values:
for (i = 0; i < EbN0dB.length(); i++) {
//Show how the simulation progresses:
cout << "Now simulating Eb/N0 value number " << i + 1 << " of " << EbN0dB.length() << endl;
//Generate a vector of random bits to transmit:
transmitted_bits = randb(Number_of_bits);
//Modulate the bits to QPSK symbols:
transmitted_symbols = qpsk.modulate_bits(transmitted_bits);
//Set the noise variance of the AWGN channel:
awgn_channel.set_noise(N0(i));
//Run the transmited symbols through the channel using the () operator:
received_symbols = awgn_channel(transmitted_symbols);
//Demodulate the received QPSK symbols into received bits:
received_bits = qpsk.demodulate_bits(received_symbols);
//Calculate the bit error rate:
berc.clear(); //Clear the bit error rate counter
berc.count(transmitted_bits, received_bits); //Count the bit errors
bit_error_rate(i) = berc.get_errorrate(); //Save the estimated BER in the result vector
}
tt.toc();
//Print the results:
cout << endl;
cout << "EbN0dB = " << EbN0dB << " [dB]" << endl;
cout << "BER = " << bit_error_rate << endl;
cout << "Saving results to ./qpsk_result_file.it" << endl;
cout << endl;
//Save the results to file:
ff.open("qpsk_result_file.it");
ff << Name("EbN0dB") << EbN0dB;
ff << Name("ber") << bit_error_rate;
ff.close();
//Exit program:
return 0;
}

When you run this program, the output will look something like this:

Now simulating Eb/N0 value number 1 of 10
Now simulating Eb/N0 value number 2 of 10
Now simulating Eb/N0 value number 3 of 10
Now simulating Eb/N0 value number 4 of 10
Now simulating Eb/N0 value number 5 of 10
Now simulating Eb/N0 value number 6 of 10
Now simulating Eb/N0 value number 7 of 10
Now simulating Eb/N0 value number 8 of 10
Now simulating Eb/N0 value number 9 of 10
Now simulating Eb/N0 value number 10 of 10
Elapsed time = 0.460899 seconds
EbN0dB = [0 1 2 3 4 5 6 7 8 9] [dB]
BER = [0.07968 0.0559 0.03729 0.02294 0.01243 0.0058 0.0025 0.00076 0.00013 6e-05]
Saving results to ./qpsk_result_file.it

Now it is time to plot the simulation results in Matlab and compare with theory using the Matlab code below. The results will be stored in a file called "qpsk_result_file.it". Make sure load_it.m is in your Matlab path (look in /matlab) and that you run the example code below from the directory where qpsk_result_file.it is located

figure(1); clf;
load_it qpsk_result_file.it
h1 = semilogy(EbN0dB,ber,'*-r'); hold on
ebn0db = 0:.1:10;
ebn0 = 10.^(ebn0db/10);
Pb = 0.5 * erfc(sqrt(ebn0));
h2 = semilogy(ebn0db,Pb);
set(gca,'fontname','times','fontsize',16);
xlabel('{\it E_b} / {\it N}_0 [dB]');
ylabel('BER')
title('QPSK on an AWGN Channel');
legend([h1 h2],'Simulation','Theory');
grid on;
itpp::AWGN_Channel::set_noise
void set_noise(double noisevar)
Set noise variance (for complex-valued channels the sum of real and imaginary parts)
Definition: channel.h:1094
itpp::QPSK
QPSK modulator.
Definition: modulator.h:677
itpp::Timer::tic
void tic(void)
Resets the timer and starts it.
Definition: timing.cpp:119
itpp::BERC::get_errorrate
double get_errorrate() const
Returns the estimated bit error rate.
Definition: error_counters.h:103
itpp::RNG_randomize
void RNG_randomize()
Set a random seed for all Random Number Generators in the current thread.
Definition: random.cpp:254
itpp::Modulator::modulate_bits
virtual void modulate_bits(const bvec &bits, Vec< T > &output) const
Modulation of bits.
Definition: modulator.h:362
itpp
itpp namespace
Definition: itmex.h:36
itpp::BERC::clear
void clear()
Clears the bit error counter.
Definition: error_counters.h:91
itpp::it_file::open
void open(const std::string &filename, bool trunc=false)
Open a file for reading and writing.
Definition: itfile.cpp:512
itpp::inv_dB
double inv_dB(double x)
Inverse of decibel of x.
Definition: log_exp.h:73
itpp::PSK::demodulate_bits
void demodulate_bits(const cvec &signal, bvec &bits) const
Hard demodulation of bits.
Definition: modulator.cpp:151
itpp::randb
bin randb(void)
Generates a random bit (equally likely 0s and 1s)
Definition: random.h:793
itpp::Real_Timer
A real time timer class.
Definition: timing.h:138
itpp::Timer::toc
double toc(void)
Returns the elapsed time since last tic()
Definition: timing.cpp:125
itpp::linspace
vec linspace(double from, double to, int points)
linspace (works in the same way as the MATLAB version)
Definition: specmat.cpp:106
itpp::AWGN_Channel
Ordinary AWGN Channel for cvec or vec inputs and outputs.
Definition: channel.h:1088
itpp::it_file::close
void close()
Close the file.
Definition: itfile.cpp:530
itpp::it_file
The IT++ file format reading and writing class.
Definition: itfile.h:245
itpp::pow
vec pow(const double x, const vec &y)
Calculates x to the power of y (x^y)
Definition: log_exp.h:176
itpp::sqrt
vec sqrt(const vec &x)
Square root of the elements.
Definition: elem_math.h:123
itpp::BERC
Bit Error Rate Counter (BERC) Class.
Definition: error_counters.h:67
itcomm.h
Include file for the IT++ communications module.
itpp::Name
Automatic naming when saving.
Definition: itfile.h:428
itpp::BERC::count
void count(const bvec &in1, const bvec &in2)
Cumulative error counter.
Definition: error_counters.cpp:49
itpp::erfc
vec erfc(const vec &x)
Complementary error function.
Definition: error.cpp:240

Generated on Mon Mar 23 2020 06:18:03 for IT++ by Doxygen 1.8.17