spin_sim/statistics/
equilibration.rs1pub struct EquilCheckpoint {
2 pub sweep: usize,
3 pub energy_avg: Vec<f64>,
4 pub link_overlap_avg: Vec<f64>,
5}
6
7pub struct EquilDiagnosticAccum {
8 n_temps: usize,
9 checkpoints: Vec<usize>,
10 next_ckpt_idx: usize,
11 count: usize,
12 sum_energy: Vec<f64>,
13 sum_link_overlap: Vec<f64>,
14 snapshots: Vec<EquilCheckpoint>,
15}
16
17impl EquilDiagnosticAccum {
18 pub fn new(n_temps: usize, n_sweeps: usize) -> Self {
19 let mut checkpoints = Vec::new();
20 let mut p = 128usize;
21 while p < n_sweeps {
22 checkpoints.push(p);
23 p *= 2;
24 }
25 if checkpoints.last() != Some(&n_sweeps) {
26 checkpoints.push(n_sweeps);
27 }
28
29 Self {
30 n_temps,
31 checkpoints,
32 next_ckpt_idx: 0,
33 count: 0,
34 sum_energy: vec![0.0; n_temps],
35 sum_link_overlap: vec![0.0; n_temps],
36 snapshots: Vec::new(),
37 }
38 }
39
40 pub fn push(&mut self, energies: &[f32], link_overlaps: &[f32]) {
41 self.count += 1;
42 for t in 0..self.n_temps {
43 self.sum_energy[t] += energies[t] as f64;
44 self.sum_link_overlap[t] += link_overlaps[t] as f64;
45 }
46
47 if self.next_ckpt_idx < self.checkpoints.len()
48 && self.count == self.checkpoints[self.next_ckpt_idx]
49 {
50 let c = self.count as f64;
51 self.snapshots.push(EquilCheckpoint {
52 sweep: self.count,
53 energy_avg: self.sum_energy.iter().map(|&s| s / c).collect(),
54 link_overlap_avg: self.sum_link_overlap.iter().map(|&s| s / c).collect(),
55 });
56 self.next_ckpt_idx += 1;
57 }
58 }
59
60 pub fn finish(self) -> Vec<EquilCheckpoint> {
61 self.snapshots
62 }
63}