1use super::{
7 DecoderOutput, LdpcDecoder, Messages, arithmetic::DecoderArithmetic, check_llrs, hard_decisions,
8};
9use crate::sparse::SparseMatrix;
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct Decoder<A: DecoderArithmetic> {
14 arithmetic: A,
15 h: SparseMatrix,
16 input_llrs: Box<[A::Llr]>,
17 output_llrs: Box<[A::Llr]>,
18 check_messages: Messages<A::CheckMessage>,
19 variable_messages: Messages<A::VarMessage>,
20}
21
22impl<A: DecoderArithmetic> Decoder<A> {
23 pub fn new(h: SparseMatrix, arithmetic: A) -> Self {
27 let input_llrs = vec![Default::default(); h.num_cols()].into_boxed_slice();
28 let output_llrs = input_llrs.clone();
29 let check_messages = Messages::from_iter((0..h.num_cols()).map(|c| h.iter_col(c)));
30 let variable_messages = Messages::from_iter((0..h.num_rows()).map(|r| h.iter_row(r)));
31 Decoder {
32 arithmetic,
33 h,
34 input_llrs,
35 output_llrs,
36 check_messages,
37 variable_messages,
38 }
39 }
40
41 pub fn decode(
52 &mut self,
53 llrs: &[f64],
54 max_iterations: usize,
55 ) -> Result<DecoderOutput, DecoderOutput> {
56 assert_eq!(llrs.len(), self.input_llrs.len());
57 let input_llrs_hard_decision = |x| x <= 0.0;
58 if check_llrs(&self.h, llrs, input_llrs_hard_decision) {
59 return Ok(DecoderOutput {
61 codeword: hard_decisions(llrs, input_llrs_hard_decision),
62 iterations: 0,
63 });
64 }
65 self.initialize(llrs);
66 for iteration in 1..=max_iterations {
67 self.process_check_nodes();
68 self.process_variable_nodes();
69 if check_llrs(&self.h, &self.output_llrs, |x| {
70 self.arithmetic.llr_hard_decision(x)
71 }) {
72 return Ok(DecoderOutput {
74 codeword: hard_decisions(&self.output_llrs, |x| {
75 self.arithmetic.llr_hard_decision(x)
76 }),
77 iterations: iteration,
78 });
79 }
80 }
81 Err(DecoderOutput {
83 codeword: hard_decisions(&self.output_llrs, |x| self.arithmetic.llr_hard_decision(x)),
84 iterations: max_iterations,
85 })
86 }
87
88 fn initialize(&mut self, llrs: &[f64]) {
89 for (x, &y) in self.input_llrs.iter_mut().zip(llrs.iter()) {
90 *x = self.arithmetic.input_llr_quantize(y)
91 }
92
93 for (v, &llr) in self.input_llrs.iter().enumerate() {
95 for &c in self.h.iter_col(v) {
96 self.variable_messages
97 .send(v, c, self.arithmetic.llr_to_var_message(llr));
98 }
99 }
100 }
101
102 fn process_check_nodes(&mut self) {
103 for (c, messages) in self.variable_messages.per_destination.iter().enumerate() {
104 self.arithmetic.send_check_messages(messages, {
105 let check_messages = &mut self.check_messages;
106 move |msg| check_messages.send(c, msg.dest, msg.value)
107 });
108 }
109 }
110
111 fn process_variable_nodes(&mut self) {
112 for (((v, messages), output_llr), &input_llr) in self
113 .check_messages
114 .per_destination
115 .iter()
116 .enumerate()
117 .zip(self.output_llrs.iter_mut())
118 .zip(self.input_llrs.iter())
119 {
120 *output_llr = self.arithmetic.send_var_messages(input_llr, messages, {
121 let var_messages = &mut self.variable_messages;
122 move |msg| var_messages.send(v, msg.dest, msg.value)
123 });
124 }
125 }
126}
127
128impl<A: DecoderArithmetic> LdpcDecoder for Decoder<A> {
129 fn decode(
130 &mut self,
131 llrs: &[f64],
132 max_iterations: usize,
133 ) -> Result<DecoderOutput, DecoderOutput> {
134 Decoder::decode(self, llrs, max_iterations)
135 }
136}
137
138#[cfg(test)]
139mod test {
140 use super::super::arithmetic::Phif64;
141 use super::*;
142
143 fn test_decoder() -> Decoder<Phif64> {
144 let mut h = SparseMatrix::new(4, 6);
146 h.insert_row(0, [0, 1, 3].iter());
147 h.insert_row(1, [1, 2, 4].iter());
148 h.insert_row(2, [0, 4, 5].iter());
149 h.insert_row(3, [2, 3, 5].iter());
150 Decoder::new(h, Phif64::new())
151 }
152
153 fn to_llrs(bits: &[u8]) -> Vec<f64> {
156 bits.iter()
157 .map(|&b| if b == 0 { 1.3863 } else { -1.3863 })
158 .collect()
159 }
160
161 #[test]
162 fn no_errors() {
163 let mut decoder = test_decoder();
164 let codeword = [0, 0, 1, 0, 1, 1];
165 let max_iter = 100;
166 let DecoderOutput {
167 codeword: decoded,
168 iterations,
169 } = decoder.decode(&to_llrs(&codeword), max_iter).unwrap();
170 assert_eq!(&decoded, &codeword);
171 assert_eq!(iterations, 0);
172 }
173
174 #[test]
175 fn single_error() {
176 let mut decoder = test_decoder();
177 let codeword_good = [0, 0, 1, 0, 1, 1];
178 for j in 0..codeword_good.len() {
179 let mut codeword_bad = codeword_good;
180 codeword_bad[j] ^= 1;
181 let max_iter = 100;
182 let DecoderOutput {
183 codeword: decoded,
184 iterations,
185 } = decoder.decode(&to_llrs(&codeword_bad), max_iter).unwrap();
186 assert_eq!(&decoded, &codeword_good);
187 assert_eq!(iterations, 1);
188 }
189 }
190}