use crate::traits::DataOperator;
use crate::algebra::finite_field::{Field, GF256};
use crate::types::{CodeParams, GF2_FIELD_POLY, Operation, SolverType};
use std::collections::HashMap;
const MAX_DATA_VECTOR_ID: usize = 10000000;
pub struct DataManager {
params: CodeParams,
variable_data_id_0: usize,
operations: Vec<Operation>,
last_retrieved_index: usize,
next_data_id: usize,
coded_id_to_data_id: HashMap<usize, usize>,
operator: Option<Box<dyn DataOperator>>,
pub num_coded_vector_inserted: usize,
gf256: Option<GF256>,
}
impl Default for DataManager {
fn default() -> Self {
Self::new()
}
}
impl DataManager {
pub fn new() -> Self {
Self {
params: CodeParams::new(0, 0, 0, 0),
variable_data_id_0: 0,
operations: Vec::new(),
next_data_id: MAX_DATA_VECTOR_ID,
coded_id_to_data_id: HashMap::new(),
operator: None,
last_retrieved_index: 0,
num_coded_vector_inserted: 0,
gf256: None,
}
}
pub fn new_with_operator(operator: Box<dyn DataOperator>) -> Self {
Self {
params: CodeParams::new(0, 0, 0, 0),
variable_data_id_0: 0,
operations: Vec::new(),
next_data_id: MAX_DATA_VECTOR_ID,
coded_id_to_data_id: HashMap::new(),
operator: Some(operator),
last_retrieved_index: 0,
num_coded_vector_inserted: 0,
gf256: None,
}
}
pub fn config_from(&mut self, params: CodeParams, solver_type: SolverType) {
self.params = params;
match solver_type {
SolverType::OrdEnc => {
self.variable_data_id_0 = 0;
}
SolverType::OrdDec => {
self.variable_data_id_0 = 0;
}
SolverType::SysEnc => {
self.variable_data_id_0 = self.params.k;
}
SolverType::SysDec => {
self.variable_data_id_0 = self.params.k;
}
}
self.next_data_id = self.variable_data_id_0 + self.params.num_total();
}
pub fn config_finite_field(&mut self, pp: u16) {
if pp == GF2_FIELD_POLY {
self.gf256 = None;
} else {
self.gf256 = Some(GF256::new_with_primitive_polynomial(pp));
}
if let Some(operator) = self.operator.as_mut() {
operator.config_finite_field(pp);
}
}
pub fn config_finite_field_from(&mut self, gf: &GF256) {
self.gf256 = Some(gf.clone());
if let Some(operator) = self.operator.as_mut() {
operator.config_finite_field_from(gf);
}
}
#[inline]
pub fn gf256(&self) -> Option<&GF256> {
self.gf256.as_ref()
}
pub fn insert_coded_id(&mut self, coded_id: usize) -> usize {
self.num_coded_vector_inserted += 1;
if let Some(data_id) = self.coded_id_to_data_id.get(&coded_id) {
*data_id
} else {
let data_id = self.next_data_id;
self.next_data_id += 1;
self.coded_id_to_data_id.insert(coded_id, data_id);
data_id
}
}
pub fn assign_data_id(&mut self, coded_id: usize, data_id: usize) {
self.coded_id_to_data_id.insert(coded_id, data_id);
}
pub fn coded_data_id(&mut self, coded_id: usize) -> usize {
let data_id = self.next_data_id;
self.next_data_id += 1;
self.coded_id_to_data_id.insert(coded_id, data_id);
self.ensure_zero(&[data_id]);
data_id
}
pub fn temp_data_id(&mut self) -> usize {
let data_id = self.next_data_id;
self.next_data_id += 1;
self.ensure_zero(&[data_id]);
data_id
}
pub fn data_id_of_coded_vector(&self, coded_id: usize) -> Option<usize> {
self.coded_id_to_data_id.get(&coded_id).cloned()
}
pub fn data_id_of_variable_vector(&self, var_id: usize) -> usize {
var_id + self.variable_data_id_0
}
pub fn data_id_range_of_active_variable(&self) -> Vec<usize> {
(self.variable_data_id_0..self.variable_data_id_0 + self.params.num_active()).collect()
}
pub fn data_id_range_of_msg_ldpc_variable(&self) -> Vec<usize> {
(self.variable_data_id_0..self.variable_data_id_0 + self.params.num_message_ldpc())
.collect()
}
pub fn data_id_range_of_ldpc_variable(&self) -> Vec<usize> {
(self.variable_data_id_0 + self.params.a
..self.variable_data_id_0 + self.params.a + self.params.l)
.collect()
}
pub fn data_id_range_of_hdpc_variable(&self) -> Vec<usize> {
(self.variable_data_id_0 + self.params.num_message_ldpc()
..self.variable_data_id_0 + self.params.num_total())
.collect()
}
pub fn data_id_of_active_variable(&self, idx: usize) -> usize {
self.variable_data_id_0 + idx
}
pub fn data_id_of_inactive_variable(&self, idx: usize) -> usize {
self.variable_data_id_0 + self.params.num_active() + idx
}
pub fn data_id_of_ldpc_variable(&mut self, idx: usize) -> usize {
self.variable_data_id_0 + self.params.a + idx
}
pub fn data_id_of_hdpc_variable(&self, idx: usize) -> usize {
self.variable_data_id_0 + idx + self.params.num_message_ldpc()
}
pub fn get_operations(&self) -> &[Operation] {
&self.operations
}
pub fn clear_operations(&mut self) {
self.operations.clear();
self.last_retrieved_index = 0;
}
pub fn move_new_operations(&mut self) -> Vec<Operation> {
let start = self.last_retrieved_index;
let end = self.operations.len();
self.last_retrieved_index = end;
self.operations[start..end].to_vec()
}
pub fn move_operator(&mut self) -> Box<dyn DataOperator> {
self.operator.take().unwrap()
}
pub fn set_operator(&mut self, operator: Box<dyn DataOperator>) {
self.operator = Some(operator);
}
fn save_operation(&mut self, operation: Operation) {
self.operations.push(operation.clone());
if let Some(ref mut operator) = self.operator {
operator.execute(&operation);
}
}
pub fn get_variable_vector(&self, var_id: usize) -> Vec<u8> {
if let Some(operator) = self.operator.as_ref() {
operator
.get_vector(self.data_id_of_variable_vector(var_id))
.to_vec()
} else {
panic!("Operator is not set");
}
}
pub fn get_data_vector(&self, data_id: usize) -> &[u8] {
if let Some(operator) = self.operator.as_ref() {
operator.get_vector(data_id)
} else {
panic!("Operator is not set");
}
}
pub fn get_coded_vector(&self, coded_id: usize) -> Vec<u8> {
if let Some(data_id) = self.coded_id_to_data_id.get(&coded_id) {
if let Some(operator) = self.operator.as_ref() {
operator.get_vector(*data_id).to_vec()
} else {
panic!("Operator is not set");
}
} else {
panic!("Coded vector with ID {} does not exist", coded_id);
}
}
pub fn insert_data_vector(&mut self, data_id: usize, vector: &[u8]) {
if let Some(operator) = self.operator.as_mut() {
operator.insert_vector(vector, data_id);
} else {
panic!("Operator is not set");
}
}
pub fn insert_coded_vector(&mut self, coded_id: usize, vector: &[u8]) {
let data_id = self.insert_coded_id(coded_id);
if let Some(operator) = self.operator.as_mut() {
operator.insert_vector(vector, data_id);
} else {
panic!("Operator is not set");
}
}
pub fn ensure_zero(&mut self, list_id: &[usize]) {
self.save_operation(Operation::EnsureZero {
list_id: list_id.to_vec(),
});
}
pub fn multiply_alpha(&mut self, id: usize) {
self.save_operation(Operation::MultiplyAlpha { id });
}
pub fn multiply_scalar(&mut self, scalar: u8, id: usize) {
if scalar == 0 {
self.save_operation(Operation::EnsureZero { list_id: vec![id] });
} else if scalar == 1 {
} else if let Some(gf) = self.gf256() {
if scalar == gf.primitive_element() {
self.save_operation(Operation::MultiplyAlpha { id });
} else {
self.save_operation(Operation::MultiplyScalar { scalar, id });
}
} else {
panic!("GF(256) is not set");
}
}
pub fn divide_scalar(&mut self, scalar: u8, id: usize) {
if scalar == 1 {
} else if let Some(gf) = self.gf256() {
let inverse = gf.inverse(scalar);
if inverse == gf.primitive_element() {
self.save_operation(Operation::MultiplyAlpha { id });
} else {
self.save_operation(Operation::MultiplyScalar {
scalar: inverse,
id,
});
}
} else {
panic!("GF(256) is not set");
}
}
pub fn add_to_vector(&mut self, list_id: &[usize], target_id: usize) {
self.save_operation(Operation::AddToVector {
list_id: list_id.to_vec(),
target_id,
});
}
pub fn broadcast_add(&mut self, src_id: usize, target_ids: &[usize]) {
self.save_operation(Operation::BroadcastAdd {
src_id,
target_ids: target_ids.to_vec(),
});
}
pub fn mul_add(&mut self, src_id: usize, scalar: u8, target_id: usize) {
if scalar == 0 {
} else if scalar == 1 {
self.save_operation(Operation::AddToVector {
list_id: vec![src_id],
target_id,
});
} else {
self.save_operation(Operation::MulAdd {
src_id,
scalar,
target_id,
});
}
}
pub fn move_to(&mut self, src_id: usize, target_id: usize) {
if src_id == target_id {
return;
}
self.save_operation(Operation::MoveTo { src_id, target_id });
}
pub fn copy_to(&mut self, src_id: usize, target_id: usize) {
if src_id == target_id {
return;
}
self.save_operation(Operation::CopyTo { src_id, target_id });
}
pub fn remove(&mut self, id: usize) {
self.save_operation(Operation::Remove { id });
}
pub fn add_coded_vector(&mut self, coded_id: usize, data_id: usize) {
self.save_operation(Operation::InfoCodedVector { coded_id, data_id });
}
pub fn encode_coded_vector(&mut self, coded_id: usize, data_id: usize) {
self.save_operation(Operation::InfoCodedVector { coded_id, data_id });
}
}
#[macro_export]
macro_rules! lu_solve {
($manager:expr, $matrix_a:expr, $target_ids:expr) => {{
let matrix_a = $matrix_a;
let target_ids = $target_ids;
if matrix_a.len() != target_ids.len() {
panic!("The number of rows in A must be equal to the number of target IDs");
}
let n = matrix_a.len();
for j in 0..n - 1 {
for i in j + 1..n {
if matrix_a[i][j] != 0 {
$manager.mul_add(target_ids[j], matrix_a[i][j], target_ids[i]);
}
}
}
for j in (0..n).rev() {
if matrix_a[j][j] == 0 {
panic!(
"Singular matrix: diagonal element at position {} is zero",
j
);
}
$manager.divide_scalar(matrix_a[j][j], target_ids[j]);
for i in (0..j).rev() {
if matrix_a[i][j] != 0 {
$manager.mul_add(target_ids[j], matrix_a[i][j], target_ids[i]);
}
}
}
}};
}
#[macro_export]
macro_rules! lu_solve_incr {
($manager:expr, $matrix_a:expr, $target_ids:expr, $q:expr) => {{
let matrix_a = $matrix_a;
let target_ids = $target_ids;
let q = $q;
if matrix_a.len() != target_ids.len() {
panic!("The number of rows in A must be equal to the number of target IDs");
}
let n = matrix_a.len();
for j in 0..n - 1 {
for i in j + 1..n {
let l = matrix_a[i][q[j]];
if l != 0 {
$manager.mul_add(target_ids[j], l, target_ids[i]);
}
}
}
for j in (0..n).rev() {
let l = matrix_a[j][q[j]];
if l == 0 {
panic!(
"Singular matrix: diagonal element at position {} is zero",
j
);
}
$manager.divide_scalar(l, target_ids[j]);
for i in (0..j).rev() {
let l = matrix_a[i][q[j]];
if l != 0 {
$manager.mul_add(target_ids[j], l, target_ids[i]);
}
}
}
}};
}