1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use super::{LinearCode, SparseBinMat};
use bigs::{error::InvalidParameters, graph::Graph, Sampler};
use itertools::Itertools;
use rand::Rng;
use std::error::Error;
use std::fmt;
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
pub struct RandomRegularCode {
block_size: usize,
number_of_checks: usize,
bit_degree: usize,
check_degree: usize,
}
impl RandomRegularCode {
pub fn block_size(&mut self, block_size: usize) -> &mut Self {
self.block_size = block_size;
self
}
pub fn number_of_checks(&mut self, number_of_checks: usize) -> &mut Self {
self.number_of_checks = number_of_checks;
self
}
pub fn bit_degree(&mut self, bit_degree: usize) -> &mut Self {
self.bit_degree = bit_degree;
self
}
pub fn check_degree(&mut self, check_degree: usize) -> &mut Self {
self.check_degree = check_degree;
self
}
pub fn sample_with<R: Rng>(&self, rng: &mut R) -> Result<LinearCode, SamplingError> {
Sampler::builder()
.number_of_variables(self.block_size)
.number_of_constraints(self.number_of_checks)
.variable_degree(self.bit_degree)
.constraint_degree(self.check_degree)
.build()
.map(|sampler| convert_graph_into_code(sampler.sample_with(rng)))
.map_err(|error| SamplingError::from_error(error))
}
}
fn convert_graph_into_code(graph: Graph) -> LinearCode {
let checks = graph
.constraints()
.sorted_by_key(|check| check.label())
.map(|check| check.neighbors().iter().sorted().cloned().collect())
.collect();
let parity_check_matrix = SparseBinMat::new(graph.number_of_variables(), checks);
LinearCode::from_parity_check_matrix(parity_check_matrix)
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct SamplingError {
block_size: usize,
number_of_checks: usize,
bit_degree: usize,
check_degree: usize,
}
impl SamplingError {
fn from_error(error: InvalidParameters) -> Self {
Self {
block_size: error.number_of_variables,
number_of_checks: error.number_of_constraints,
bit_degree: error.variable_degree,
check_degree: error.constraint_degree,
}
}
}
impl fmt::Display for SamplingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"can't generate a regular code with {} bits of degree {} and {} checks of degree {}",
self.block_size, self.bit_degree, self.number_of_checks, self.check_degree
)
}
}
impl Error for SamplingError {}