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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use super::DecodingResult;
/// An interface for simulation result.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct SimulationResult {
n_successes: u64,
n_failures: u64,
}
impl SimulationResult {
// ***** Construction *****
/// Creates a new empty `SimulationResult`.
pub fn new() -> Self {
Self { n_successes: 0, n_failures: 0 }
}
/// Creates a new `SimulationResult` from the number of successes and failures.
pub fn with_n_successes_and_failures(n_successes: u64, n_failures: u64) -> Self {
Self { n_successes, n_failures }
}
/// Creates the worse `SimulationResult`. That is, a simulation with failure rate 1.
pub fn worse_result() -> Self {
Self { n_successes: 0, n_failures: 1 }
}
// ***** Updaters *****
pub fn add_decoding_result<D: DecodingResult>(&mut self, result: D) {
if result.is_success() {
self.n_successes += 1;
} else {
self.n_failures += 1;
}
}
// ***** Checkers *****
pub fn has_not_at_least_one_success_and_one_failure(&self) -> bool {
self.n_successes == 0 || self.n_failures == 0
}
/// Checks if `self` has better performance than `other`.
pub fn is_better_than(&self, other: &Self) -> bool {
self.get_failure_rate() < other.get_failure_rate()
}
// ***** Getters *****
pub fn combine_with(&self, other: SimulationResult) -> Self {
Self {
n_successes: self.n_successes + other.n_successes,
n_failures: self.n_failures + other.n_failures,
}
}
/// Get the effective failure rate of `self` for a given code `dimension`.
///
/// This is the equivalent failure rate per bit if `dimension` similar bits without error
/// correction where used.
///
///
/// # Example
///
/// ```
/// use believer::SimulationResult;
/// let result = SimulationResult::with_n_successes_and_failures(9, 16);
/// assert_eq!(result.get_effective_failure_rate_for_code_dimension(2), 0.4);
/// ```
pub fn get_effective_failure_rate_for_code_dimension(&self, dimension: u32) -> f64 {
1.0 - self.get_effective_success_rate_for_code_dimension(dimension)
}
/// Get the effective success rate of `self` for a given code `dimension`.
///
/// This is the equivalent success rate per bit if `dimension` similar bits without error
/// correction where used.
///
///
/// # Example
///
/// ```
/// use believer::SimulationResult;
/// let result = SimulationResult::with_n_successes_and_failures(9, 16);
/// assert_eq!(result.get_effective_success_rate_for_code_dimension(2), 0.6);
/// ```
pub fn get_effective_success_rate_for_code_dimension(&self, dimension: u32) -> f64 {
(self.get_success_rate() as f64).powf(1.0 / dimension as f64)
}
/// Get the failure rate of `self`.
///
/// # Example
///
/// ```
/// use believer::SimulationResult;
/// let result = SimulationResult::with_n_successes_and_failures(9, 16);
/// assert_eq!(result.get_failure_rate(), 0.64);
/// ```
pub fn get_failure_rate(&self) -> f64 {
self.n_failures as f64 / self.get_n_iterations() as f64
}
/// Get the success rate of `self`.
///
/// # Example
///
/// ```
/// use believer::SimulationResult;
/// let result = SimulationResult::with_n_successes_and_failures(9, 16);
/// assert_eq!(result.get_success_rate(), 0.36);
/// ```
pub fn get_success_rate(&self) -> f64 {
self.n_successes as f64 / self.get_n_iterations() as f64
}
pub fn get_n_iterations(&self) -> u64 {
self.n_failures + self.n_successes
}
pub fn get_n_failures(&self) -> u64 {
self.n_failures
}
pub fn get_n_successes(&self) -> u64 {
self.n_successes
}
}