Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

interleave.h

Go to the documentation of this file.
00001 // 
00002 // SPUC - Signal processing using C++ - A DSP library
00003 /*---------------------------------------------------------------------------*
00004  *                                   IT++                                    *
00005  *---------------------------------------------------------------------------*
00006  * Copyright (c) 1995-2001 by Tony Ottosson, Thomas Eriksson, Pål Frenger,   *
00007  * Tobias Ringström, and Jonas Samuelsson.                                   *
00008  *                                                                           *
00009  * Permission to use, copy, modify, and distribute this software and its     *
00010  * documentation under the terms of the GNU General Public License is hereby *
00011  * granted. No representations are made about the suitability of this        *
00012  * software for any purpose. It is provided "as is" without expressed or     *
00013  * implied warranty. See the GNU General Public License for more details.    *
00014  *---------------------------------------------------------------------------*/
00015 
00026 #ifndef __interleave_h
00027 #define __interleave_h
00028 #include <binary.h>
00029 #include <matrix.h>
00030 #include <random.h>
00031 namespace SPUC {
00032 template<class T> class Vec;
00033 template<class T> class Mat;
00053 template <class T>
00054 class Block_Interleaver {
00055 public:
00057     Block_Interleaver(void) {rows = 0; cols = 0;};
00059     Block_Interleaver(int in_rows, int in_cols);
00061     Vec<T> interleave(const Vec<T> &input);
00063     void interleave(const Vec<T> &input, Vec<T> &output);
00065     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 );
00067     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 );
00069     void set_rows(int in_rows) {rows = in_rows;};
00071     void set_cols(int in_cols) {cols = in_cols;};
00073     int get_rows(void) {return rows;};
00075     int get_cols(void) {return cols;};
00076 private:
00077     int rows, cols, input_length;
00078 };
00079 
00099 template <class T>
00100 class Cross_Interleaver {
00101 public:
00103     Cross_Interleaver(void) {order = 0;};
00105     Cross_Interleaver(int in_order);
00107     Vec<T> interleave(const Vec<T> &input);
00109     void interleave(const Vec<T> &input, Vec<T> &output);
00111     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
00113     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
00115     void set_order(int in_order); 
00117     int get_order(void) {return order;};
00118 private:
00119     int order;
00120     int input_length;
00121     Mat<T> inter_matrix;
00122     Vec<T> tempvec, zerostemp;
00123 };
00124 
00141 template <class T>
00142 class Sequence_Interleaver {
00143 public:
00145     Sequence_Interleaver(void) {interleaver_depth = 0;};
00151     Sequence_Interleaver(int in_interleaver_depth);
00157     Sequence_Interleaver(ivec in_interleaver_sequence);
00159     Vec<T> interleave(const Vec<T> &input);
00161     void interleave(const Vec<T> &input, Vec<T> &output);
00163     Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 );
00165     void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 );
00167     void randomize_interleaver_sequence();
00169     ivec get_interleaver_sequence();
00171     void set_interleaver_sequence(ivec in_interleaver_sequence);
00173     void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; };
00175     int get_interleaver_depth(void) { return interleaver_depth; };
00176 private:
00177     ivec interleaver_sequence;
00178     int interleaver_depth, input_length;
00179 };
00180 /************************************************************
00181  * Block Interleaver
00182  ************************************************************/
00183 template<class T>
00184 Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols)
00185 {
00186     rows = in_rows;
00187     cols = in_cols;
00188     input_length = 0;
00189 };
00190 
00191 template<class T>
00192 void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00193 {
00194     input_length = input.length();
00195     long_long steps = (long_long)ceil( double(input_length)/double(rows*cols) );
00196     long_long output_length = steps * rows * cols;
00197     output.set_length(output_length,false);
00198     int s, r, c;
00199     
00200     if (input_length==output_length) {
00201         //Block interleaver loop: All steps.
00202         for (s=0; s<steps; s++) {
00203             for (c=0; c<cols; c++) {
00204                 for (r=0; r<rows; r++) {
00205                     output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r);
00206                 }
00207             }
00208         }
00209     } else {
00210         //Block interleaver loop: All, but the last, steps.
00211         for (s=0; s<steps-1; s++) {
00212             for (c=0; c<cols; c++) {
00213                 for (r=0; r<rows; r++) {
00214                     output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r);
00215                 }
00216             }
00217         }
00218         //The last step.
00219         Vec<T> zerovect(output_length - input_length);
00220         zerovect.clear();
00221         Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00222         for (c=0; c<cols; c++) {
00223             for (r=0; r<rows; r++) {
00224                 output((steps-1)*rows*cols+r*cols+c) = temp_last_input(c*rows+r);
00225             }
00226         }
00227     }
00228 }
00229 
00230 template<class T>
00231 Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input)
00232 {
00233     Vec<T> output;
00234     interleave(input,output);
00235     return output;
00236 }
00237 
00238 template<class T>
00239 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00240 {
00241     long_long thisinput_length = input.length();
00242     long_long steps = (long_long)ceil( double(thisinput_length)/double(rows*cols) );
00243     long_long output_length = steps * rows * cols;
00244     output.set_size(output_length,false);
00245     long_long   s, r, c;
00246 
00247     if (thisinput_length==output_length) {
00248         //Block deinterleaver loop: All, but the last, steps.
00249         for (s=0; s<steps; s++) {
00250             for (r=0; r<rows; r++) {
00251                 for (c=0; c<cols; c++) {
00252                     output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00253                 }
00254             }
00255         }
00256     } else {
00257         //Block deinterleaver loop: All, but the last, steps.
00258         for (s=0; s<steps-1; s++) {
00259             for (r=0; r<rows; r++) {
00260                 for (c=0; c<cols; c++) {
00261                     output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c);
00262                 }
00263             }
00264         }
00265         //The last step.
00266         Vec<T> zerovect(output_length - thisinput_length);
00267         zerovect.clear();
00268         Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect );
00269         for (r=0; r<rows; r++) {
00270             for (c=0; c<cols; c++) {
00271                 output((steps-1)*rows*cols+c*rows+r) = temp_last_input(r*cols+c);
00272             }
00273         }
00274         if (keepzeros == 0)
00275             output.set_size(input_length,true);
00276     }
00277 }
00278 
00279 template<class T>
00280 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00281 {
00282     Vec<T> output;
00283     deinterleave(input,output,keepzeros);
00284     return output;
00285 }
00286 
00287 /************************************************************
00288  * Cross Interleaver
00289  ************************************************************/
00290 template<class T>
00291 Cross_Interleaver<T>::Cross_Interleaver(int in_order)
00292 {
00293     order = in_order;
00294     input_length = 0;
00295     inter_matrix.set_size(order,order,false);
00296     tempvec.set_size(order,false);
00297     zerostemp.set_size(order,false);
00298 }
00299 
00300 template<class T>
00301 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00302 {
00303     input_length = input.length();
00304     long_long steps = (long_long)ceil( float(input_length) / order ) + order;
00305     long_long output_length = steps * order;
00306     output.set_length(output_length,false);
00307     long_long i, r, c;
00308 
00309     inter_matrix.clear();
00310     zerostemp.clear();
00311         
00312     //Cross interleaver loop:
00313     for (i=0; i< steps; i++ ){
00314 
00315         //Shift the matrix to the right:
00316         for (c=order-1; c>0; c--) 
00317             inter_matrix.set_col(c, inter_matrix.get_col(c-1) );
00318                 
00319         // Write the new data to the matrix
00320         if ((i*order+order)<input_length)
00321             tempvec = input.mid(i*order,order);
00322         else if ((i*order)<input_length)
00323             tempvec = concat( input.right(input_length-i*order), zerostemp.left(order-(input_length-i*order)) );
00324         else
00325             tempvec.clear();
00326         inter_matrix.set_col(0,tempvec);
00327                 
00328         //Read the matrix diagonal-wise:
00329         for (r=0; r<order; r++) 
00330             output(i*order+r) = inter_matrix(r,r);
00331     }
00332 }
00333 
00334 
00335 template<class T>
00336 Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input)
00337 {
00338     Vec<T> output;
00339     interleave(input,output);
00340     return output;
00341 }
00342 
00343 template<class T>
00344 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00345 {
00346     long_long thisinput_length = input.length();
00347     long_long   steps = (long_long)ceil( float(thisinput_length) / order ) + order;
00348     long_long output_length = steps * order;
00349     output.set_size(output_length,false);
00350     long_long i, r, c;
00351         long pow(long o, long i);
00352 
00353     inter_matrix.clear();
00354     zerostemp.clear();
00355         
00356     //Cross interleaver loop:
00357     for (i=0; i<steps; i++ ){
00358 
00359         //Shift the matrix to the right:
00360         for (c=order-1; c>0; c--) 
00361             inter_matrix.set_col(c,inter_matrix.get_col(c-1));
00362                 
00363         // Write the new data to the matrix
00364         if ((i*order+order)<thisinput_length)
00365             tempvec = input.mid(i*order,order);
00366         else if ((i*order)<thisinput_length)
00367             tempvec = concat( input.right(thisinput_length-i*order), zerostemp.left(order-(thisinput_length-i*order)) );
00368         else
00369             tempvec.clear();
00370         inter_matrix.set_col(0,tempvec);
00371                 
00372         //Read the matrix diagonal-wise:
00373         for (r=0; r<order; r++) 
00374             output(i*order+r)  = inter_matrix(r,order-1-r);
00375     }
00376     if (keepzeros == 0) 
00377         output = output.mid(pow(order,2)-order,input_length);
00378 }
00379 
00380 template<class T>
00381 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00382 {
00383     Vec<T> output;
00384     deinterleave(input,output,keepzeros);
00385     return output;
00386 }
00387 
00388 template<class T>
00389 void Cross_Interleaver<T>::set_order(int in_order)
00390 {
00391     order = in_order;
00392     input_length = 0;
00393     inter_matrix.set_size(order,order,false);
00394     tempvec.set_size(order,false);
00395     zerostemp.set_size(order,false);
00396 }
00397 
00398 /************************************************************
00399  * Sequence Interleaver
00400  ************************************************************/
00401 template<class T>
00402 Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth)
00403 {
00404         double randu(void);
00405     interleaver_depth = in_interleaver_depth;
00406     interleaver_sequence = sort_index(randu(in_interleaver_depth));
00407     input_length = 0;
00408 }
00409 
00410 template<class T>
00411 Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence)
00412 {
00413     interleaver_depth = in_interleaver_sequence.length();
00414     interleaver_sequence = in_interleaver_sequence;
00415     input_length = 0;
00416 }
00417 
00418 template<class T>
00419 void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
00420 {
00421     input_length = input.length();
00422     long_long steps = (long_long)ceil( double(input_length)/double(interleaver_depth) );
00423     long_long output_length = steps*interleaver_depth;
00424     output.set_size(output_length,false);
00425     long_long   s, i;
00426 
00427     if (input_length==output_length) {
00428         
00429         //Sequence interleaver loop: All steps.
00430         for (s=0; s<steps; s++) {
00431             for (i=0; i<interleaver_depth; i++) {
00432                 output(s*interleaver_depth+i) = input(s*interleaver_depth+interleaver_sequence(i));
00433             }
00434         }
00435         
00436     } else {
00437         
00438         //Sequence interleaver loop: All, but the last, steps.
00439         for (s=0; s<steps-1; 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         //The last step.
00445         Vec<T> zerovect(output_length - input_length);
00446         zerovect.clear();
00447         Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect );
00448         for (i=0; i<interleaver_depth; i++) {
00449             output((steps-1)*interleaver_depth+i) = temp_last_input(interleaver_sequence(i));
00450         }
00451         
00452     }
00453 }
00454 
00455 template<class T>
00456 Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input)
00457 {
00458     Vec<T> output;
00459     interleave(input,output);
00460     return output;
00461 }
00462 
00463 template<class T>
00464 void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
00465 {
00466     long_long thisinput_length = input.length();
00467     long_long steps = (long_long)ceil( double(thisinput_length)/double(interleaver_depth) );
00468     long_long output_length = steps*interleaver_depth;
00469     output.set_length(output_length,false);
00470     long_long   s, i;
00471 
00472     if (thisinput_length == output_length) {
00473 
00474         //Sequence interleaver loop: All steps.
00475         for (s=0; s<steps; s++) {
00476             for (i=0; i<interleaver_depth; i++) {
00477                 output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i);
00478             }
00479         }
00480         
00481     } else {
00482         //Sequence interleaver loop: All, but the last, steps.
00483         for (s=0; s<steps-1; s++) {
00484             for (i=0; i<interleaver_depth; i++) {
00485                 output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i);
00486             }
00487         }
00488         //The last step.
00489         Vec<T> zerovect(output_length - thisinput_length);
00490         zerovect.clear();
00491         Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect );
00492         for (i=0; i<interleaver_depth; i++) {
00493             output((steps-1)*interleaver_depth+interleaver_sequence(i)) = temp_last_input(i);
00494         }
00495         if (keepzeros == 0) 
00496             output.set_size(input_length,true);
00497     }
00498 
00499 }
00500 
00501 template<class T>
00502 Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
00503 {
00504     Vec<T> output;
00505     deinterleave(input,output,keepzeros);
00506     return output;
00507 }
00508 
00509 template<class T>
00510 void Sequence_Interleaver<T>::randomize_interleaver_sequence()
00511 {
00512         double randu(void);
00513     interleaver_sequence = sort_index(randu(interleaver_depth));
00514 }
00515 
00516 template<class T>
00517 ivec Sequence_Interleaver<T>::get_interleaver_sequence()
00518 {
00519     return interleaver_sequence;
00520 }
00521 
00522 template<class T>
00523 void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence)
00524 {
00525     interleaver_sequence = in_interleaver_sequence;
00526     interleaver_depth = interleaver_sequence.size(); //<-- Bug Fix 2000-09-29 PF
00527 }
00528 
00529 }
00530 #endif

Generated on Fri Sep 16 11:02:20 2005 for spuc by  doxygen 1.4.4