IT++ Logo Newcom Logo

interleave.h

Go to the documentation of this file.
00001 
00033 #ifndef INTERLEAVE_H
00034 #define INTERLEAVE_H
00035 
00036 #include <itpp/base/vec.h>
00037 #include <itpp/base/mat.h>
00038 #include <itpp/base/random.h>
00039 #include <itpp/base/sort.h>
00040 
00041 
00042 namespace itpp {
00043 
00063   template <class T>
00064     class Block_Interleaver {
00065     public:
00067     Block_Interleaver(void) {rows = 0; cols = 0;};
00069     Block_Interleaver(int in_rows, int in_cols);
00071     Vec<T> interleave(const Vec<T> &input);
00073     void interleave(const Vec<T> &input, Vec<T> &output);
00075     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 );
00077     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 );
00079     void set_rows(int in_rows) {rows = in_rows;};
00081     void set_cols(int in_cols) {cols = in_cols;};
00083     int get_rows(void) {return rows;};
00085     int get_cols(void) {return cols;};
00086     private:
00087     int rows, cols, input_length;
00088   };
00089 
00109   template <class T>
00110     class Cross_Interleaver {
00111     public:
00113     Cross_Interleaver(void) {order = 0;};
00115     Cross_Interleaver(int in_order);
00117     Vec<T> interleave(const Vec<T> &input);
00119     void interleave(const Vec<T> &input, Vec<T> &output);
00121     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00123     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00125     void set_order(int in_order); 
00127     int get_order(void) {return order;};
00128     private:
00129     int order;
00130     int input_length;
00131     Mat<T> inter_matrix;
00132     Vec<T> tempvec, zerostemp;
00133   };
00134 
00151   template <class T>
00152     class Sequence_Interleaver {
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       } else {
00224         //Block interleaver loop: All, but the last, steps.
00225         for (s=0; s<steps-1; s++) {
00226           for (c=0; c<cols; c++) {
00227             for (r=0; r<rows; r++) {
00228               output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r);
00229             }
00230           }
00231         }
00232         //The last step.
00233         Vec<T> zerovect(output_length - input_length);
00234         zerovect.clear();
00235         Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00236         for (c=0; c<cols; c++) {
00237           for (r=0; r<rows; r++) {
00238             output((steps-1)*rows*cols+r*cols+c) = temp_last_input(c*rows+r);
00239           }
00240         }
00241       }
00242     }
00243 
00244   template<class T>
00245     Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input)
00246     {
00247       Vec<T> output;
00248       interleave(input,output);
00249       return output;
00250     }
00251 
00252   template<class T>
00253     void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00254     {
00255       int thisinput_length = input.length();
00256       int steps = (int)std::ceil( double(thisinput_length)/double(rows*cols) );
00257       int output_length = steps * rows * cols;
00258       output.set_size(output_length,false);
00259       int       s, r, c;
00260 
00261       if (thisinput_length==output_length) {
00262         //Block deinterleaver loop: All, but the last, steps.
00263         for (s=0; s<steps; s++) {
00264           for (r=0; r<rows; r++) {
00265             for (c=0; c<cols; c++) {
00266               output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00267             }
00268           }
00269         }
00270       } else {
00271         //Block deinterleaver loop: All, but the last, steps.
00272         for (s=0; s<steps-1; s++) {
00273           for (r=0; r<rows; r++) {
00274             for (c=0; c<cols; c++) {
00275               output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00276             }
00277           }
00278         }
00279         //The last step.
00280         Vec<T> zerovect(output_length - thisinput_length);
00281         zerovect.clear();
00282         Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00283         for (r=0; r<rows; r++) {
00284           for (c=0; c<cols; c++) {
00285             output((steps-1)*rows*cols+c*rows+r) = temp_last_input(r*cols+c);
00286           }
00287         }
00288       }
00289       if (keepzeros == 0)
00290         output.set_size(input_length,true);
00291     }
00292 
00293   template<class T>
00294     Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00295     {
00296       Vec<T> output;
00297       deinterleave(input,output,keepzeros);
00298       return output;
00299     }
00300 
00301   //---------------------------- Cross Interleaver ---------------------------
00302 
00303   template<class T>
00304     Cross_Interleaver<T>::Cross_Interleaver(int in_order)
00305     {
00306       order = in_order;
00307       input_length = 0;
00308       inter_matrix.set_size(order,order,false);
00309       tempvec.set_size(order,false);
00310       zerostemp.set_size(order,false);
00311     }
00312 
00313   template<class T>
00314     void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00315     {
00316       input_length = input.length();
00317       int steps = (int)std::ceil( float(input_length) / order ) + order;
00318       int output_length = steps * order;
00319       output.set_length(output_length,false);
00320       int i, r, c;
00321 
00322       inter_matrix.clear();
00323       zerostemp.clear();
00324 
00325       //Cross interleaver loop:
00326       for (i=0; i< steps; i++ ){
00327 
00328         //Shift the matrix to the right:
00329         for (c=order-1; c>0; c--)
00330           inter_matrix.set_col(c, inter_matrix.get_col(c-1) );
00331 
00332         // Write the new data to the matrix
00333         if ((i*order+order)<input_length)
00334           tempvec = input.mid(i*order,order);
00335         else if ((i*order)<input_length)
00336           tempvec = concat( input.right(input_length-i*order), zerostemp.left(order-(input_length-i*order)) );
00337         else
00338           tempvec.clear();
00339         inter_matrix.set_col(0,tempvec);
00340 
00341         //Read the matrix diagonal-wise:
00342         for (r=0; r<order; r++)
00343           output(i*order+r) = inter_matrix(r,r);
00344       }
00345     }
00346 
00347   template<class T>
00348     Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input)
00349     {
00350       Vec<T> output;
00351       interleave(input,output);
00352       return output;
00353     }
00354 
00355   template<class T>
00356     void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00357     {
00358       int thisinput_length = input.length();
00359       int       steps = (int)std::ceil( float(thisinput_length) / order ) + order;
00360       int output_length = steps * order;
00361       output.set_size(output_length,false);
00362       int i, r, c;
00363 
00364       inter_matrix.clear();
00365       zerostemp.clear();
00366 
00367       //Cross interleaver loop:
00368       for (i=0; i<steps; i++ ){
00369 
00370         //Shift the matrix to the right:
00371         for (c=order-1; c>0; c--)
00372           inter_matrix.set_col(c,inter_matrix.get_col(c-1));
00373 
00374         // Write the new data to the matrix
00375         if ((i*order+order)<thisinput_length)
00376           tempvec = input.mid(i*order,order);
00377         else if ((i*order)<thisinput_length)
00378           tempvec = concat( input.right(thisinput_length-i*order), zerostemp.left(order-(thisinput_length-i*order)) );
00379         else
00380           tempvec.clear();
00381         inter_matrix.set_col(0,tempvec);
00382 
00383         //Read the matrix diagonal-wise:
00384         for (r=0; r<order; r++)
00385           output(i*order+r)  = inter_matrix(r,order-1-r);
00386       }
00387       if (keepzeros == 0)
00388         output = output.mid(round_i(std::pow(double(order),2))-order,input_length);
00389     }
00390 
00391   template<class T>
00392     Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00393     {
00394       Vec<T> output;
00395       deinterleave(input,output,keepzeros);
00396       return output;
00397     }
00398 
00399   template<class T>
00400     void Cross_Interleaver<T>::set_order(int in_order)
00401     {
00402       order = in_order;
00403       input_length = 0;
00404       inter_matrix.set_size(order,order,false);
00405       tempvec.set_size(order,false);
00406       zerostemp.set_size(order,false);
00407     }
00408 
00409   //------------------- Sequence Interleaver --------------------------------
00410 
00411   template<class T>
00412     Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth)
00413     {
00414       interleaver_depth = in_interleaver_depth;
00415       interleaver_sequence = sort_index(randu(in_interleaver_depth));
00416       input_length = 0;
00417     }
00418 
00419   template<class T>
00420     Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence)
00421     {
00422       interleaver_depth = in_interleaver_sequence.length();
00423       interleaver_sequence = in_interleaver_sequence;
00424       input_length = 0;
00425     }
00426 
00427   template<class T>
00428     void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00429     {
00430       input_length = input.length();
00431       int steps = (int)std::ceil( double(input_length)/double(interleaver_depth) );
00432       int output_length = steps*interleaver_depth;
00433       output.set_size(output_length,false);
00434       int       s, i;
00435 
00436       if (input_length==output_length) {
00437 
00438         //Sequence interleaver loop: All steps.
00439         for (s=0; s<steps; s++) {
00440           for (i=0; i<interleaver_depth; i++) {
00441             output(s*interleaver_depth+i) = input(s*interleaver_depth+interleaver_sequence(i));
00442           }
00443         }
00444 
00445       } else {
00446 
00447         //Sequence interleaver loop: All, but the last, steps.
00448         for (s=0; s<steps-1; 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         //The last step.
00454         Vec<T> zerovect(output_length - input_length);
00455         zerovect.clear();
00456         Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect );
00457         for (i=0; i<interleaver_depth; i++) {
00458           output((steps-1)*interleaver_depth+i) = temp_last_input(interleaver_sequence(i));
00459         }
00460 
00461       }
00462     }
00463 
00464   template<class T>
00465     Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input)
00466     {
00467       Vec<T> output;
00468       interleave(input,output);
00469       return output;
00470     }
00471 
00472   template<class T>
00473     void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00474     {
00475       int thisinput_length = input.length();
00476       int steps = (int)std::ceil( double(thisinput_length)/double(interleaver_depth) );
00477       int output_length = steps*interleaver_depth;
00478       //long_long thisinput_length = input.length();
00479       //long_long steps = (long_long)std::ceil( double(thisinput_length)/double(interleaver_depth) );
00480       //long_long output_length = steps*interleaver_depth;
00481       output.set_length(output_length,false);
00482       int       s, i;
00483       //long_long       s, i;
00484 
00485       if (thisinput_length == output_length) {
00486 
00487         //Sequence interleaver loop: All steps.
00488         for (s=0; s<steps; s++) {
00489           for (i=0; i<interleaver_depth; i++) {
00490             output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i);
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 
00541   // ------------------------ Instantiations --------------------------------
00542 #ifndef _MSC_VER
00543 
00545   extern template class Block_Interleaver<double>;
00547   extern template class Block_Interleaver<short>;
00549   extern template class Block_Interleaver<int>;
00551   extern template class Block_Interleaver<std::complex<double> >;
00553   extern template class Block_Interleaver<bin>;
00554 
00556   extern template class Cross_Interleaver<double>;
00558   extern template class Cross_Interleaver<short>;
00560   extern template class Cross_Interleaver<int>;
00562   extern template class Cross_Interleaver<std::complex<double> >;
00564   extern template class Cross_Interleaver<bin>;
00565 
00567   extern template class Sequence_Interleaver<double>;
00569   extern template class Sequence_Interleaver<short>;
00571   extern template class Sequence_Interleaver<int>;
00573   extern template class Sequence_Interleaver<std::complex<double> >;
00575   extern template class Sequence_Interleaver<bin>;
00576 #endif
00577 
00578 } // namespace itpp
00579 
00580 #endif // #ifndef INTERLEAVE_H
SourceForge Logo

Generated on Wed Apr 18 11:23:32 2007 for IT++ by Doxygen 1.5.2