ldpc_toolbox/simulation/
interleaving.rs1use ndarray::{Array1, Array2, ArrayBase, Axis, Data, Ix1};
8use num_traits::Zero;
9
10#[derive(Debug, Clone)]
15pub struct Interleaver {
16 columns: usize,
17 read_rows_backwards: bool,
18}
19
20impl Interleaver {
21 pub fn new(columns: usize, read_rows_backwards: bool) -> Interleaver {
29 Interleaver {
30 columns,
31 read_rows_backwards,
32 }
33 }
34
35 pub fn interleave<S, T: Clone + Zero>(&self, codeword: &ArrayBase<S, Ix1>) -> Array1<T>
41 where
42 S: Data<Elem = T>,
43 {
44 assert_eq!(codeword.len() % self.columns, 0);
45 let a2 = codeword
46 .view()
47 .into_shape_with_order((self.columns, codeword.len() / self.columns))
48 .unwrap();
49 let mut transpose = a2.t();
50 if self.read_rows_backwards {
51 transpose.invert_axis(Axis(1));
52 }
53 let mut a = Array2::zeros(transpose.raw_dim());
54 a.assign(&transpose);
55 a.view()
56 .into_shape_with_order(codeword.len())
57 .unwrap()
58 .to_owned()
59 }
60
61 pub fn deinterleave<T: Clone + Zero>(&self, codeword: &[T]) -> Vec<T> {
67 assert_eq!(codeword.len() % self.columns, 0);
68 let codeword = Array1::from_iter(codeword.iter().cloned());
69 let a2 = codeword
70 .view()
71 .into_shape_with_order((codeword.len() / self.columns, self.columns))
72 .unwrap();
73 let mut transpose = a2.t();
74 if self.read_rows_backwards {
75 transpose.invert_axis(Axis(0));
76 }
77 let mut a = Array2::zeros(transpose.raw_dim());
78 a.assign(&transpose);
79 a.view()
80 .into_shape_with_order(codeword.len())
81 .unwrap()
82 .iter()
83 .cloned()
84 .collect()
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use super::*;
91
92 #[test]
93 fn interleaver_3() {
94 let interleaver = Interleaver::new(3, false);
95 let interleaved = interleaver.interleave(&ndarray::arr1(&[0, 1, 2, 3, 4, 5]));
96 let expected = [0, 2, 4, 1, 3, 5];
97 assert_eq!(interleaved.as_slice().unwrap(), &expected);
98 }
99
100 #[test]
101 fn interleaver_3_backwards() {
102 let interleaver = Interleaver::new(3, true);
103 let interleaved = interleaver.interleave(&ndarray::arr1(&[0, 1, 2, 3, 4, 5]));
104 let expected = [4, 2, 0, 5, 3, 1];
105 assert_eq!(interleaved.as_slice().unwrap(), &expected);
106 }
107
108 #[test]
109 fn deinterleaver_3() {
110 let interleaver = Interleaver::new(3, false);
111 let original = [0, 1, 2, 3, 4, 5];
112 let interleaved = interleaver.interleave(&ndarray::arr1(&original));
113 let deinterleaved = interleaver.deinterleave(interleaved.as_slice().unwrap());
114 assert_eq!(&deinterleaved, &original);
115 }
116
117 #[test]
118 fn deinterleaver_3_backwards() {
119 let interleaver = Interleaver::new(3, true);
120 let original = [0, 1, 2, 3, 4, 5];
121 let interleaved = interleaver.interleave(&ndarray::arr1(&original));
122 let deinterleaved = interleaver.deinterleave(interleaved.as_slice().unwrap());
123 assert_eq!(&deinterleaved, &original);
124 }
125}