00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
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
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
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
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
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
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
00313 for (i=0; i< steps; i++ ){
00314
00315
00316 for (c=order-1; c>0; c--)
00317 inter_matrix.set_col(c, inter_matrix.get_col(c-1) );
00318
00319
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
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
00357 for (i=0; i<steps; i++ ){
00358
00359
00360 for (c=order-1; c>0; c--)
00361 inter_matrix.set_col(c,inter_matrix.get_col(c-1));
00362
00363
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
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
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
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
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
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
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
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
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();
00527 }
00528
00529 }
00530 #endif