use crate::algebra::finite_field::GF2;
use crate::algebra::finite_field::GF256;
use crate::algebra::linear_algebra::Matrix;
use crate::core::binary_matrix::BinaryMatrix;
use crate::data_manager::DataManager;
use crate::traits::LDPC;
use crate::types::CodeParams;
pub trait HDPC {
fn mul_data(
&self,
_manager: &mut DataManager,
_params: &CodeParams,
_x_ids: &[usize],
_y_ids: &[usize],
) {
}
#[allow(deprecated)]
fn mul_binary(
&self,
gf: Option<&GF256>,
params: &CodeParams,
n: usize,
v: &dyn Fn(usize) -> Vec<u8>,
) -> Vec<Vec<u8>> {
let s = |i: usize| {
v(i).iter()
.enumerate()
.filter(|&(_, &v)| v == 1)
.map(|(j, _)| j)
.collect::<Vec<_>>()
};
self.mul_sparse(gf, params, n, &s)
}
fn mul_binary_from_rows(
&self,
gf: Option<&GF256>,
params: &CodeParams,
rows: &[Vec<u8>],
) -> Vec<Vec<u8>> {
let n = rows.first().map_or(0, Vec::len);
let v = |i: usize| rows[i].clone();
self.mul_binary(gf, params, n, &v)
}
fn mul_binary_packed(
&self,
gf: Option<&GF256>,
params: &CodeParams,
num_inactive: usize,
tilde_g: &BinaryMatrix,
) -> BinaryMatrix {
let v = |i: usize| tilde_g.row_bytes(i, num_inactive);
let dense = self.mul_binary(gf, params, num_inactive, &v);
let mut out = BinaryMatrix::new(num_inactive);
for row in dense {
let nwords = out.words_per_row();
let mut words = vec![0_u64; nwords];
for (seq, &byte) in row.iter().enumerate().take(num_inactive) {
if byte != 0 {
let word = seq / 64;
let bit = seq % 64;
words[word] |= 1_u64 << bit;
}
}
out.append_row_from_words(&words, num_inactive);
}
out
}
#[deprecated(since = "1.1.0", note = "use mul_binary instead")]
fn mul_sparse(
&self,
_gf: Option<&GF256>,
_params: &CodeParams,
_n: usize,
_s: &dyn Fn(usize) -> Vec<usize>,
) -> Vec<Vec<u8>> {
vec![]
}
fn mul_sparse_sh(
&self,
_gf: Option<&GF256>,
_params: &CodeParams,
_s: &dyn Fn(usize) -> Vec<usize>,
) -> Vec<Vec<u8>> {
vec![]
}
fn lu_idssh(
&self,
gf: Option<&GF256>,
params: &CodeParams,
ldpc: &dyn LDPC,
) -> (Vec<usize>, Vec<Vec<u8>>) {
let sh_column = |row: usize| {
ldpc.inactive_row(row)
.into_iter()
.filter(|&id| id >= params.b)
.map(|id| id - params.b)
.collect::<Vec<_>>()
};
let mut m = self.mul_sparse_sh(gf, params, &sh_column);
for (i, row) in m.iter_mut().enumerate().take(params.h) {
row[i] ^= 1; }
let (p, r) = match gf {
Some(gf) => Matrix::lu_decomp(gf, &mut m),
None => Matrix::lu_decomp(&GF2::new(), &mut m),
};
assert_eq!(r, params.h, "I' + D_s S_h singular, rank {r}");
(p, m)
}
fn gf_poly(&self) -> u16 {
0x11D_u16
}
}