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

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