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
use crate::{Decoder, DecodingResult};
use rayon::prelude::*;
pub struct Simulator<'a, D>
where
D: Decoder,
{
decoder: &'a D,
}
impl<'a, D> Simulator<'a, D>
where
D: Decoder,
{
pub fn new(decoder: &'a D) -> Self {
Self { decoder }
}
pub fn simulate_n_iterations(&self, n_iterations: usize) -> SimulationResult {
let successes: usize = (0..n_iterations)
.into_par_iter()
.map::<_, D::Result>(|_| {
let error = self.decoder.random_error();
self.decoder.decode(&error)
})
.filter(|decoding| decoding.succeed())
.count();
SimulationResult {
successes,
failures: n_iterations - successes,
}
}
pub fn simulate_until_failures_are_found(
&self,
n_threads: usize,
n_failures_per_thread: usize,
) -> SimulationResult {
let successes = (0..n_threads)
.into_par_iter()
.map::<_, usize>(|_| {
(0..n_failures_per_thread)
.into_par_iter()
.map(|_| {
let mut successes = 0;
let mut has_failed = false;
while !has_failed {
let error = self.decoder.random_error();
if self.decoder.decode(&error).succeed() {
successes += 1;
} else {
has_failed = true;
}
}
successes
})
.sum()
})
.sum();
SimulationResult {
successes,
failures: n_failures_per_thread * n_threads,
}
}
}
pub struct SimulationResult {
successes: usize,
failures: usize,
}
impl SimulationResult {
pub fn failure_rate(&self) -> f64 {
self.failures() as f64 / self.total() as f64
}
pub fn failures(&self) -> usize {
self.failures
}
pub fn success_rate(&self) -> f64 {
self.successes() as f64 / self.total() as f64
}
pub fn successes(&self) -> usize {
self.successes
}
pub fn total(&self) -> usize {
self.failures() + self.successes()
}
}