예제 #1
0
파일: sccc.cpp 프로젝트: Yang-PY/turbosiso
int main(void)
{
    //general parameters
    double threshold_value = 50;
    string map_metric="logMAP";
    ivec gen = "037 021";//octal form
    int constraint_length = 5;
    int nb_errors_lim = 1500;
    int nb_bits_lim = int(1e6);
    int perm_len = pow2i(14);//permutation length
    int nb_iter = 10;//number of iterations in the turbo decoder
    vec EbN0_dB = "0:0.1:5";
    double R = 1.0/4.0;//coding rate (non punctured SCCC)
    double Ec = 1.0;//coded bit energy

    //other parameters
    string filename = "Res/sccc_"+map_metric+".it";
    int nb_bits_tail = perm_len/gen.length();
    int nb_bits = nb_bits_tail-(constraint_length-1);//number of bits in a block (without tail)
    vec sigma2 = (0.5*Ec/R)*pow(inv_dB(EbN0_dB), -1.0);//N0/2
    double Lc;//scaling factor for intrinsic information
    int nb_blocks;//number of blocks
    int nb_errors;
    bvec bits(nb_bits);//data bits
    bvec nsc_coded_bits;//tail is added
    bmat rsc_parity_bits;
    ivec perm(perm_len);
    ivec inv_perm(perm_len);
    int rec_len = gen.length()*perm_len;
    bvec coded_bits(rec_len);    
    vec rec(rec_len);    
    //SISO RSC
    vec rsc_intrinsic_coded(rec_len);
    vec rsc_apriori_data(perm_len);
    vec rsc_extrinsic_coded;
    vec rsc_extrinsic_data;
    //SISO NSC
    vec nsc_intrinsic_coded(perm_len);
    vec nsc_apriori_data(nb_bits_tail);
    nsc_apriori_data.zeros();//always zero
    vec nsc_extrinsic_coded;
    vec nsc_extrinsic_data;
    //decision
    bvec rec_bits(nb_bits_tail);    
    int snr_len = EbN0_dB.length();
    mat ber(nb_iter,snr_len);
    ber.zeros();
    register int en,n;
    
    //Non recursive non Systematic Convolutional Code
    Convolutional_Code nsc;
    nsc.set_generator_polynomials(gen, constraint_length);
        
    //Recursive Systematic Convolutional Code
    Rec_Syst_Conv_Code rsc;
    rsc.set_generator_polynomials(gen, constraint_length);//initial state should be the zero state
    
    //BPSK modulator
    BPSK bpsk;
    
    //AWGN channel
    AWGN_Channel channel;

    //SISO blocks
    SISO siso;
    siso.set_generators(gen, constraint_length);
    siso.set_map_metric(map_metric);
    
    //BER
    BERC berc;

    //Progress timer
    tr::Progress_Timer timer;
    timer.set_max(snr_len);
            
    //Randomize generators
    RNG_randomize();
    
    //main loop
    timer.progress(0.0);
    for (en=0;en<snr_len;en++)
    {
        channel.set_noise(sigma2(en));
        Lc = -2.0/sigma2(en);//take into account the BPSK mapping
        nb_errors = 0;
        nb_blocks = 0;
        while ((nb_errors<nb_errors_lim) && (nb_blocks*nb_bits<nb_bits_lim))//if at the last iteration the nb. of errors is inferior to lim, then process another block
        {
            //permutation
            perm = sort_index(randu(perm_len));
            //inverse permutation
            inv_perm = sort_index(perm);

            //bits generation
            bits = randb(nb_bits);

            //serial concatenated convolutional code
            nsc.encode_tail(bits, nsc_coded_bits);//tail is added here to information bits to close the trellis
            nsc_coded_bits = nsc_coded_bits(perm);//interleave 
            rsc.encode(nsc_coded_bits, rsc_parity_bits);//no tail added            
            for(n=0;n<perm_len;n++)
            {
            	coded_bits(2*n) = nsc_coded_bits(n);//systematic output
            	coded_bits(2*n+1) = rsc_parity_bits(n,0);//parity output
            }

            //BPSK modulation (1->-1,0->+1) + channel
            rec = channel(bpsk.modulate_bits(coded_bits));

            //turbo decoder
            rsc_intrinsic_coded = Lc*rec;//intrinsic information of coded bits
            rsc_apriori_data.zeros();//a priori LLR for information bits
            for (n=0;n<nb_iter;n++)
            {
                //first decoder
                siso.rsc(rsc_extrinsic_coded, rsc_extrinsic_data, rsc_intrinsic_coded, rsc_apriori_data, false);                
                
                //deinterleave+threshold
                nsc_intrinsic_coded = threshold(rsc_extrinsic_data(inv_perm), threshold_value);
                
                //second decoder
                siso.nsc(nsc_extrinsic_coded, nsc_extrinsic_data, nsc_intrinsic_coded, nsc_apriori_data, true);              

                //decision
                rec_bits = bpsk.demodulate_bits(-nsc_extrinsic_data);//suppose that a priori info is zero
                //count errors
                berc.clear();
                berc.count(bits, rec_bits.left(nb_bits));
                ber(n,en) += berc.get_errorrate();

                //interleave
                rsc_apriori_data = nsc_extrinsic_coded(perm);
            }//end iterations
            nb_errors += int(berc.get_errors());//get number of errors at the last iteration
            nb_blocks++;
        }//end blocks (while loop)

        //compute BER over all tx blocks
        ber.set_col(en, ber.get_col(en)/nb_blocks);

        //show progress
        timer.progress(1+en);
    }
    timer.toc_print();

#ifdef TO_FILE
	//save results to file
    it_file ff(filename);
    ff << Name("BER") << ber;
    ff << Name("EbN0_dB") << EbN0_dB;
    ff << Name("gen") << gen;
    ff << Name("R") << R;
    ff << Name("nb_iter") << nb_iter;
    ff << Name("total_nb_bits") << nb_bits;
    ff << Name("nb_errors_lim") << nb_errors_lim;
    ff << Name("nb_bits_lim") << nb_bits_lim;
    ff.close();
#else
    //show BER
    cout << ber << endl;
#endif    
    
    return 0;
}
예제 #2
0
int main(void)
{
    //general parameters
    double threshold_value = 10;
    string map_metric="maxlogMAP";
    ivec gen = "07 05";//octal form, feedback first
    int constraint_length = 3;
    int nb_errors_lim = 3000;
    int nb_bits_lim = int(1e6);
    int perm_len = (1<<14);//total number of bits in a block (with tail)
    int nb_iter = 10;//number of iterations in the turbo decoder
    vec EbN0_dB = "0:0.1:5";
    double R = 1.0/3.0;//coding rate (non punctured PCCC)
    double Ec = 1.0;//coded bit energy

    //other parameters
    int nb_bits = perm_len-(constraint_length-1);//number of bits in a block (without tail)
    vec sigma2 = (0.5*Ec/R)*pow(inv_dB(EbN0_dB), -1.0);//N0/2
    double Lc;//scaling factor
    int nb_blocks;//number of 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();
    bmat cod1_bits;//tail is added
    bvec tail;
    bvec cod2_input;
    bmat cod2_bits;
    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);//a priori LLR for information bits
    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;

    //Recursive Systematic Convolutional Code
    Rec_Syst_Conv_Code cc;
    cc.set_generator_polynomials(gen, constraint_length);//initial state should be the zero state

    //BPSK modulator
    BPSK bpsk;

    //AWGN channel
    AWGN_Channel channel;

    //SISO modules
    SISO siso;
    siso.set_generators(gen, constraint_length);
    siso.set_map_metric(map_metric);

    //BER
    BERC berc;

    //Randomize generators
    RNG_randomize();

    //main loop
    for (en=0;en<snr_len;en++)
    {
        cout << "EbN0_dB = " << EbN0_dB(en) << endl;
        channel.set_noise(sigma2(en));
        Lc = -2/sigma2(en);//normalisation factor for intrinsic information (take into account the BPSK mapping)
        nb_errors = 0;
        nb_blocks = 0;
        while ((nb_errors<nb_errors_lim) && (nb_blocks*nb_bits<nb_bits_lim))
        {
            //permutation
            perm = sort_index(randu(perm_len));
            //inverse permutation
            inv_perm = sort_index(perm);

            //bits generation
            bits = randb(nb_bits);

            //parallel concatenated convolutional code
            cc.encode_tail(bits, tail, cod1_bits);//tail is added here to information bits to close the trellis
            cod2_input = concat(bits, tail);
            cc.encode(cod2_input(perm), cod2_bits);
            for (n=0;n<perm_len;n++)//output with no puncturing
            {
                coded_bits(3*n) = cod2_input(n);//systematic output
                coded_bits(3*n+1) = cod1_bits(n,0);//first parity output
                coded_bits(3*n+2) = cod2_bits(n,0);//second parity output
            }

            //BPSK modulation (1->-1,0->+1) + AWGN channel
            rec = channel(bpsk.modulate_bits(coded_bits));

            //form input for SISO blocks
            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;//systematic output of the CC is already used in decoder1
                dec2_intrinsic_coded(2*n+1) = Lc*rec(3*n+2);
            }
            //turbo decoder
            apriori_data.zeros();//a priori LLR for information bits
            for (n=0;n<nb_iter;n++)
            {
                //first decoder (terminated trellis)
                siso.rsc(extrinsic_coded, extrinsic_data, dec1_intrinsic_coded, apriori_data, true);
                //interleave
                apriori_data = extrinsic_data(perm);
                //threshold
                apriori_data = SISO::threshold(apriori_data, threshold_value);
                //second decoder (unterminated trellis)
                siso.rsc(extrinsic_coded, extrinsic_data, dec2_intrinsic_coded, apriori_data);

                //decision
                apriori_data += extrinsic_data;//a posteriori information
                rec_bits = bpsk.demodulate_bits(-apriori_data(inv_perm));//take into account the BPSK mapping
                //count errors
                berc.clear();
                berc.count(bits, rec_bits.left(nb_bits));
                ber(n,en) += berc.get_errorrate();

                //deinterleave for the next iteration
                apriori_data = extrinsic_data(inv_perm);
            }//end iterations
            nb_errors += int(berc.get_errors());//get number of errors at the last iteration
            nb_blocks++;
        }//end blocks (while loop)

        //compute BER over all tx 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;
}
예제 #3
0
TEST(SISO, all)
{
    //general parameters
    string map_metric="maxlogMAP";
    ivec gen = "07 05";//octal form, feedback first
    int constraint_length = 3;
    int nb_errors_lim = 300;
    int nb_bits_lim = int(1e4);
    int perm_len = (1<<14);//total number of bits in a block (with tail)
    int nb_iter = 10;//number of iterations in the turbo decoder
    vec EbN0_dB = "0.0 0.5 1.0 1.5 2.0";
    double R = 1.0/3.0;//coding rate (non punctured PCCC)
    double Ec = 1.0;//coded bit energy

    //other parameters
    int nb_bits = perm_len-(constraint_length-1);//number of bits in a block (without tail)
    vec sigma2 = (0.5*Ec/R)*pow(inv_dB(EbN0_dB), -1.0);//N0/2
    double Lc;//scaling factor
    int nb_blocks;//number of 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();
    bmat cod1_bits;//tail is added
    bvec tail;
    bvec cod2_input;
    bmat cod2_bits;
    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);//a priori LLR for information bits
    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;

    //Recursive Systematic Convolutional Code
    Rec_Syst_Conv_Code cc;
    cc.set_generator_polynomials(gen, constraint_length);//initial state should be the zero state

    //BPSK modulator
    BPSK bpsk;

    //AWGN channel
    AWGN_Channel channel;

    //SISO modules
    SISO siso;
    siso.set_generators(gen, constraint_length);
    siso.set_map_metric(map_metric);

    //BER
    BERC berc;

    //Fix random generators
    RNG_reset(12345);

    //main loop
    for (en=0;en<snr_len;en++)
    {
        channel.set_noise(sigma2(en));
        Lc = -2/sigma2(en);//normalisation factor for intrinsic information (take into account the BPSK mapping)
        nb_errors = 0;
        nb_blocks = 0;
        while ((nb_errors<nb_errors_lim) && (nb_blocks*nb_bits<nb_bits_lim))//if at the last iteration the nb. of errors is inferior to lim, then process another block
        {
            //permutation
            perm = sort_index(randu(perm_len));
            //inverse permutation
            inv_perm = sort_index(perm);

            //bits generation
            bits = randb(nb_bits);

            //parallel concatenated convolutional code
            cc.encode_tail(bits, tail, cod1_bits);//tail is added here to information bits to close the trellis
            cod2_input = concat(bits, tail);
            cc.encode(cod2_input(perm), cod2_bits);
            for (n=0;n<perm_len;n++)//output with no puncturing
            {
                coded_bits(3*n) = cod2_input(n);//systematic output
                coded_bits(3*n+1) = cod1_bits(n,0);//first parity output
                coded_bits(3*n+2) = cod2_bits(n,0);//second parity output
            }

            //BPSK modulation (1->-1,0->+1) + AWGN channel
            rec = channel(bpsk.modulate_bits(coded_bits));

            //form input for SISO blocks
            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;//systematic output of the CC is already used in decoder1
                dec2_intrinsic_coded(2*n+1) = Lc*rec(3*n+2);
            }
            //turbo decoder
            apriori_data.zeros();//a priori LLR for information bits
            for (n=0;n<nb_iter;n++)
            {
                //first decoder
               siso.rsc(extrinsic_coded, extrinsic_data, dec1_intrinsic_coded, apriori_data, true);
                //interleave
                apriori_data = extrinsic_data(perm);
                //second decoder
                siso.rsc(extrinsic_coded, extrinsic_data, dec2_intrinsic_coded, apriori_data, false);

                //decision
                apriori_data += extrinsic_data;//a posteriori information
                rec_bits = bpsk.demodulate_bits(-apriori_data(inv_perm));//take into account the BPSK mapping
                //count errors
                berc.clear();
                berc.count(bits, rec_bits.left(nb_bits));
                ber(n,en) += berc.get_errorrate();

                //deinterleave for the next iteration
                apriori_data = extrinsic_data(inv_perm);
            }//end iterations
            nb_errors += int(berc.get_errors());//get number of errors at the last iteration
            nb_blocks++;
        }//end blocks (while loop)

        //compute BER over all tx blocks
        ber.set_col(en, ber.get_col(en)/nb_blocks);
    }

    // Results for max log MAP algorithm
    vec ref = "0.158039 0.110731 0.0770358 0.0445611 0.0235014";
    assert_vec(ref, ber.get_row(0));
    ref = "0.14168 0.0783177 0.0273471 0.00494445 0.00128189";
    assert_vec(ref, ber.get_row(1));
    ref = "0.141375 0.0565865 0.00817971 0.000305213 0";
    assert_vec(ref, ber.get_row(2));
    ref = "0.142412 0.0421194 0.000732511 0 0";
    assert_vec(ref, ber.get_row(3));
    ref = "0.144244 0.0282017 0.000183128 0 0";
    assert_vec(ref, ber.get_row(4));
    ref = "0.145587 0.0142229 0 0 0";
    assert_vec(ref, ber.get_row(5));
    ref = "0.148517 0.00714199 0 0 0";
    assert_vec(ref, ber.get_row(6));
    ref = "0.141619 0.00225858 0 0 0";
    assert_vec(ref, ber.get_row(7));
    ref = "0.149676 0.000549383 0 0 0";
    assert_vec(ref, ber.get_row(8));
    ref = "0.14461 0 0 0 0";
    assert_vec(ref, ber.get_row(9));
}