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 namespace itpp;
using std::cout;
using std::endl;
using std::string;
int main(void)
{
    
    double threshold_value = 10;
    string map_metric="maxlogMAP";
    ivec gen = "07 05";
    int constraint_length = 3;
    int nb_errors_lim = 3000;
    int nb_bits_lim = int(1e6);
    int perm_len = (1<<14);
    int nb_iter = 10;
    vec EbN0_dB = "0:0.1:5";
    double R = 1.0/3.0;
    double Ec = 1.0;
    
    int nb_bits = perm_len-(constraint_length-1);
    vec sigma2 = (0.5*Ec/R)*
pow(
inv_dB(EbN0_dB), -1.0);
    double Lc;
    int nb_blocks;
    int nb_errors;
    ivec perm(perm_len);
    ivec inv_perm(perm_len);
    bvec bits(nb_bits);
    int cod_bits_len = perm_len*gen.length();
    bvec tail;
    bvec cod2_input;
    int rec_len = int(1.0/R)*perm_len;
    bvec coded_bits(rec_len);
    vec rec(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);
    bvec rec_bits(perm_len);
    int snr_len = EbN0_dB.length();
    mat ber(nb_iter,snr_len);
    ber.zeros();
    register int en,n;
    
    
    
    
    
    
    
    for (en=0;en<snr_len;en++)
    {
        cout << "EbN0_dB = " << EbN0_dB(en) << endl;
        Lc = -2/sigma2(en);
        nb_errors = 0;
        nb_blocks = 0;
        while ((nb_errors<nb_errors_lim) && (nb_blocks*nb_bits<nb_bits_lim))
        {
            
            perm = sort_index(
randu(perm_len));
            
            inv_perm = sort_index(perm);
            
            
            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);
            }
            
            
            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);
                
                
                siso.
rsc(extrinsic_coded, extrinsic_data, dec2_intrinsic_coded, apriori_data);
                
                apriori_data += extrinsic_data;
                
                berc.
count(bits, rec_bits.left(nb_bits));
                
                apriori_data = extrinsic_data(inv_perm);
            }
            nb_blocks++;
        }
        
        ber.set_col(en, ber.get_col(en)/nb_blocks);
    }
    ff << 
Name(
"EbN0_dB") << EbN0_dB;
    ff << 
Name(
"BER") << ber;
    return 0;
}
 When you run this program, the results (BER and EbN0_dB) are saved into pccc_bersim_awgn.it file. Using the following MATLAB script: 
itload('pccc_bersim_awgn.it');
figure
semilogy(EbN0_dB, BER, 'o-')
grid on
ylabel('BER')
  the results can be displayed.
Similarly, the results can be displayed using the following Python script (pyitpp, numpy and matplotlib modules are required): 
#!/usr/bin/env python
from pyitpp import itload
from matplotlib.pyplot import *
out = itload('pccc_bersim_awgn.it')
semilogy(out['EbN0_dB'], out['BER'].T, 'o-')
grid()
ylabel('$BER$')
show()