use crate::error::Result;
use crate::gf2;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PackedRow {
inner: gf2::BitPackedRow,
}
impl PackedRow {
pub fn from_dense(row: &[u8]) -> Result<Self> {
Ok(Self {
inner: gf2::BitPackedRow::try_from_dense(row, row.len())?,
})
}
pub fn zeros(width: usize) -> Self {
Self {
inner: gf2::BitPackedRow::zeros(width),
}
}
pub fn width(&self) -> usize {
self.inner.width()
}
pub fn bit(&self, index: usize) -> Result<u8> {
self.inner.try_bit(index)
}
pub fn to_dense(&self) -> Vec<u8> {
self.inner.to_dense()
}
pub fn xor_assign(&mut self, rhs: &Self) -> Result<()> {
self.inner.xor_assign(&rhs.inner)
}
pub fn dot_parity(&self, rhs: &Self) -> Result<u8> {
self.inner.dot_parity(&rhs.inner)
}
pub fn weight(&self) -> usize {
self.inner.weight()
}
pub fn is_zero(&self) -> bool {
self.inner.is_zero()
}
}
#[derive(Debug, Clone)]
pub struct ReducedRowSpace {
inner: gf2::PackedReducedRows,
rank: usize,
}
impl ReducedRowSpace {
pub fn from_dense_rows(rows: &[Vec<u8>], width: usize) -> Result<Self> {
let reduced = gf2::try_rref_with_width(rows, width)?;
let rank = reduced.pivot_cols.len();
Ok(Self {
inner: gf2::PackedReducedRows::try_from_reduced_rows(&reduced)?,
rank,
})
}
pub fn width(&self) -> usize {
self.inner.width()
}
pub fn rank(&self) -> usize {
self.rank
}
pub fn contains(&self, target: &PackedRow) -> Result<bool> {
gf2::try_in_packed_reduced_row_span(&self.inner, &target.inner)
}
pub fn contains_dense(&self, target: &[u8]) -> Result<bool> {
self.contains(&PackedRow::from_dense(target)?)
}
}
#[derive(Debug, Default)]
pub struct KernelWorkspace {
inner: gf2::RandomWindowKernelWorkspace,
}
impl KernelWorkspace {
pub fn new() -> Self {
Self::default()
}
pub fn kernel_basis(
&mut self,
matrix: &[Vec<u8>],
width: usize,
column_permutation: &[usize],
) -> Result<&[Vec<u8>]> {
self.inner
.try_kernel_basis_with_width(matrix, width, column_permutation)
}
}