IT++ Logo
interleave.h
Go to the documentation of this file.
1 
29 #ifndef INTERLEAVE_H
30 #define INTERLEAVE_H
31 
32 #include <itpp/base/vec.h>
33 #include <itpp/base/mat.h>
34 #include <itpp/base/random.h>
35 #include <itpp/base/sort.h>
36 #include <itpp/itexports.h>
37 
38 namespace itpp
39 {
40 
60 template <class T>
62 {
63 public:
65  Block_Interleaver(void) {rows = 0; cols = 0;};
67  Block_Interleaver(int in_rows, int in_cols);
69  Vec<T> interleave(const Vec<T> &input);
71  void interleave(const Vec<T> &input, Vec<T> &output);
73  Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
75  void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
77  void set_rows(int in_rows) {rows = in_rows;};
79  void set_cols(int in_cols) {cols = in_cols;};
81  int get_rows(void) {return rows;};
83  int get_cols(void) {return cols;};
84 private:
85  int rows, cols, input_length;
86 };
87 
107 template <class T>
109 {
110 public:
112  Cross_Interleaver(void) {order = 0;};
114  Cross_Interleaver(int in_order);
116  Vec<T> interleave(const Vec<T> &input);
118  void interleave(const Vec<T> &input, Vec<T> &output);
120  Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
122  void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
124  void set_order(int in_order);
126  int get_order(void) {return order;};
127 private:
128  int order;
129  int input_length;
130  Mat<T> inter_matrix;
131  Vec<T> tempvec, zerostemp;
132 };
133 
150 template <class T>
152 {
153 public:
155  Sequence_Interleaver(void) {interleaver_depth = 0;};
161  Sequence_Interleaver(int in_interleaver_depth);
167  Sequence_Interleaver(ivec in_interleaver_sequence);
169  Vec<T> interleave(const Vec<T> &input);
171  void interleave(const Vec<T> &input, Vec<T> &output);
173  Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
175  void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
181  void set_interleaver_sequence(ivec in_interleaver_sequence);
183  void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; };
185  int get_interleaver_depth(void) { return interleaver_depth; };
186 private:
187  ivec interleaver_sequence;
188  int interleaver_depth, input_length;
189 };
190 
191 //-----------------------------------------------------------------------------
192 // Implementation of templated members starts here
193 //-----------------------------------------------------------------------------
194 
195 //-------------------------- Block Interleaver ---------------------------------
196 
197 template<class T>
199 {
200  rows = in_rows;
201  cols = in_cols;
202  input_length = 0;
203 }
204 
205 template<class T>
206 void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
207 {
208  input_length = input.length();
209  int steps = (int)std::ceil(double(input_length) / double(rows * cols));
210  int output_length = steps * rows * cols;
211  output.set_length(output_length, false);
212  int s, r, c;
213 
214  if (input_length == output_length) {
215  //Block interleaver loop: All steps.
216  for (s = 0; s < steps; s++) {
217  for (c = 0; c < cols; c++) {
218  for (r = 0; r < rows; r++) {
219  output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
220  }
221  }
222  }
223  }
224  else {
225  //Block interleaver loop: All, but the last, steps.
226  for (s = 0; s < steps - 1; s++) {
227  for (c = 0; c < cols; c++) {
228  for (r = 0; r < rows; r++) {
229  output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
230  }
231  }
232  }
233  //The last step.
234  Vec<T> zerovect(output_length - input_length);
235  zerovect.clear();
236  Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
237  for (c = 0; c < cols; c++) {
238  for (r = 0; r < rows; r++) {
239  output((steps - 1)*rows*cols + r*cols + c) = temp_last_input(c * rows + r);
240  }
241  }
242  }
243 }
244 
245 template<class T>
247 {
248  Vec<T> output;
249  interleave(input, output);
250  return output;
251 }
252 
253 template<class T>
254 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
255 {
256  int thisinput_length = input.length();
257  int steps = (int)std::ceil(double(thisinput_length) / double(rows * cols));
258  int output_length = steps * rows * cols;
259  output.set_size(output_length, false);
260  int s, r, c;
261 
262  if (thisinput_length == output_length) {
263  //Block deinterleaver loop: All, but the last, steps.
264  for (s = 0; s < steps; s++) {
265  for (r = 0; r < rows; r++) {
266  for (c = 0; c < cols; c++) {
267  output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
268  }
269  }
270  }
271  }
272  else {
273  //Block deinterleaver loop: All, but the last, steps.
274  for (s = 0; s < steps - 1; s++) {
275  for (r = 0; r < rows; r++) {
276  for (c = 0; c < cols; c++) {
277  output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
278  }
279  }
280  }
281  //The last step.
282  Vec<T> zerovect(output_length - thisinput_length);
283  zerovect.clear();
284  Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
285  for (r = 0; r < rows; r++) {
286  for (c = 0; c < cols; c++) {
287  output((steps - 1)*rows*cols + c*rows + r) = temp_last_input(r * cols + c);
288  }
289  }
290  }
291  if (keepzeros == 0)
292  output.set_size(input_length, true);
293 }
294 
295 template<class T>
296 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
297 {
298  Vec<T> output;
299  deinterleave(input, output, keepzeros);
300  return output;
301 }
302 
303 //---------------------------- Cross Interleaver ---------------------------
304 
305 template<class T>
307 {
308  order = in_order;
309  input_length = 0;
310  inter_matrix.set_size(order, order, false);
311  tempvec.set_size(order, false);
312  zerostemp.set_size(order, false);
313 }
314 
315 template<class T>
316 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
317 {
318  input_length = input.length();
319  int steps = (int)std::ceil(float(input_length) / order) + order;
320  int output_length = steps * order;
321  output.set_length(output_length, false);
322  int i, r, c;
323 
324  inter_matrix.clear();
325  zerostemp.clear();
326 
327  //Cross interleaver loop:
328  for (i = 0; i < steps; i++) {
329 
330  //Shift the matrix to the right:
331  for (c = order - 1; c > 0; c--)
332  inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
333 
334  // Write the new data to the matrix
335  if ((i*order + order) < input_length)
336  tempvec = input.mid(i * order, order);
337  else if ((i*order) < input_length)
338  tempvec = concat(input.right(input_length - i * order), zerostemp.left(order - (input_length - i * order)));
339  else
340  tempvec.clear();
341  inter_matrix.set_col(0, tempvec);
342 
343  //Read the matrix diagonal-wise:
344  for (r = 0; r < order; r++)
345  output(i*order + r) = inter_matrix(r, r);
346  }
347 }
348 
349 template<class T>
351 {
352  Vec<T> output;
353  interleave(input, output);
354  return output;
355 }
356 
357 template<class T>
358 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
359 {
360  int thisinput_length = input.length();
361  int steps = (int)std::ceil(float(thisinput_length) / order) + order;
362  int output_length = steps * order;
363  output.set_size(output_length, false);
364  int i, r, c;
365 
366  inter_matrix.clear();
367  zerostemp.clear();
368 
369  //Cross interleaver loop:
370  for (i = 0; i < steps; i++) {
371 
372  //Shift the matrix to the right:
373  for (c = order - 1; c > 0; c--)
374  inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
375 
376  // Write the new data to the matrix
377  if ((i*order + order) < thisinput_length)
378  tempvec = input.mid(i * order, order);
379  else if ((i*order) < thisinput_length)
380  tempvec = concat(input.right(thisinput_length - i * order), zerostemp.left(order - (thisinput_length - i * order)));
381  else
382  tempvec.clear();
383  inter_matrix.set_col(0, tempvec);
384 
385  //Read the matrix diagonal-wise:
386  for (r = 0; r < order; r++)
387  output(i*order + r) = inter_matrix(r, order - 1 - r);
388  }
389  if (keepzeros == 0)
390  output = output.mid(round_i(std::pow(double(order), 2)) - order, input_length);
391 }
392 
393 template<class T>
394 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
395 {
396  Vec<T> output;
397  deinterleave(input, output, keepzeros);
398  return output;
399 }
400 
401 template<class T>
403 {
404  order = in_order;
405  input_length = 0;
406  inter_matrix.set_size(order, order, false);
407  tempvec.set_size(order, false);
408  zerostemp.set_size(order, false);
409 }
410 
411 //------------------- Sequence Interleaver --------------------------------
412 
413 template<class T>
415 {
416  interleaver_depth = in_interleaver_depth;
417  interleaver_sequence = sort_index(randu(in_interleaver_depth));
418  input_length = 0;
419 }
420 
421 template<class T>
423 {
424  interleaver_depth = in_interleaver_sequence.length();
425  interleaver_sequence = in_interleaver_sequence;
426  input_length = 0;
427 }
428 
429 template<class T>
431 {
432  input_length = input.length();
433  int steps = (int)std::ceil(double(input_length) / double(interleaver_depth));
434  int output_length = steps * interleaver_depth;
435  output.set_size(output_length, false);
436  int s, i;
437 
438  if (input_length == output_length) {
439 
440  //Sequence interleaver loop: All steps.
441  for (s = 0; s < steps; s++) {
442  for (i = 0; i < interleaver_depth; i++) {
443  output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
444  }
445  }
446 
447  }
448  else {
449 
450  //Sequence interleaver loop: All, but the last, steps.
451  for (s = 0; s < steps - 1; s++) {
452  for (i = 0; i < interleaver_depth; i++) {
453  output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
454  }
455  }
456  //The last step.
457  Vec<T> zerovect(output_length - input_length);
458  zerovect.clear();
459  Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
460  for (i = 0; i < interleaver_depth; i++) {
461  output((steps - 1)*interleaver_depth + i) = temp_last_input(interleaver_sequence(i));
462  }
463 
464  }
465 }
466 
467 template<class T>
469 {
470  Vec<T> output;
471  interleave(input, output);
472  return output;
473 }
474 
475 template<class T>
476 void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
477 {
478  int thisinput_length = input.length();
479  int steps = (int)std::ceil(double(thisinput_length) / double(interleaver_depth));
480  int output_length = steps * interleaver_depth;
481  output.set_length(output_length, false);
482  int s, i;
483 
484  if (thisinput_length == output_length) {
485 
486  //Sequence interleaver loop: All steps.
487  for (s = 0; s < steps; s++) {
488  for (i = 0; i < interleaver_depth; i++) {
489  output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
490  }
491  }
492 
493  }
494  else {
495  //Sequence interleaver loop: All, but the last, steps.
496  for (s = 0; s < steps - 1; s++) {
497  for (i = 0; i < interleaver_depth; i++) {
498  output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
499  }
500  }
501  //The last step.
502  Vec<T> zerovect(output_length - thisinput_length);
503  zerovect.clear();
504  Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
505  for (i = 0; i < interleaver_depth; i++) {
506  output((steps - 1)*interleaver_depth + interleaver_sequence(i)) = temp_last_input(i);
507  }
508  if (keepzeros == 0)
509  output.set_size(input_length, true);
510  }
511 
512 }
513 
514 template<class T>
516 {
517  Vec<T> output;
518  deinterleave(input, output, keepzeros);
519  return output;
520 }
521 
522 template<class T>
524 {
525  interleaver_sequence = sort_index(randu(interleaver_depth));
526 }
527 
528 template<class T>
530 {
531  return interleaver_sequence;
532 }
533 
534 template<class T>
535 void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence)
536 {
537  interleaver_sequence = in_interleaver_sequence;
538  interleaver_depth = interleaver_sequence.size();
539 }
540 
542 
543 // ----------------------------------------------------------------------
544 // Instantiations
545 // ----------------------------------------------------------------------
546 
547 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<double>;
548 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<short>;
549 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<int>;
550 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<std::complex<double> >;
551 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<bin>;
552 
553 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<double>;
554 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<short>;
555 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<int>;
556 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<std::complex<double> >;
557 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<bin>;
558 
559 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<double>;
560 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<short>;
561 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<int>;
562 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<std::complex<double> >;
563 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<bin>;
564 
566 
567 } // namespace itpp
568 
569 #endif // #ifndef INTERLEAVE_H
SourceForge Logo

Generated on Sat May 25 2013 16:32:21 for IT++ by Doxygen 1.8.2