IT++ Logo
turbo.cpp
Go to the documentation of this file.
00001 
00029 #include <itpp/comm/turbo.h>
00030 
00031 
00032 namespace itpp
00033 {
00034 
00035 void Turbo_Codec::set_parameters(ivec gen1, ivec gen2, int constraint_length, const ivec &interleaver_sequence,
00036                                  int in_iterations, std::string in_metric, double in_logmax_scale_factor,
00037                                  bool in_adaptive_stop,  LLR_calc_unit in_llrcalc)
00038 {
00039   //Set the input parameters:
00040   iterations          = in_iterations;
00041   interleaver_size    = interleaver_sequence.size();
00042   Nuncoded            = interleaver_size;
00043   logmax_scale_factor = in_logmax_scale_factor;
00044   adaptive_stop       = in_adaptive_stop;
00045 
00046   //Check the decoding metric
00047   if (in_metric == "LOGMAX") {
00048     metric = "LOGMAX";
00049   }
00050   else if (in_metric == "LOGMAP") {
00051     metric = "LOGMAP";
00052   }
00053   else if (in_metric == "MAP") {
00054     metric = "MAP";
00055   }
00056   else if (in_metric == "TABLE") {
00057     metric = "TABLE";
00058   }
00059   else {
00060     it_error("Turbo_Codec::set_parameters: The decoder metric must be either MAP, LOGMAP or LOGMAX");
00061   }
00062 
00063   if (logmax_scale_factor != 1.0) {
00064     it_assert(metric == "LOGMAX", "Turbo_Codec::set_parameters: logmax_scale_factor can only be used together with LOGMAX decoding");
00065   }
00066 
00067   //The RSC Encoders:
00068   rscc1.set_generator_polynomials(gen1, constraint_length);
00069   rscc2.set_generator_polynomials(gen2, constraint_length);
00070   n1 = gen1.length() - 1; //Number of parity bits from rscc1
00071   n2 = gen2.length() - 1; //Number of parity bits from rscc2
00072   n_tot = 1 + n1 + n2;  //Total number of parity bits and systematic bits
00073 
00074   //Set the number of tail bits:
00075   m_tail = constraint_length - 1;
00076 
00077   //Calculate the number of coded bits per code-block:
00078   Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2);
00079 
00080   //Set the interleaver sequence
00081   bit_interleaver.set_interleaver_depth(interleaver_size);
00082   float_interleaver.set_interleaver_depth(interleaver_size);
00083   bit_interleaver.set_interleaver_sequence(interleaver_sequence);
00084   float_interleaver.set_interleaver_sequence(interleaver_sequence);
00085 
00086   //Default value of the channel reliability scaling factor is 1
00087   Lc = 1.0;
00088 
00089   // LLR algebra table
00090   rscc1.set_llrcalc(in_llrcalc);
00091   rscc2.set_llrcalc(in_llrcalc);
00092 
00093 }
00094 
00095 void Turbo_Codec::set_interleaver(const ivec &interleaver_sequence)
00096 {
00097   interleaver_size = interleaver_sequence.size();
00098   Nuncoded = interleaver_size;
00099 
00100   //Calculate the number of coded bits per code-block:
00101   Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2);
00102 
00103   //Set the interleaver sequence
00104   bit_interleaver.set_interleaver_depth(interleaver_size);
00105   float_interleaver.set_interleaver_depth(interleaver_size);
00106   bit_interleaver.set_interleaver_sequence(interleaver_sequence);
00107   float_interleaver.set_interleaver_sequence(interleaver_sequence);
00108 }
00109 
00110 void Turbo_Codec::set_metric(std::string in_metric, double in_logmax_scale_factor, LLR_calc_unit in_llrcalc)
00111 {
00112   logmax_scale_factor = in_logmax_scale_factor;
00113 
00114   //Check the decoding metric
00115   if (in_metric == "LOGMAX") {
00116     metric = "LOGMAX";
00117   }
00118   else if (in_metric == "LOGMAP") {
00119     metric = "LOGMAP";
00120   }
00121   else if (in_metric == "MAP") {
00122     metric = "MAP";
00123   }
00124   else if (in_metric == "TABLE") {
00125     metric = "TABLE";
00126   }
00127   else {
00128     it_error("Turbo_Codec::set_metric: The decoder metric must be either MAP, LOGMAP or LOGMAX");
00129   }
00130 
00131   rscc1.set_llrcalc(in_llrcalc);
00132   rscc2.set_llrcalc(in_llrcalc);
00133 }
00134 
00135 void Turbo_Codec::set_iterations(int in_iterations)
00136 {
00137   iterations = in_iterations;
00138 }
00139 
00140 void Turbo_Codec::set_adaptive_stop(bool in_adaptive_stop)
00141 {
00142   adaptive_stop = in_adaptive_stop;
00143 }
00144 
00145 void Turbo_Codec::set_awgn_channel_parameters(double in_Ec, double in_N0)
00146 {
00147   Ec = in_Ec;
00148   N0 = in_N0;
00149   Lc = 4.0 * std::sqrt(Ec) / N0;
00150 }
00151 
00152 void Turbo_Codec::set_scaling_factor(double in_Lc)
00153 {
00154   Lc = in_Lc;
00155 }
00156 
00157 
00158 void Turbo_Codec::encode(const bvec &input, bvec &output)
00159 {
00160   //Local variables:
00161   int i, k, j, no_blocks;
00162   int count;
00163   bvec input_bits, in1, in2, tail1, tail2, out;
00164   bmat parity1, parity2;
00165 
00166   //Initializations:
00167   no_blocks = input.length() / Nuncoded;
00168   output.set_size(no_blocks*Ncoded, false);
00169 
00170   //Set the bit counter to zero:
00171   count = 0;
00172 
00173   //Encode all code blocks:
00174   for (i = 0; i < no_blocks; i++) {
00175 
00176     //Encode one block
00177     input_bits = input.mid(i * Nuncoded, Nuncoded);
00178     encode_block(input_bits, in1, in2, parity1, parity2);
00179 
00180     //The data part:
00181     for (k = 0; k < Nuncoded; k++) {
00182       output(count) = in1(k);
00183       count++;                                //Systematic bits
00184       for (j = 0; j < n1; j++) { output(count) = parity1(k, j); count++; } //Parity-1 bits
00185       for (j = 0; j < n2; j++) { output(count) = parity2(k, j); count++; } //Parity-2 bits
00186     }
00187 
00188     //The first tail:
00189     for (k = 0; k < m_tail; k++) {
00190       output(count) = in1(Nuncoded + k);
00191       count++;                                //First systematic tail bit
00192       for (j = 0; j < n1; j++) { output(count) = parity1(Nuncoded + k, j); count++; } //Parity-1 tail bits
00193     }
00194 
00195     //The second tail:
00196     for (k = 0; k < m_tail; k++) {
00197       output(count) = in2(Nuncoded + k);
00198       count++;                                //Second systematic tail bit
00199       for (j = 0; j < n2; j++) { output(count) = parity2(Nuncoded + k, j); count++; } //Parity-2 tail bits
00200     }
00201 
00202   }
00203 
00204 }
00205 
00206 void Turbo_Codec::decode(const vec &received_signal, bvec &decoded_bits, const bvec &true_bits)
00207 {
00208   ivec nrof_used_iterations;
00209   decode(received_signal, decoded_bits, nrof_used_iterations, true_bits);
00210 }
00211 
00212 void Turbo_Codec::decode(const vec &received_signal, bvec &decoded_bits, ivec &nrof_used_iterations,
00213                          const bvec &true_bits)
00214 {
00215 
00216   if ((n1 == 1) && (n2 == 1) && (metric != "MAP")) {
00217     //This is a speed optimized decoder for R=1/3 (log domain metrics only)
00218     decode_n3(received_signal, decoded_bits, nrof_used_iterations, true_bits);
00219   }
00220   else {
00221 
00222     //Local variables:
00223     vec rec, rec_syst1, rec_syst2;
00224     mat rec_parity1, rec_parity2;
00225     bmat decoded_bits_i;
00226     int no_blocks, i, j, k, nrof_used_iterations_i;
00227     int count;
00228     bool CHECK_TRUE_BITS;
00229 
00230     //Initilaizations:
00231     no_blocks = received_signal.length() / Ncoded;
00232     decoded_bits.set_size(no_blocks * Nuncoded, false);
00233     decoded_bits_i.set_size(iterations, no_blocks * Nuncoded, false);
00234     rec_syst1.set_size(Nuncoded + m_tail, false);
00235     rec_syst2.set_size(Nuncoded + m_tail, false);
00236     rec_syst2.clear();
00237     rec_parity1.set_size(Nuncoded + m_tail, n1, false);
00238     rec_parity2.set_size(Nuncoded + m_tail, n2, false);
00239     nrof_used_iterations.set_size(no_blocks, false);
00240 
00241     //Check the vector true_bits:
00242     if (true_bits.size() > 1) {
00243       it_assert(true_bits.size() == (Nuncoded * no_blocks), "Turbo_Codec::decode: Wrong size of input vectors");
00244       CHECK_TRUE_BITS = true;
00245     }
00246     else {
00247       CHECK_TRUE_BITS = false;
00248     }
00249 
00250     //Set the bit counter to zero:
00251     count = 0;
00252 
00253     //Itterate over all received code blocks:
00254     for (i = 0; i < no_blocks; i++) {
00255 
00256       //The data part:
00257       for (k = 0; k < Nuncoded; k++) {
00258         rec_syst1(k) = received_signal(count);
00259         count++;                               //Systematic bit
00260         for (j = 0; j < n1; j++) { rec_parity1(k, j) = received_signal(count); count++; }  //Parity-1 bits
00261         for (j = 0; j < n2; j++) { rec_parity2(k, j) = received_signal(count); count++; }  //Parity-2 bits
00262       }
00263 
00264       //The first tail:
00265       for (k = 0; k < m_tail; k++) {
00266         rec_syst1(Nuncoded + k) = received_signal(count);
00267         count++;                               //Tail 1 systematic bit
00268         for (j = 0; j < n1; j++) { rec_parity1(Nuncoded + k, j) = received_signal(count); count++; }  //Tail 1 parity-1 bits
00269       }
00270 
00271       //The second tail:
00272       for (k = 0; k < m_tail; k++) {
00273         rec_syst2(Nuncoded + k) = received_signal(count);
00274         count++;                              //Tail2 systematic bit
00275         for (j = 0; j < n2; j++) { rec_parity2(Nuncoded + k, j) = received_signal(count); count++; } //Tali2 parity-2 bits
00276       }
00277 
00278       //Scale the input data if necessary:
00279       if (Lc != 1.0) {
00280         rec_syst1 *= Lc;
00281         rec_syst2 *= Lc;
00282         rec_parity1 *= Lc;
00283         rec_parity2 *= Lc;
00284       }
00285 
00286       //Decode the block:
00287       if (CHECK_TRUE_BITS) {
00288         decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i,
00289                      nrof_used_iterations_i, true_bits.mid(i*Nuncoded, Nuncoded));
00290         nrof_used_iterations(i) = nrof_used_iterations_i;
00291       }
00292       else {
00293         decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i, nrof_used_iterations_i);
00294         nrof_used_iterations(i) = nrof_used_iterations_i;
00295       }
00296 
00297       //Put the decoded bits in the output vector:
00298       decoded_bits.replace_mid(i*Nuncoded, decoded_bits_i.get_row(iterations - 1));
00299 
00300     }
00301 
00302   }
00303 
00304 }
00305 
00306 void Turbo_Codec::encode_block(const bvec &input, bvec &in1, bvec &in2, bmat &parity1, bmat &parity2)
00307 {
00308   //Local variables:
00309   bvec tail1, tail2, interleaved_input;
00310 
00311   //Error check:
00312   it_assert(input.length() == Nuncoded, "Turbo_Codec::encode_block: Parameter error in Nuncoded.");
00313 
00314   //Initializations:
00315   tail1.set_size(m_tail, false);
00316   tail1.clear();
00317   tail2.set_size(m_tail, false);
00318   tail2.clear();
00319   parity1.set_size(Nuncoded + m_tail, n1, false);
00320   parity1.clear();
00321   parity2.set_size(Nuncoded + m_tail, n2, false);
00322   parity2.clear();
00323   interleaved_input.set_size(Nuncoded, false);
00324   interleaved_input.clear();
00325 
00326   //The first encoder:
00327   rscc1.encode_tail(input, tail1, parity1);
00328 
00329   //The interleaver:
00330   bit_interleaver.interleave(input, interleaved_input);
00331 
00332   //The second encoder:
00333   rscc2.encode_tail(interleaved_input, tail2, parity2);
00334 
00335   //The input vectors used to the two constituent encoders:
00336   in1 = concat(input, tail1);
00337   in2 = concat(interleaved_input, tail2);
00338 
00339 }
00340 
00341 void Turbo_Codec::decode_block(const vec &rec_syst1, const vec &rec_syst2, const mat &rec_parity1,
00342                                const mat &rec_parity2, bmat &decoded_bits_i, int &nrof_used_iterations_i,
00343                                const bvec &true_bits)
00344 {
00345   //Local variables:
00346   int i;
00347   int count, l, k;
00348   vec extrinsic_input, extrinsic_output, int_rec_syst1, int_rec_syst, tmp;
00349   vec deint_rec_syst2, rec_syst, sub_rec_syst, Le12, Le21, Le12_int, Le21_int, L, tail1, tail2;
00350   bool CHECK_TRUE_BITS, CONTINUE;
00351 
00352   //Size initializations:
00353   decoded_bits_i.set_size(iterations, Nuncoded, false);
00354   Le12.set_size(Nuncoded + m_tail, false);
00355   Le21.set_size(Nuncoded + m_tail, false);
00356   Le21.zeros();
00357 
00358   //Calculate the interleaved and the deinterleaved sequences:
00359   float_interleaver.interleave(rec_syst1.left(interleaver_size), int_rec_syst1);
00360   float_interleaver.deinterleave(rec_syst2.left(interleaver_size), deint_rec_syst2);
00361 
00362   //Combine the results from rec_syst1 and rec_syst2 (in case some bits are transmitted several times)
00363   rec_syst = rec_syst1.left(interleaver_size) + deint_rec_syst2;
00364   int_rec_syst = rec_syst2.left(interleaver_size) + int_rec_syst1;
00365 
00366   //Get the two tails
00367   tail1 = rec_syst1.right(m_tail);
00368   tail2 = rec_syst2.right(m_tail);
00369 
00370   //Form the input vectors (including tails) to the two decoders:
00371   rec_syst = concat(rec_syst, tail1);
00372   int_rec_syst = concat(int_rec_syst, tail2);
00373 
00374   // Check the vector true_bits
00375   if (true_bits.size() > 1) {
00376     it_assert(true_bits.size() == Nuncoded, "Turbo_Codec::decode_block: Illegal size of input vector true_bits");
00377     CHECK_TRUE_BITS = true;
00378   }
00379   else {
00380     CHECK_TRUE_BITS = false;
00381   }
00382 
00383   if (CHECK_TRUE_BITS) {
00384     it_assert(adaptive_stop == false,
00385               "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits");
00386   }
00387 
00388   // Do the iterative decoding:
00389   nrof_used_iterations_i = iterations;
00390   for (i = 0; i < iterations; i++) {
00391 
00392     // Decode Code 1
00393     if (metric == "MAP") {
00394       rscc1.map_decode(rec_syst, rec_parity1, Le21, Le12, true);
00395     }
00396     else if ((metric == "LOGMAX") || (metric == "LOGMAP") || (metric == "TABLE")) {
00397       rscc1.log_decode(rec_syst, rec_parity1, Le21, Le12, true, metric);
00398       if (logmax_scale_factor != 1.0) {
00399         Le12 *= logmax_scale_factor;
00400       }
00401     }
00402     else {
00403       it_error("Turbo_Codec::decode_block: Illegal metric value");
00404     }
00405 
00406     // Interleave the extrinsic information:
00407     float_interleaver.interleave(Le12.left(interleaver_size), tmp);
00408     Le12_int = concat(tmp, zeros(Le12.size() - interleaver_size));
00409 
00410     // Decode Code 2
00411     if (metric == "MAP") {
00412       rscc2.map_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int, true);
00413     }
00414     else if ((metric == "LOGMAX") || (metric == "LOGMAP")  || (metric == "TABLE")) {
00415       rscc2.log_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int, true, metric);
00416       if (logmax_scale_factor != 1.0) {
00417         Le21_int *= logmax_scale_factor;
00418       }
00419     }
00420     else {
00421       it_error("Turbo_Codec::decode_block: Illegal metric value");
00422     }
00423 
00424     // De-interleave the extrinsic information:
00425     float_interleaver.deinterleave(Le21_int.left(interleaver_size), tmp);
00426     Le21 = concat(tmp, zeros(Le21_int.size() - interleaver_size));
00427 
00428     // Take bit decisions
00429     L = rec_syst + Le21 + Le12;
00430     count = 0;
00431     for (l = 0; l < Nuncoded; l++) {
00432       (L(l) > 0.0) ? (decoded_bits_i(i, count) = bin(0)) : (decoded_bits_i(i, count) = bin(1));
00433       count++;
00434     }
00435 
00436     //Check if it is possible to stop iterating early:
00437     CONTINUE = true;
00438     if (i < (iterations - 1)) {
00439 
00440       if (CHECK_TRUE_BITS) {
00441         CONTINUE = false;
00442         for (k = 0; k < Nuncoded; k++) { if (true_bits(k) != decoded_bits_i(i, k)) { CONTINUE = true; break; } }
00443       }
00444 
00445       if ((adaptive_stop) && (i > 0)) {
00446         CONTINUE = false;
00447         for (k = 0; k < Nuncoded; k++) { if (decoded_bits_i(i - 1, k) != decoded_bits_i(i, k)) { CONTINUE = true; break; } }
00448       }
00449 
00450     }
00451 
00452     //Check if iterations shall continue:
00453     if (CONTINUE == false) {
00454       //Copy the results from current iteration to all following iterations:
00455       for (k = (i + 1); k < iterations; k++) {
00456         decoded_bits_i.set_row(k, decoded_bits_i.get_row(i));
00457         nrof_used_iterations_i = i + 1;
00458       }
00459       break;
00460     }
00461 
00462   }
00463 
00464 }
00465 
00466 void Turbo_Codec::decode_n3(const vec &received_signal, bvec &decoded_bits, ivec &nrof_used_iterations,
00467                             const bvec &true_bits)
00468 {
00469   //Local variables:
00470   vec rec, rec_syst1, int_rec_syst1, rec_syst2;
00471   vec rec_parity1, rec_parity2;
00472   vec extrinsic_input, extrinsic_output, Le12, Le21, Le12_int, Le21_int, L;
00473   bvec temp_decoded_bits;
00474   int no_blocks, i, j, k, l, nrof_used_iterations_i;
00475   int count, count_out;
00476   bool CHECK_TRUE_BITS, CONTINUE;
00477 
00478   //Initializations:
00479   no_blocks = received_signal.length() / Ncoded;
00480   decoded_bits.set_size(no_blocks * Nuncoded, false);
00481   rec_syst1.set_size(Nuncoded + m_tail, false);
00482   rec_syst2.set_size(Nuncoded + m_tail, false);
00483   rec_syst2.clear();
00484   rec_parity1.set_size(Nuncoded + m_tail, false);
00485   rec_parity2.set_size(Nuncoded + m_tail, false);
00486   temp_decoded_bits.set_size(Nuncoded, false);
00487   decoded_bits_previous_iteration.set_size(Nuncoded, false);
00488   nrof_used_iterations.set_size(no_blocks, false);
00489 
00490   //Size initializations:
00491   Le12.set_size(Nuncoded, false);
00492   Le21.set_size(Nuncoded, false);
00493 
00494   //Set the bit counter to zero:
00495   count = 0;
00496   count_out = 0;
00497 
00498   // Check the vector true_bits
00499   if (true_bits.size() > 1) {
00500     it_assert(true_bits.size() == Nuncoded*no_blocks, "Turbo_Codec::decode_n3: Illegal size of input vector true_bits");
00501     CHECK_TRUE_BITS = true;
00502   }
00503   else {
00504     CHECK_TRUE_BITS = false;
00505   }
00506 
00507   if (CHECK_TRUE_BITS) {
00508     it_assert(adaptive_stop == false,
00509               "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits");
00510   }
00511 
00512   //Iterate over all received code blocks:
00513   for (i = 0; i < no_blocks; i++) {
00514 
00515     //Reset extrinsic data:
00516     Le21.zeros();
00517 
00518     //The data part:
00519     for (k = 0; k < Nuncoded; k++) {
00520       rec_syst1(k)   = received_signal(count);
00521       count++; //Systematic bit
00522       rec_parity1(k) = received_signal(count);
00523       count++; //Parity-1 bits
00524       rec_parity2(k) = received_signal(count);
00525       count++; //Parity-2 bits
00526     }
00527 
00528     //The first tail:
00529     for (k = 0; k < m_tail; k++) {
00530       rec_syst1(Nuncoded + k)   = received_signal(count);
00531       count++; //Tail 1 systematic bit
00532       rec_parity1(Nuncoded + k) = received_signal(count);
00533       count++; //Tail 1 parity-1 bits
00534     }
00535 
00536     //The second tail:
00537     for (k = 0; k < m_tail; k++) {
00538       rec_syst2(Nuncoded + k)   = received_signal(count);
00539       count++; //Tail2 systematic bit
00540       rec_parity2(Nuncoded + k) = received_signal(count);
00541       count++; //Tali2 parity-2 bits
00542     }
00543 
00544     float_interleaver.interleave(rec_syst1.left(Nuncoded), int_rec_syst1);
00545     rec_syst2.replace_mid(0, int_rec_syst1);
00546 
00547     //Scale the input data if necessary:
00548     if (Lc != 1.0) {
00549       rec_syst1   *= Lc;
00550       rec_syst2   *= Lc;
00551       rec_parity1 *= Lc;
00552       rec_parity2 *= Lc;
00553     }
00554 
00555     //Decode the block:
00556     CONTINUE = true;
00557     nrof_used_iterations_i = iterations;
00558     for (j = 0; j < iterations; j++) {
00559 
00560       rscc1.log_decode_n2(rec_syst1, rec_parity1, Le21, Le12, true, metric);
00561       if (logmax_scale_factor != 1.0) { Le12 *= logmax_scale_factor; }
00562       float_interleaver.interleave(Le12, Le12_int);
00563 
00564       rscc2.log_decode_n2(rec_syst2, rec_parity2, Le12_int, Le21_int, true, metric);
00565       if (logmax_scale_factor != 1.0) { Le21_int *= logmax_scale_factor; }
00566       float_interleaver.deinterleave(Le21_int, Le21);
00567 
00568       if (adaptive_stop) {
00569         L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded);
00570         for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); }
00571         if (j == 0) { decoded_bits_previous_iteration = temp_decoded_bits; }
00572         else {
00573           if (temp_decoded_bits == decoded_bits_previous_iteration) {
00574             CONTINUE = false;
00575           }
00576           else if (j < (iterations - 1)) {
00577             decoded_bits_previous_iteration = temp_decoded_bits;
00578           }
00579         }
00580       }
00581 
00582       if (CHECK_TRUE_BITS) {
00583         L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded);
00584         for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); }
00585         if (temp_decoded_bits == true_bits.mid(i*Nuncoded, Nuncoded)) {
00586           CONTINUE = false;
00587         }
00588       }
00589 
00590       if (CONTINUE == false) { nrof_used_iterations_i = j + 1; break; }
00591 
00592     }
00593 
00594     //Take final bit decisions
00595     L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded);
00596     for (l = 0; l < Nuncoded; l++) {
00597       (L(l) > 0.0) ? (decoded_bits(count_out) = bin(0)) : (decoded_bits(count_out) = bin(1));
00598       count_out++;
00599     }
00600 
00601     nrof_used_iterations(i) = nrof_used_iterations_i;
00602 
00603   }
00604 
00605 }
00606 
00607 ivec wcdma_turbo_interleaver_sequence(int interleaver_size)
00608 {
00609   const int MAX_INTERLEAVER_SIZE = 5114;
00610   const int MIN_INTERLEAVER_SIZE = 40;
00611   int K;  //Interleaver size
00612   int R;  //Number of rows of rectangular matrix
00613   int C;  //Number of columns of rectangular matrix
00614   int p;  //Prime number
00615   int v;  //Primitive root
00616   ivec s; //Base sequence for intra-row permutation
00617   ivec q; //Minimum prime integers
00618   ivec r; //Permuted prime integers
00619   ivec T; //Inter-row permutation pattern
00620   imat U; //Intra-row permutation patter
00621   ivec I; //The interleaver sequence
00622   ivec primes, roots, Pat1, Pat2, Pat3, Pat4, Isort;
00623   int i, j, qj, temp, row, col, index, count;
00624 
00625   if (interleaver_size > MAX_INTERLEAVER_SIZE) {
00626 
00627     I = sort_index(randu(interleaver_size));
00628     return I;
00629 
00630   }
00631   else {
00632 
00633     p = 0;
00634     v = 0;
00635 
00636     //Check the range of the interleaver size:
00637     it_assert(interleaver_size <= MAX_INTERLEAVER_SIZE, "wcdma_turbo_interleaver_sequence: The interleaver size is to large");
00638     it_assert(interleaver_size >= MIN_INTERLEAVER_SIZE, "wcdma_turbo_interleaver_sequence: The interleaver size is to small");
00639 
00640     K = interleaver_size;
00641 
00642     //Definitions of primes and associated primitive roots:
00643     primes = "2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257";
00644     roots = "0 0 0 3 2 2 3 2 5 2 3 2 6 3 5 2 2 2 2 7 5 3 2 3 5 2 5 2 6 3 3 2 3 2 2 6 5 2 5 2 2 2 19 5 2 3 2 3 2 6 3 7 7 6 3";
00645 
00646     //Determine R
00647     if ((K >= 40) && (K <= 159)) {
00648       R = 5;
00649     }
00650     else if (((K >= 160) && (K <= 200)) || ((K >= 481) && (K <= 530))) {
00651       R = 10;
00652     }
00653     else {
00654       R = 20;
00655     }
00656 
00657     //Determine C
00658     if ((K >= 481) && (K <= 530)) {
00659       p = 53;
00660       v = 2;
00661       C = p;
00662     }
00663     else {
00664       //Find minimum prime p such that (p+1) - K/R >= 0 ...
00665       for (i = 0; i < primes.length(); i++) {
00666         if ((double(primes(i) + 1) - double(K) / double(R)) >= 0.0) {
00667           p = primes(i);
00668           v = roots(i);
00669           break;
00670         }
00671       }
00672       //... and etermine C such that
00673       if ((double(p) - double(K) / double(R)) >= 0.0) {
00674         if ((double(p) - 1.0 - double(K) / double(R)) >= 0.0) {
00675           C = p - 1;
00676         }
00677         else {
00678           C = p;
00679         }
00680       }
00681       else {
00682         C = p + 1;
00683       }
00684     }
00685 
00686     //Construct the base sequencs s for intra-row permutaions
00687     s.set_size(p - 1, false);
00688     s.clear();
00689     s(0) = 1;
00690     for (i = 1; i <= (p - 2); i++) {
00691       s(i) = mod(v * s(i - 1), p);
00692     }
00693 
00694     //Let q(0) = 1 be the first prime integer in {q(j)}, and select the consecutive
00695     //minimum prime integers {q(j)}, j = 1, 2, ..., (R-1) such that gcd( q(j), p-1) == 1, q(j) > 6, and q(j) > q(j-1)
00696     q.set_size(R, false);
00697     q.clear();
00698     q(0) = 1;
00699     for (j = 1; j <= (R - 1); j++) {
00700       for (i = 0; i < primes.length(); i++) {
00701         qj = primes(i);
00702         if ((qj > 6) && (qj > q(j - 1))) {
00703           if (gcd(qj, p - 1) == 1) {
00704             q(j) = qj;
00705             break;
00706           }
00707         }
00708       }
00709     }
00710 
00711     //Definitions of Pat1, Pat2, Pat3, and Pat4:
00712     Pat1 = "19 9 14 4 0 2 5 7 12 18 10 8 13 17 3 1 16 6 15 11";
00713     Pat2 = "19 9 14 4 0 2 5 7 12 18 16 13 17 15 3 1 6 11 8 10";
00714     Pat3 = "9 8 7 6 5 4 3 2 1 0";
00715     Pat4 = "4 3 2 1 0";
00716 
00717     //T(j) is the inter-row permutation patters defined as one of the following four
00718     //kinds of patterns: Pat1, Pat2, Pat3, and Pat4 depending on the number of input bits K
00719     if (K >= 3211) {
00720       T = Pat1;
00721     }
00722     else if (K >= 3161) {
00723       T = Pat2;
00724     }
00725     else if (K >= 2481) {
00726       T = Pat1;
00727     }
00728     else if (K >= 2281) {
00729       T = Pat2;
00730     }
00731     else if (K >= 531) {
00732       T = Pat1;
00733     }
00734     else if (K >= 481) {
00735       T = Pat3;
00736     }
00737     else if (K >= 201) {
00738       T = Pat1;
00739     }
00740     else if (K >= 160) {
00741       T = Pat3;
00742     }
00743     else {
00744       T = Pat4;
00745     }
00746 
00747     //Permute {q(j)} to make {r(j)} such that r(T(j)) = q(j), j = 0, 1, ..., (R-1),
00748     //where T(j) indicates the original row position of the j-th permuted row
00749     r.set_size(R, false);
00750     r.clear();
00751     for (j = 0; j <= (R - 1); j++) {
00752       r(T(j)) = q(j);
00753     }
00754 
00755     //U(j,i) is the input bit position of i-th output after the permutation of j-th row
00756     //Perform the j-th (j=0, 1, 2, ..., (R-1)) intra-row permutation as
00757     U.set_size(R, C, false);
00758     U.clear();
00759     if (C == p) {
00760       for (j = 0; j <= (R - 1); j++) {
00761         for (i = 0; i <= (p - 2); i++) {
00762           U(j, i) = s(mod(i * r(j), p - 1));
00763         }
00764         U(j, p - 1) = 0;
00765       }
00766     }
00767     else if (C == (p + 1)) {
00768       for (j = 0; j <= (R - 1); j++) {
00769         for (i = 0; i <= (p - 2); i++) {
00770           U(j, i) = s(mod(i * r(j), p - 1));
00771         }
00772         U(j, p - 1) = 0;
00773         U(j, p) = p;
00774       }
00775       if (K == (C*R)) {
00776         temp = U(R - 1, p);
00777         U(R - 1, p) = U(R - 1, 0);
00778         U(R - 1, 0) = temp;
00779       }
00780     }
00781     else if (C == (p - 1)) {
00782       for (j = 0; j <= (R - 1); j++) {
00783         for (i = 0; i <= (p - 2); i++) {
00784           U(j, i) = s(mod(i * r(j), p - 1)) - 1;
00785         }
00786       }
00787     }
00788 
00789     //Calculate the interleaver sequence:
00790     I.set_size(K, false);
00791     I.clear();
00792     count = 0;
00793     for (i = 0; i < C; i++) {
00794       for (j = 0; j < R; j++) {
00795         row = T(j);
00796         col = U(row, i);
00797         index = row * C + col;
00798         if (index < K) {
00799           I(count) = index;
00800           count++;
00801         }
00802       }
00803     }
00804 
00805     return I;
00806   }
00807 }
00808 
00809 } // namespace itpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4