use crate::degree_sets::{
ideal_soliton_cdf, robust_soliton_cdf, RaptorDegreeSetGenerator, CyclicStrideDegreeSetGenerator,
};
use crate::types::PseudoRandom;
use fountain_engine::traits::CodeScheme;
use fountain_engine::types::{CodeParams, CodeType, DecodingConfig};
use crate::types::ProbValue;
use crate::degree_sets::validate_cdf;
#[derive(Clone)]
pub struct RandomLTCode <R: PseudoRandom> {
degree_cdf: Vec<ProbValue>,
params: CodeParams,
dec_config: DecodingConfig,
rng: R,
}
impl <R: PseudoRandom> RandomLTCode<R> {
pub fn new(k: usize, cdf: Vec<ProbValue>, rng: R) -> Self {
let m = cdf.last().expect("CDF must be non-empty");
if !validate_cdf(&cdf, *m as usize) {
panic!("Invalid CDF: {:?}", cdf);
}
Self {
degree_cdf: cdf,
params: CodeParams::new(k, k, 0, 0),
dec_config: DecodingConfig::default(),
rng,
}
}
pub fn new_from_ideal_soliton(k: usize, rng: R) -> Self {
let cdf = ideal_soliton_cdf(k, k);
Self::new(k, cdf, rng)
}
pub fn new_from_robust_soliton(k: usize, rng: R) -> Self {
let cdf = robust_soliton_cdf(k, k, 0.1, 0.5);
Self::new(k, cdf, rng)
}
}
impl<R: PseudoRandom + 'static> CodeScheme for RandomLTCode<R> {
fn get_params(&self) -> CodeParams {
self.params.clone()
}
fn code_type(&self) -> CodeType {
CodeType::Ordinary
}
fn create_degree_set_fn(&self) -> Box<dyn FnMut(usize) -> Vec<usize>> {
let mut degree_set = RaptorDegreeSetGenerator::new(
self.degree_cdf.clone(),
self.params.clone(),
self.rng.clone(),
);
Box::new(move |coded_id| degree_set.degree_set(coded_id))
}
fn create_precode(
&self,
) -> (
Option<Box<dyn fountain_engine::traits::HDPC>>,
Option<Box<dyn fountain_engine::traits::LDPC>>,
) {
(None, None)
}
fn decoding_config(&self) -> DecodingConfig {
self.dec_config.clone()
}
}
#[derive(Clone)]
pub struct DeterministicLTCode {
degree_cdf: Vec<ProbValue>,
params: CodeParams,
}
impl DeterministicLTCode {
pub fn new(k: usize, cdf: Vec<ProbValue>) -> Self {
let m = cdf.last().expect("CDF must be non-empty");
if !validate_cdf(&cdf, *m as usize) {
panic!("Invalid CDF: {:?}", cdf);
}
Self {
degree_cdf: cdf,
params: CodeParams::new(k, k, 0, 0),
}
}
pub fn new_from_ideal_soliton(k: usize) -> Self {
let cdf = ideal_soliton_cdf(k, k);
Self::new(k, cdf)
}
pub fn new_from_robust_soliton(k: usize) -> Self {
let cdf = robust_soliton_cdf(k, k, 0.1, 0.5);
Self::new(k, cdf)
}
}
impl CodeScheme for DeterministicLTCode {
fn get_params(&self) -> CodeParams {
self.params.clone()
}
fn code_type(&self) -> CodeType {
CodeType::Ordinary
}
fn create_degree_set_fn(&self) -> Box<dyn FnMut(usize) -> Vec<usize>> {
let mut degree_set = CyclicStrideDegreeSetGenerator::new(self.params.k, self.degree_cdf.clone());
Box::new(move |coded_id| degree_set.degree_set(coded_id))
}
fn create_precode(
&self,
) -> (
Option<Box<dyn fountain_engine::traits::HDPC>>,
Option<Box<dyn fountain_engine::traits::LDPC>>,
) {
(None, None)
}
fn decoding_config(&self) -> DecodingConfig {
DecodingConfig::default()
}
}