fpm_rs/algorithms/
metrics.rs1use std::collections::BTreeMap;
4
5use serde::{Deserialize, Serialize};
6
7use crate::reconstruction::AlgorithmMetricRecord;
8
9#[derive(Clone, Debug, Default, Serialize, Deserialize)]
11#[serde(deny_unknown_fields)]
12pub struct StepSummary {
13 pub objective_sum: f64,
15 pub frame_count: usize,
17 pub weight_sum: f64,
19 pub per_frame_objective: BTreeMap<usize, f64>,
21}
22
23impl StepSummary {
24 pub fn push_frame(&mut self, frame: usize, objective: f64, weight: f64) {
26 self.objective_sum += weight * objective;
27 self.frame_count += 1;
28 self.weight_sum += weight;
29 self.per_frame_objective.insert(frame, objective);
30 }
31
32 pub fn mean_objective(&self) -> Option<f64> {
34 (self.weight_sum > 0.0).then(|| self.objective_sum / self.weight_sum)
35 }
36
37 pub fn merge(&mut self, other: Self) {
39 self.objective_sum += other.objective_sum;
40 self.frame_count += other.frame_count;
41 self.weight_sum += other.weight_sum;
42 self.per_frame_objective.extend(other.per_frame_objective);
43 }
44}
45
46pub trait AlgorithmIterationMetrics: Default {
52 fn merge(&mut self, other: Self);
54
55 fn append_records(&self, iteration: usize, output: &mut Vec<AlgorithmMetricRecord>);
57}
58
59#[derive(Clone, Copy, Debug, Default)]
61pub struct NoIterationMetrics;
62
63impl AlgorithmIterationMetrics for NoIterationMetrics {
64 fn merge(&mut self, _other: Self) {}
65
66 fn append_records(&self, _iteration: usize, _output: &mut Vec<AlgorithmMetricRecord>) {}
67}
68
69#[derive(Clone, Debug)]
71pub struct StepOutput<M> {
72 pub summary: StepSummary,
74 pub metrics: M,
76}
77
78impl<M: Default> From<StepSummary> for StepOutput<M> {
79 fn from(summary: StepSummary) -> Self {
80 Self {
81 summary,
82 metrics: M::default(),
83 }
84 }
85}
86
87impl<M: AlgorithmIterationMetrics> Default for StepOutput<M> {
88 fn default() -> Self {
89 Self {
90 summary: StepSummary::default(),
91 metrics: M::default(),
92 }
93 }
94}
95
96impl<M: AlgorithmIterationMetrics> StepOutput<M> {
97 pub fn merge(&mut self, other: Self) {
99 self.summary.merge(other.summary);
100 self.metrics.merge(other.metrics);
101 }
102}