IT++ Logo
interleave.h
Go to the documentation of this file.
00001 
00030 #ifndef INTERLEAVE_H
00031 #define INTERLEAVE_H
00032 
00033 #ifndef _MSC_VER
00034 #  include <itpp/config.h>
00035 #else
00036 #  include <itpp/config_msvc.h>
00037 #endif
00038 
00039 #include <itpp/base/vec.h>
00040 #include <itpp/base/mat.h>
00041 #include <itpp/base/random.h>
00042 #include <itpp/base/sort.h>
00043 
00044 
00045 namespace itpp
00046 {
00047 
00067 template <class T>
00068 class Block_Interleaver
00069 {
00070 public:
00072   Block_Interleaver(void) {rows = 0; cols = 0;};
00074   Block_Interleaver(int in_rows, int in_cols);
00076   Vec<T> interleave(const Vec<T> &input);
00078   void interleave(const Vec<T> &input, Vec<T> &output);
00080   Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00082   void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00084   void set_rows(int in_rows) {rows = in_rows;};
00086   void set_cols(int in_cols) {cols = in_cols;};
00088   int get_rows(void) {return rows;};
00090   int get_cols(void) {return cols;};
00091 private:
00092   int rows, cols, input_length;
00093 };
00094 
00114 template <class T>
00115 class Cross_Interleaver
00116 {
00117 public:
00119   Cross_Interleaver(void) {order = 0;};
00121   Cross_Interleaver(int in_order);
00123   Vec<T> interleave(const Vec<T> &input);
00125   void interleave(const Vec<T> &input, Vec<T> &output);
00127   Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00129   void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00131   void set_order(int in_order);
00133   int get_order(void) {return order;};
00134 private:
00135   int order;
00136   int input_length;
00137   Mat<T> inter_matrix;
00138   Vec<T> tempvec, zerostemp;
00139 };
00140 
00157 template <class T>
00158 class Sequence_Interleaver
00159 {
00160 public:
00162   Sequence_Interleaver(void) {interleaver_depth = 0;};
00168   Sequence_Interleaver(int in_interleaver_depth);
00174   Sequence_Interleaver(ivec in_interleaver_sequence);
00176   Vec<T> interleave(const Vec<T> &input);
00178   void interleave(const Vec<T> &input, Vec<T> &output);
00180   Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00182   void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00184   void randomize_interleaver_sequence();
00186   ivec get_interleaver_sequence();
00188   void set_interleaver_sequence(ivec in_interleaver_sequence);
00190   void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; };
00192   int get_interleaver_depth(void) { return interleaver_depth; };
00193 private:
00194   ivec interleaver_sequence;
00195   int interleaver_depth, input_length;
00196 };
00197 
00198 //-----------------------------------------------------------------------------
00199 // Implementation of templated members starts here
00200 //-----------------------------------------------------------------------------
00201 
00202 //-------------------------- Block Interleaver ---------------------------------
00203 
00204 template<class T>
00205 Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols)
00206 {
00207   rows = in_rows;
00208   cols = in_cols;
00209   input_length = 0;
00210 }
00211 
00212 template<class T>
00213 void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00214 {
00215   input_length = input.length();
00216   int steps = (int)std::ceil(double(input_length) / double(rows * cols));
00217   int output_length = steps * rows * cols;
00218   output.set_length(output_length, false);
00219   int s, r, c;
00220 
00221   if (input_length == output_length) {
00222     //Block interleaver loop: All steps.
00223     for (s = 0; s < steps; s++) {
00224       for (c = 0; c < cols; c++) {
00225         for (r = 0; r < rows; r++) {
00226           output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
00227         }
00228       }
00229     }
00230   }
00231   else {
00232     //Block interleaver loop: All, but the last, steps.
00233     for (s = 0; s < steps - 1; s++) {
00234       for (c = 0; c < cols; c++) {
00235         for (r = 0; r < rows; r++) {
00236           output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
00237         }
00238       }
00239     }
00240     //The last step.
00241     Vec<T> zerovect(output_length - input_length);
00242     zerovect.clear();
00243     Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
00244     for (c = 0; c < cols; c++) {
00245       for (r = 0; r < rows; r++) {
00246         output((steps - 1)*rows*cols + r*cols + c) = temp_last_input(c * rows + r);
00247       }
00248     }
00249   }
00250 }
00251 
00252 template<class T>
00253 Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input)
00254 {
00255   Vec<T> output;
00256   interleave(input, output);
00257   return output;
00258 }
00259 
00260 template<class T>
00261 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00262 {
00263   int thisinput_length = input.length();
00264   int steps = (int)std::ceil(double(thisinput_length) / double(rows * cols));
00265   int output_length = steps * rows * cols;
00266   output.set_size(output_length, false);
00267   int s, r, c;
00268 
00269   if (thisinput_length == output_length) {
00270     //Block deinterleaver loop: All, but the last, steps.
00271     for (s = 0; s < steps; s++) {
00272       for (r = 0; r < rows; r++) {
00273         for (c = 0; c < cols; c++) {
00274           output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
00275         }
00276       }
00277     }
00278   }
00279   else {
00280     //Block deinterleaver loop: All, but the last, steps.
00281     for (s = 0; s < steps - 1; s++) {
00282       for (r = 0; r < rows; r++) {
00283         for (c = 0; c < cols; c++) {
00284           output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
00285         }
00286       }
00287     }
00288     //The last step.
00289     Vec<T> zerovect(output_length - thisinput_length);
00290     zerovect.clear();
00291     Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
00292     for (r = 0; r < rows; r++) {
00293       for (c = 0; c < cols; c++) {
00294         output((steps - 1)*rows*cols + c*rows + r) = temp_last_input(r * cols + c);
00295       }
00296     }
00297   }
00298   if (keepzeros == 0)
00299     output.set_size(input_length, true);
00300 }
00301 
00302 template<class T>
00303 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00304 {
00305   Vec<T> output;
00306   deinterleave(input, output, keepzeros);
00307   return output;
00308 }
00309 
00310 //---------------------------- Cross Interleaver ---------------------------
00311 
00312 template<class T>
00313 Cross_Interleaver<T>::Cross_Interleaver(int in_order)
00314 {
00315   order = in_order;
00316   input_length = 0;
00317   inter_matrix.set_size(order, order, false);
00318   tempvec.set_size(order, false);
00319   zerostemp.set_size(order, false);
00320 }
00321 
00322 template<class T>
00323 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00324 {
00325   input_length = input.length();
00326   int steps = (int)std::ceil(float(input_length) / order) + order;
00327   int output_length = steps * order;
00328   output.set_length(output_length, false);
00329   int i, r, c;
00330 
00331   inter_matrix.clear();
00332   zerostemp.clear();
00333 
00334   //Cross interleaver loop:
00335   for (i = 0; i < steps; i++) {
00336 
00337     //Shift the matrix to the right:
00338     for (c = order - 1; c > 0; c--)
00339       inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
00340 
00341     // Write the new data to the matrix
00342     if ((i*order + order) < input_length)
00343       tempvec = input.mid(i * order, order);
00344     else if ((i*order) < input_length)
00345       tempvec = concat(input.right(input_length - i * order), zerostemp.left(order - (input_length - i * order)));
00346     else
00347       tempvec.clear();
00348     inter_matrix.set_col(0, tempvec);
00349 
00350     //Read the matrix diagonal-wise:
00351     for (r = 0; r < order; r++)
00352       output(i*order + r) = inter_matrix(r, r);
00353   }
00354 }
00355 
00356 template<class T>
00357 Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input)
00358 {
00359   Vec<T> output;
00360   interleave(input, output);
00361   return output;
00362 }
00363 
00364 template<class T>
00365 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00366 {
00367   int thisinput_length = input.length();
00368   int steps = (int)std::ceil(float(thisinput_length) / order) + order;
00369   int output_length = steps * order;
00370   output.set_size(output_length, false);
00371   int i, r, c;
00372 
00373   inter_matrix.clear();
00374   zerostemp.clear();
00375 
00376   //Cross interleaver loop:
00377   for (i = 0; i < steps; i++) {
00378 
00379     //Shift the matrix to the right:
00380     for (c = order - 1; c > 0; c--)
00381       inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
00382 
00383     // Write the new data to the matrix
00384     if ((i*order + order) < thisinput_length)
00385       tempvec = input.mid(i * order, order);
00386     else if ((i*order) < thisinput_length)
00387       tempvec = concat(input.right(thisinput_length - i * order), zerostemp.left(order - (thisinput_length - i * order)));
00388     else
00389       tempvec.clear();
00390     inter_matrix.set_col(0, tempvec);
00391 
00392     //Read the matrix diagonal-wise:
00393     for (r = 0; r < order; r++)
00394       output(i*order + r)  = inter_matrix(r, order - 1 - r);
00395   }
00396   if (keepzeros == 0)
00397     output = output.mid(round_i(std::pow(double(order), 2)) - order, input_length);
00398 }
00399 
00400 template<class T>
00401 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00402 {
00403   Vec<T> output;
00404   deinterleave(input, output, keepzeros);
00405   return output;
00406 }
00407 
00408 template<class T>
00409 void Cross_Interleaver<T>::set_order(int in_order)
00410 {
00411   order = in_order;
00412   input_length = 0;
00413   inter_matrix.set_size(order, order, false);
00414   tempvec.set_size(order, false);
00415   zerostemp.set_size(order, false);
00416 }
00417 
00418 //------------------- Sequence Interleaver --------------------------------
00419 
00420 template<class T>
00421 Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth)
00422 {
00423   interleaver_depth = in_interleaver_depth;
00424   interleaver_sequence = sort_index(randu(in_interleaver_depth));
00425   input_length = 0;
00426 }
00427 
00428 template<class T>
00429 Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence)
00430 {
00431   interleaver_depth = in_interleaver_sequence.length();
00432   interleaver_sequence = in_interleaver_sequence;
00433   input_length = 0;
00434 }
00435 
00436 template<class T>
00437 void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00438 {
00439   input_length = input.length();
00440   int steps = (int)std::ceil(double(input_length) / double(interleaver_depth));
00441   int output_length = steps * interleaver_depth;
00442   output.set_size(output_length, false);
00443   int s, i;
00444 
00445   if (input_length == output_length) {
00446 
00447     //Sequence interleaver loop: All steps.
00448     for (s = 0; s < steps; s++) {
00449       for (i = 0; i < interleaver_depth; i++) {
00450         output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
00451       }
00452     }
00453 
00454   }
00455   else {
00456 
00457     //Sequence interleaver loop: All, but the last, steps.
00458     for (s = 0; s < steps - 1; s++) {
00459       for (i = 0; i < interleaver_depth; i++) {
00460         output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
00461       }
00462     }
00463     //The last step.
00464     Vec<T> zerovect(output_length - input_length);
00465     zerovect.clear();
00466     Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
00467     for (i = 0; i < interleaver_depth; i++) {
00468       output((steps - 1)*interleaver_depth + i) = temp_last_input(interleaver_sequence(i));
00469     }
00470 
00471   }
00472 }
00473 
00474 template<class T>
00475 Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input)
00476 {
00477   Vec<T> output;
00478   interleave(input, output);
00479   return output;
00480 }
00481 
00482 template<class T>
00483 void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00484 {
00485   int thisinput_length = input.length();
00486   int steps = (int)std::ceil(double(thisinput_length) / double(interleaver_depth));
00487   int output_length = steps * interleaver_depth;
00488   output.set_length(output_length, false);
00489   int s, i;
00490 
00491   if (thisinput_length == output_length) {
00492 
00493     //Sequence interleaver loop: All steps.
00494     for (s = 0; s < steps; s++) {
00495       for (i = 0; i < interleaver_depth; i++) {
00496         output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
00497       }
00498     }
00499 
00500   }
00501   else {
00502     //Sequence interleaver loop: All, but the last, steps.
00503     for (s = 0; s < steps - 1; s++) {
00504       for (i = 0; i < interleaver_depth; i++) {
00505         output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
00506       }
00507     }
00508     //The last step.
00509     Vec<T> zerovect(output_length - thisinput_length);
00510     zerovect.clear();
00511     Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
00512     for (i = 0; i < interleaver_depth; i++) {
00513       output((steps - 1)*interleaver_depth + interleaver_sequence(i)) = temp_last_input(i);
00514     }
00515     if (keepzeros == 0)
00516       output.set_size(input_length, true);
00517   }
00518 
00519 }
00520 
00521 template<class T>
00522 Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00523 {
00524   Vec<T> output;
00525   deinterleave(input, output, keepzeros);
00526   return output;
00527 }
00528 
00529 template<class T>
00530 void Sequence_Interleaver<T>::randomize_interleaver_sequence()
00531 {
00532   interleaver_sequence = sort_index(randu(interleaver_depth));
00533 }
00534 
00535 template<class T>
00536 ivec Sequence_Interleaver<T>::get_interleaver_sequence()
00537 {
00538   return interleaver_sequence;
00539 }
00540 
00541 template<class T>
00542 void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence)
00543 {
00544   interleaver_sequence = in_interleaver_sequence;
00545   interleaver_depth = interleaver_sequence.size();
00546 }
00547 
00549 
00550 // ----------------------------------------------------------------------
00551 // Instantiations
00552 // ----------------------------------------------------------------------
00553 
00554 #ifdef HAVE_EXTERN_TEMPLATE
00555 
00556 extern template class Block_Interleaver<double>;
00557 extern template class Block_Interleaver<short>;
00558 extern template class Block_Interleaver<int>;
00559 extern template class Block_Interleaver<std::complex<double> >;
00560 extern template class Block_Interleaver<bin>;
00561 
00562 extern template class Cross_Interleaver<double>;
00563 extern template class Cross_Interleaver<short>;
00564 extern template class Cross_Interleaver<int>;
00565 extern template class Cross_Interleaver<std::complex<double> >;
00566 extern template class Cross_Interleaver<bin>;
00567 
00568 extern template class Sequence_Interleaver<double>;
00569 extern template class Sequence_Interleaver<short>;
00570 extern template class Sequence_Interleaver<int>;
00571 extern template class Sequence_Interleaver<std::complex<double> >;
00572 extern template class Sequence_Interleaver<bin>;
00573 
00574 #endif // HAVE_EXTERN_TEMPLATE
00575 
00577 
00578 } // namespace itpp
00579 
00580 #endif // #ifndef INTERLEAVE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Tue Dec 6 2011 16:51:53 for IT++ by Doxygen 1.7.4