This program simulates Parallel Concatenated Convolutional Codes (PCCCs) of coding rate 1/3 using a turbo decoder with two SISO RSC modules.
Reference: S. Benedetto, D. Divsalar, G. Motorsi and F. Pollara, "A Soft-Input Soft-Output Maximum A posteriori (MAP) Module to Decode Parallel and Serial Concatenated Codes", TDA Progress Report, nov. 1996
using std::cout;
using std::endl;
using std::string;
int main(void)
{
double threshold_value = 10;
string map_metric="maxlogMAP";
int constraint_length = 3;
int nb_errors_lim = 3000;
int nb_bits_lim = int(1e6);
int perm_len = (1<<14);
int nb_iter = 10;
double R = 1.0/3.0;
double Ec = 1.0;
int nb_bits = perm_len-(constraint_length-1);
double Lc;
int nb_blocks;
int nb_errors;
int cod_bits_len = perm_len*gen.length();
int rec_len = int(1.0/R)*perm_len;
bvec coded_bits(rec_len);
vec dec1_intrinsic_coded(cod_bits_len);
vec dec2_intrinsic_coded(cod_bits_len);
vec apriori_data(perm_len);
vec extrinsic_coded(perm_len);
vec extrinsic_data(perm_len);
int snr_len = EbN0_dB.length();
mat ber(nb_iter,snr_len);
ber.zeros();
register int en,n;
Rec_Syst_Conv_Code cc;
cc.set_generator_polynomials(gen, constraint_length);
BPSK bpsk;
AWGN_Channel channel;
SISO siso;
siso.set_generators(gen, constraint_length);
siso.set_map_metric(map_metric);
BERC berc;
for (en=0;en<snr_len;en++)
{
cout << "EbN0_dB = " << EbN0_dB(en) << endl;
channel.set_noise(sigma2(en));
Lc = -2/sigma2(en);
nb_errors = 0;
nb_blocks = 0;
while ((nb_errors<nb_errors_lim) && (nb_blocks*nb_bits<nb_bits_lim))
{
cc.encode_tail(bits, tail, cod1_bits);
cod2_input =
concat(bits, tail);
cc.encode(cod2_input(perm), cod2_bits);
for (n=0;n<perm_len;n++)
{
coded_bits(3*n) = cod2_input(n);
coded_bits(3*n+1) = cod1_bits(n,0);
coded_bits(3*n+2) = cod2_bits(n,0);
}
rec = channel(bpsk.modulate_bits(coded_bits));
for (n=0;n<perm_len;n++)
{
dec1_intrinsic_coded(2*n) = Lc*rec(3*n);
dec1_intrinsic_coded(2*n+1) = Lc*rec(3*n+1);
dec2_intrinsic_coded(2*n) = 0.0;
dec2_intrinsic_coded(2*n+1) = Lc*rec(3*n+2);
}
apriori_data.zeros();
for (n=0;n<nb_iter;n++)
{
siso.rsc(extrinsic_coded, extrinsic_data, dec1_intrinsic_coded, apriori_data, true);
apriori_data = extrinsic_data(perm);
apriori_data = SISO::threshold(apriori_data, threshold_value);
siso.rsc(extrinsic_coded, extrinsic_data, dec2_intrinsic_coded, apriori_data);
apriori_data += extrinsic_data;
rec_bits = bpsk.demodulate_bits(-apriori_data(inv_perm));
berc.clear();
berc.count(bits, rec_bits.left(nb_bits));
ber(n,en) += berc.get_errorrate();
apriori_data = extrinsic_data(inv_perm);
}
nb_errors += int(berc.get_errors());
nb_blocks++;
}
ber.set_col(en, ber.get_col(en)/nb_blocks);
}
it_file ff("pccc_bersim_awgn.it");
ff << Name("EbN0_dB") << EbN0_dB;
ff << Name("BER") << ber;
ff.close();
return 0;
}
Mat< double > mat
Default Matrix Type.
Vec< double > vec
Definition of double vector type.
ivec sort_index(const Vec< T > &data, SORTING_METHOD method=INTROSORT)
Return an index vector corresponding to a sorted vector data in increasing order.
Vec< int > ivec
Definition of integer vector type.
Vec< bin > bvec
Definition of binary vector type.
vec pow(const double x, const vec &y)
Calculates x to the power of y (x^y)
double inv_dB(double x)
Inverse of decibel of x.
void RNG_randomize()
Set a random seed for all Random Number Generators in the current thread.
double randu(void)
Generates a random uniform (0,1) number.
bin randb(void)
Generates a random bit (equally likely 0s and 1s)
Include file for the IT++ communications module.
Mat< bin > bmat
bin matrix
const Array< T > concat(const Array< T > &a, const T &e)
Append element e to the end of the Array a.
When you run this program, the results (BER and EbN0_dB) are saved into pccc_bersim_awgn.it file. Using the following MATLAB script:
the results can be displayed.
Similarly, the results can be displayed using the following Python script (pyitpp, numpy and matplotlib modules are required):