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 
00066   template <class T>
00067     class Block_Interleaver {
00068     public:
00070     Block_Interleaver(void) {rows = 0; cols = 0;};
00072     Block_Interleaver(int in_rows, int in_cols);
00074     Vec<T> interleave(const Vec<T> &input);
00076     void interleave(const Vec<T> &input, Vec<T> &output);
00078     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 );
00080     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 );
00082     void set_rows(int in_rows) {rows = in_rows;};
00084     void set_cols(int in_cols) {cols = in_cols;};
00086     int get_rows(void) {return rows;};
00088     int get_cols(void) {return cols;};
00089     private:
00090     int rows, cols, input_length;
00091   };
00092 
00112   template <class T>
00113     class Cross_Interleaver {
00114     public:
00116     Cross_Interleaver(void) {order = 0;};
00118     Cross_Interleaver(int in_order);
00120     Vec<T> interleave(const Vec<T> &input);
00122     void interleave(const Vec<T> &input, Vec<T> &output);
00124     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00126     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00128     void set_order(int in_order);
00130     int get_order(void) {return order;};
00131     private:
00132     int order;
00133     int input_length;
00134     Mat<T> inter_matrix;
00135     Vec<T> tempvec, zerostemp;
00136   };
00137 
00154   template <class T>
00155     class Sequence_Interleaver {
00156     public:
00158     Sequence_Interleaver(void) {interleaver_depth = 0;};
00164     Sequence_Interleaver(int in_interleaver_depth);
00170     Sequence_Interleaver(ivec in_interleaver_sequence);
00172     Vec<T> interleave(const Vec<T> &input);
00174     void interleave(const Vec<T> &input, Vec<T> &output);
00176     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 );
00178     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 );
00180     void randomize_interleaver_sequence();
00182     ivec get_interleaver_sequence();
00184     void set_interleaver_sequence(ivec in_interleaver_sequence);
00186     void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; };
00188     int get_interleaver_depth(void) { return interleaver_depth; };
00189     private:
00190     ivec interleaver_sequence;
00191     int interleaver_depth, input_length;
00192   };
00193 
00194   //-----------------------------------------------------------------------------
00195   // Implementation of templated members starts here
00196   //-----------------------------------------------------------------------------
00197 
00198   //-------------------------- Block Interleaver ---------------------------------
00199 
00200   template<class T>
00201     Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols)
00202     {
00203       rows = in_rows;
00204       cols = in_cols;
00205       input_length = 0;
00206     }
00207 
00208   template<class T>
00209     void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00210     {
00211       input_length = input.length();
00212       int steps = (int)std::ceil( double(input_length)/double(rows*cols) );
00213       int output_length = steps * rows * cols;
00214       output.set_length(output_length,false);
00215       int s, r, c;
00216 
00217       if (input_length==output_length) {
00218   //Block interleaver loop: All steps.
00219   for (s=0; s<steps; s++) {
00220     for (c=0; c<cols; c++) {
00221       for (r=0; r<rows; r++) {
00222         output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r);
00223       }
00224     }
00225   }
00226       } else {
00227   //Block interleaver loop: All, but the last, steps.
00228   for (s=0; s<steps-1; s++) {
00229     for (c=0; c<cols; c++) {
00230       for (r=0; r<rows; r++) {
00231         output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r);
00232       }
00233     }
00234   }
00235   //The last step.
00236   Vec<T> zerovect(output_length - input_length);
00237   zerovect.clear();
00238   Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00239   for (c=0; c<cols; c++) {
00240     for (r=0; r<rows; r++) {
00241       output((steps-1)*rows*cols+r*cols+c) = temp_last_input(c*rows+r);
00242     }
00243   }
00244       }
00245     }
00246 
00247   template<class T>
00248     Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input)
00249     {
00250       Vec<T> output;
00251       interleave(input,output);
00252       return output;
00253     }
00254 
00255   template<class T>
00256     void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00257     {
00258       int thisinput_length = input.length();
00259       int steps = (int)std::ceil( double(thisinput_length)/double(rows*cols) );
00260       int output_length = steps * rows * cols;
00261       output.set_size(output_length,false);
00262       int s, r, c;
00263 
00264       if (thisinput_length==output_length) {
00265   //Block deinterleaver loop: All, but the last, steps.
00266   for (s=0; s<steps; s++) {
00267     for (r=0; r<rows; r++) {
00268       for (c=0; c<cols; c++) {
00269         output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00270       }
00271     }
00272   }
00273       } else {
00274   //Block deinterleaver loop: All, but the last, steps.
00275   for (s=0; s<steps-1; s++) {
00276     for (r=0; r<rows; r++) {
00277       for (c=0; c<cols; c++) {
00278         output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00279       }
00280     }
00281   }
00282   //The last step.
00283   Vec<T> zerovect(output_length - thisinput_length);
00284   zerovect.clear();
00285   Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00286   for (r=0; r<rows; r++) {
00287     for (c=0; c<cols; c++) {
00288       output((steps-1)*rows*cols+c*rows+r) = temp_last_input(r*cols+c);
00289     }
00290   }
00291       }
00292       if (keepzeros == 0)
00293   output.set_size(input_length,true);
00294     }
00295 
00296   template<class T>
00297     Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00298     {
00299       Vec<T> output;
00300       deinterleave(input,output,keepzeros);
00301       return output;
00302     }
00303 
00304   //---------------------------- Cross Interleaver ---------------------------
00305 
00306   template<class T>
00307     Cross_Interleaver<T>::Cross_Interleaver(int in_order)
00308     {
00309       order = in_order;
00310       input_length = 0;
00311       inter_matrix.set_size(order,order,false);
00312       tempvec.set_size(order,false);
00313       zerostemp.set_size(order,false);
00314     }
00315 
00316   template<class T>
00317     void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00318     {
00319       input_length = input.length();
00320       int steps = (int)std::ceil( float(input_length) / order ) + order;
00321       int output_length = steps * order;
00322       output.set_length(output_length,false);
00323       int i, r, c;
00324 
00325       inter_matrix.clear();
00326       zerostemp.clear();
00327 
00328       //Cross interleaver loop:
00329       for (i=0; i< steps; i++ ){
00330 
00331   //Shift the matrix to the right:
00332   for (c=order-1; c>0; c--)
00333     inter_matrix.set_col(c, inter_matrix.get_col(c-1) );
00334 
00335   // Write the new data to the matrix
00336   if ((i*order+order)<input_length)
00337     tempvec = input.mid(i*order,order);
00338   else if ((i*order)<input_length)
00339     tempvec = concat( input.right(input_length-i*order), zerostemp.left(order-(input_length-i*order)) );
00340   else
00341     tempvec.clear();
00342   inter_matrix.set_col(0,tempvec);
00343 
00344   //Read the matrix diagonal-wise:
00345   for (r=0; r<order; r++)
00346     output(i*order+r) = inter_matrix(r,r);
00347       }
00348     }
00349 
00350   template<class T>
00351     Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input)
00352     {
00353       Vec<T> output;
00354       interleave(input,output);
00355       return output;
00356     }
00357 
00358   template<class T>
00359     void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00360     {
00361       int thisinput_length = input.length();
00362       int steps = (int)std::ceil( float(thisinput_length) / order ) + order;
00363       int output_length = steps * order;
00364       output.set_size(output_length,false);
00365       int i, r, c;
00366 
00367       inter_matrix.clear();
00368       zerostemp.clear();
00369 
00370       //Cross interleaver loop:
00371       for (i=0; i<steps; i++ ){
00372 
00373   //Shift the matrix to the right:
00374   for (c=order-1; c>0; c--)
00375     inter_matrix.set_col(c,inter_matrix.get_col(c-1));
00376 
00377   // Write the new data to the matrix
00378   if ((i*order+order)<thisinput_length)
00379     tempvec = input.mid(i*order,order);
00380   else if ((i*order)<thisinput_length)
00381     tempvec = concat( input.right(thisinput_length-i*order), zerostemp.left(order-(thisinput_length-i*order)) );
00382   else
00383     tempvec.clear();
00384   inter_matrix.set_col(0,tempvec);
00385 
00386   //Read the matrix diagonal-wise:
00387   for (r=0; r<order; r++)
00388     output(i*order+r)  = inter_matrix(r,order-1-r);
00389       }
00390       if (keepzeros == 0)
00391   output = output.mid(round_i(std::pow(double(order),2))-order,input_length);
00392     }
00393 
00394   template<class T>
00395     Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00396     {
00397       Vec<T> output;
00398       deinterleave(input,output,keepzeros);
00399       return output;
00400     }
00401 
00402   template<class T>
00403     void Cross_Interleaver<T>::set_order(int in_order)
00404     {
00405       order = in_order;
00406       input_length = 0;
00407       inter_matrix.set_size(order,order,false);
00408       tempvec.set_size(order,false);
00409       zerostemp.set_size(order,false);
00410     }
00411 
00412   //------------------- Sequence Interleaver --------------------------------
00413 
00414   template<class T>
00415     Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth)
00416     {
00417       interleaver_depth = in_interleaver_depth;
00418       interleaver_sequence = sort_index(randu(in_interleaver_depth));
00419       input_length = 0;
00420     }
00421 
00422   template<class T>
00423     Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence)
00424     {
00425       interleaver_depth = in_interleaver_sequence.length();
00426       interleaver_sequence = in_interleaver_sequence;
00427       input_length = 0;
00428     }
00429 
00430   template<class T>
00431     void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00432     {
00433       input_length = input.length();
00434       int steps = (int)std::ceil( double(input_length)/double(interleaver_depth) );
00435       int output_length = steps*interleaver_depth;
00436       output.set_size(output_length,false);
00437       int s, i;
00438 
00439       if (input_length==output_length) {
00440 
00441   //Sequence interleaver loop: All steps.
00442   for (s=0; s<steps; s++) {
00443     for (i=0; i<interleaver_depth; i++) {
00444       output(s*interleaver_depth+i) = input(s*interleaver_depth+interleaver_sequence(i));
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       } else {
00494   //Sequence interleaver loop: All, but the last, steps.
00495   for (s=0; s<steps-1; s++) {
00496     for (i=0; i<interleaver_depth; i++) {
00497       output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i);
00498     }
00499   }
00500   //The last step.
00501   Vec<T> zerovect(output_length - thisinput_length);
00502   zerovect.clear();
00503   Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect );
00504   for (i=0; i<interleaver_depth; i++) {
00505     output((steps-1)*interleaver_depth+interleaver_sequence(i)) = temp_last_input(i);
00506   }
00507   if (keepzeros == 0)
00508     output.set_size(input_length,true);
00509       }
00510 
00511     }
00512 
00513   template<class T>
00514     Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00515     {
00516       Vec<T> output;
00517       deinterleave(input,output,keepzeros);
00518       return output;
00519     }
00520 
00521   template<class T>
00522     void Sequence_Interleaver<T>::randomize_interleaver_sequence()
00523     {
00524       interleaver_sequence = sort_index(randu(interleaver_depth));
00525     }
00526 
00527   template<class T>
00528     ivec Sequence_Interleaver<T>::get_interleaver_sequence()
00529     {
00530       return interleaver_sequence;
00531     }
00532 
00533   template<class T>
00534     void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence)
00535     {
00536       interleaver_sequence = in_interleaver_sequence;
00537       interleaver_depth = interleaver_sequence.size();
00538     }
00539 
00541 
00542   // ----------------------------------------------------------------------
00543   // Instantiations
00544   // ----------------------------------------------------------------------
00545 
00546 #ifdef HAVE_EXTERN_TEMPLATE
00547 
00548   extern template class Block_Interleaver<double>;
00549   extern template class Block_Interleaver<short>;
00550   extern template class Block_Interleaver<int>;
00551   extern template class Block_Interleaver<std::complex<double> >;
00552   extern template class Block_Interleaver<bin>;
00553 
00554   extern template class Cross_Interleaver<double>;
00555   extern template class Cross_Interleaver<short>;
00556   extern template class Cross_Interleaver<int>;
00557   extern template class Cross_Interleaver<std::complex<double> >;
00558   extern template class Cross_Interleaver<bin>;
00559 
00560   extern template class Sequence_Interleaver<double>;
00561   extern template class Sequence_Interleaver<short>;
00562   extern template class Sequence_Interleaver<int>;
00563   extern template class Sequence_Interleaver<std::complex<double> >;
00564   extern template class Sequence_Interleaver<bin>;
00565 
00566 #endif // HAVE_EXTERN_TEMPLATE
00567 
00569 
00570 } // namespace itpp
00571 
00572 #endif // #ifndef INTERLEAVE_H
SourceForge Logo

Generated on Sun Sep 14 18:52:35 2008 for IT++ by Doxygen 1.5.6