spin_sim/statistics/
results.rs1use super::equilibration::EquilCheckpoint;
2
3pub struct ClusterStats {
4 pub fk_csd: Vec<Vec<u64>>,
6 pub overlap_csd: Vec<Vec<u64>>,
8 pub top_cluster_sizes: Vec<[f64; 4]>,
11}
12
13pub struct Diagnostics {
14 pub mags2_tau: Vec<f64>,
17 pub overlap2_tau: Vec<f64>,
20 pub equil_checkpoints: Vec<EquilCheckpoint>,
23}
24
25pub struct SweepResult {
30 pub mags: Vec<f64>,
32 pub mags2: Vec<f64>,
34 pub mags4: Vec<f64>,
36 pub energies: Vec<f64>,
38 pub energies2: Vec<f64>,
40 pub overlap: Vec<f64>,
42 pub overlap2: Vec<f64>,
44 pub overlap4: Vec<f64>,
46 pub cluster_stats: ClusterStats,
47 pub diagnostics: Diagnostics,
48}
49
50impl SweepResult {
51 pub fn aggregate(results: &[Self]) -> Self {
53 let n = results.len() as f64;
54 let n_temps = results[0].mags.len();
55 let n_overlap = results[0].overlap.len();
56 let n_fk_csd = results[0].cluster_stats.fk_csd.len();
57 let n_ov_csd = results[0].cluster_stats.overlap_csd.len();
58
59 let fk_len = results[0]
60 .cluster_stats
61 .fk_csd
62 .first()
63 .map_or(0, |v| v.len());
64 let ov_len = results[0]
65 .cluster_stats
66 .overlap_csd
67 .first()
68 .map_or(0, |v| v.len());
69
70 let n_top = results[0].cluster_stats.top_cluster_sizes.len();
71
72 let m2_tau_len = results[0].diagnostics.mags2_tau.len();
73 let q2_tau_len = results[0].diagnostics.overlap2_tau.len();
74 let n_ckpts = results[0].diagnostics.equil_checkpoints.len();
75
76 let mut agg = SweepResult {
77 mags: vec![0.0; n_temps],
78 mags2: vec![0.0; n_temps],
79 mags4: vec![0.0; n_temps],
80 energies: vec![0.0; n_temps],
81 energies2: vec![0.0; n_temps],
82 overlap: vec![0.0; n_overlap],
83 overlap2: vec![0.0; n_overlap],
84 overlap4: vec![0.0; n_overlap],
85 cluster_stats: ClusterStats {
86 fk_csd: (0..n_fk_csd).map(|_| vec![0u64; fk_len]).collect(),
87 overlap_csd: (0..n_ov_csd).map(|_| vec![0u64; ov_len]).collect(),
88 top_cluster_sizes: vec![[0.0; 4]; n_top],
89 },
90 diagnostics: Diagnostics {
91 mags2_tau: vec![0.0; m2_tau_len],
92 overlap2_tau: vec![0.0; q2_tau_len],
93 equil_checkpoints: (0..n_ckpts)
94 .map(|i| EquilCheckpoint {
95 sweep: results[0].diagnostics.equil_checkpoints[i].sweep,
96 energy_avg: vec![0.0; n_temps],
97 link_overlap_avg: vec![0.0; n_temps],
98 })
99 .collect(),
100 },
101 };
102
103 for r in results {
104 for (a, &v) in agg.mags.iter_mut().zip(r.mags.iter()) {
105 *a += v;
106 }
107 for (a, &v) in agg.mags2.iter_mut().zip(r.mags2.iter()) {
108 *a += v;
109 }
110 for (a, &v) in agg.mags4.iter_mut().zip(r.mags4.iter()) {
111 *a += v;
112 }
113 for (a, &v) in agg.energies.iter_mut().zip(r.energies.iter()) {
114 *a += v;
115 }
116 for (a, &v) in agg.energies2.iter_mut().zip(r.energies2.iter()) {
117 *a += v;
118 }
119 for (a, &v) in agg.overlap.iter_mut().zip(r.overlap.iter()) {
120 *a += v;
121 }
122 for (a, &v) in agg.overlap2.iter_mut().zip(r.overlap2.iter()) {
123 *a += v;
124 }
125 for (a, &v) in agg.overlap4.iter_mut().zip(r.overlap4.iter()) {
126 *a += v;
127 }
128 for (a, s) in agg
129 .cluster_stats
130 .fk_csd
131 .iter_mut()
132 .zip(r.cluster_stats.fk_csd.iter())
133 {
134 for (ah, &sh) in a.iter_mut().zip(s.iter()) {
135 *ah += sh;
136 }
137 }
138 for (a, s) in agg
139 .cluster_stats
140 .overlap_csd
141 .iter_mut()
142 .zip(r.cluster_stats.overlap_csd.iter())
143 {
144 for (ah, &sh) in a.iter_mut().zip(s.iter()) {
145 *ah += sh;
146 }
147 }
148 for (a, &s) in agg
149 .cluster_stats
150 .top_cluster_sizes
151 .iter_mut()
152 .zip(r.cluster_stats.top_cluster_sizes.iter())
153 {
154 for k in 0..4 {
155 a[k] += s[k];
156 }
157 }
158 for (a, &v) in agg
159 .diagnostics
160 .mags2_tau
161 .iter_mut()
162 .zip(r.diagnostics.mags2_tau.iter())
163 {
164 *a += v;
165 }
166 for (a, &v) in agg
167 .diagnostics
168 .overlap2_tau
169 .iter_mut()
170 .zip(r.diagnostics.overlap2_tau.iter())
171 {
172 *a += v;
173 }
174 for (ac, rc) in agg
175 .diagnostics
176 .equil_checkpoints
177 .iter_mut()
178 .zip(r.diagnostics.equil_checkpoints.iter())
179 {
180 for (a, &v) in ac.energy_avg.iter_mut().zip(rc.energy_avg.iter()) {
181 *a += v;
182 }
183 for (a, &v) in ac
184 .link_overlap_avg
185 .iter_mut()
186 .zip(rc.link_overlap_avg.iter())
187 {
188 *a += v;
189 }
190 }
191 }
192
193 for v in agg
194 .mags
195 .iter_mut()
196 .chain(agg.mags2.iter_mut())
197 .chain(agg.mags4.iter_mut())
198 .chain(agg.energies.iter_mut())
199 .chain(agg.energies2.iter_mut())
200 .chain(agg.overlap.iter_mut())
201 .chain(agg.overlap2.iter_mut())
202 .chain(agg.overlap4.iter_mut())
203 {
204 *v /= n;
205 }
206
207 for arr in agg.cluster_stats.top_cluster_sizes.iter_mut() {
208 for v in arr.iter_mut() {
209 *v /= n;
210 }
211 }
212
213 for v in agg.diagnostics.mags2_tau.iter_mut() {
214 *v /= n;
215 }
216 for v in agg.diagnostics.overlap2_tau.iter_mut() {
217 *v /= n;
218 }
219 for ckpt in agg.diagnostics.equil_checkpoints.iter_mut() {
220 for v in ckpt.energy_avg.iter_mut() {
221 *v /= n;
222 }
223 for v in ckpt.link_overlap_avg.iter_mut() {
224 *v /= n;
225 }
226 }
227
228 agg
229 }
230}