use super::degree_distribution::SolitonDistribution;
use super::examples::{DeterministicDegreeSet, FixedDegreeSet};
use super::random::RandomDegreeSet;
use super::random_triangular::RandomTriangularDegreeSet;
use super::traits::DegreeSetGenerator;
use fountain_engine::CodeParams;
#[derive(Clone, Debug)]
pub enum DegreeSetConfig {
RandomIdeal,
RandomRobust {
c: f64,
delta: f64,
},
RandomIdealTruncated {
dmax: usize,
},
TriangularIdealTruncated {
dmax: usize,
},
ByName {
name: String,
degree_params: Vec<f64>,
},
}
impl DegreeSetConfig {
pub fn create(&self, params: &CodeParams) -> Box<dyn DegreeSetGenerator> {
match self {
DegreeSetConfig::RandomIdeal => Box::new(RandomDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: params.num_active(),
},
params,
)),
DegreeSetConfig::RandomRobust { c, delta } => Box::new(RandomDegreeSet::new(
&SolitonDistribution::RobustSoliton {
dmax: params.num_active(),
c: *c,
delta: *delta,
},
params,
)),
DegreeSetConfig::RandomIdealTruncated { dmax } => Box::new(RandomDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: *dmax.min(¶ms.num_active()),
},
params,
)),
DegreeSetConfig::TriangularIdealTruncated { dmax } => {
Box::new(RandomTriangularDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: *dmax.min(¶ms.num_active()),
},
params,
))
}
DegreeSetConfig::ByName {
name,
degree_params,
} => create_degree_set_by_name(name, degree_params, params),
}
}
}
pub fn create_degree_set_by_name(
name: &str,
degree_params: &[f64],
code_params: &CodeParams,
) -> Box<dyn DegreeSetGenerator> {
match name.to_lowercase().as_str() {
"random_ideal" => Box::new(RandomDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: code_params.num_active(),
},
code_params,
)),
"random_robust" => {
let c = degree_params.first().copied().unwrap_or(0.1);
let delta = degree_params.get(1).copied().unwrap_or(0.5);
Box::new(RandomDegreeSet::new(
&SolitonDistribution::RobustSoliton {
dmax: code_params.num_active(),
c,
delta,
},
code_params,
))
}
"random_ideal_truncated" => {
let dmax = degree_params.first().map(|&x| x as usize).unwrap_or(30);
Box::new(RandomDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: dmax.min(code_params.num_active()),
},
code_params,
))
}
"triangular_ideal_truncated" => {
let dmax = degree_params.first().map(|&x| x as usize).unwrap_or(30);
Box::new(RandomTriangularDegreeSet::new(
&SolitonDistribution::IdealSoliton {
dmax: dmax.min(code_params.num_active()),
},
code_params,
))
}
"deterministic" => Box::new(DeterministicDegreeSet::new(code_params)),
"fixed_degree" => {
let degree = degree_params.first().map(|&x| x as usize).unwrap_or(3);
Box::new(FixedDegreeSet::new(code_params, degree))
}
_ => panic!("Unknown degree set generator: {}", name),
}
}