ndhistogram/value/
weightedsum.rs

1use std::ops::Mul;
2
3use num_traits::Float;
4
5use crate::{Fill, FillWith};
6
7/// ndhistogram bin value type that calculates a weight sum.
8/// It also provides methods to keep track of the sum of weights squared.
9/// This is used to provide estimates of the statistical error on the weighted
10/// sum. This performs a similar function to `Sumw2` that
11/// [ROOT](https://root.cern.ch/doc/master/classTH1.html) users may be familiar
12/// with.
13#[derive(Copy, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct WeightedSum<T = f64> {
16    sumw: T,
17    sumw2: T,
18}
19
20impl<T: Copy> WeightedSum<T> {
21    /// Factory method to create an unfilled (or zero-valued) WeightedSum.
22    pub fn new() -> Self
23    where
24        Self: Default,
25    {
26        Self::default()
27    }
28
29    /// Get the current value of the weighted sum.
30    pub fn get(&self) -> T {
31        self.sum()
32    }
33
34    /// Get the current value of the weighted sum.
35    pub fn sum(&self) -> T {
36        self.sumw
37    }
38
39    /// Estimate of the variance of the weighted sum value is the sum of the
40    /// weights squared.
41    pub fn variance(&self) -> T {
42        self.sumw2
43    }
44
45    /// Square root of the variance.
46    pub fn standard_deviation<O>(&self) -> O
47    where
48        T: Into<O>,
49        O: Float,
50    {
51        self.variance().into().sqrt()
52    }
53}
54
55impl<T: Copy + Fill> Fill for WeightedSum<T> {
56    #[inline]
57    fn fill(&mut self) {
58        self.sumw.fill();
59        self.sumw2.fill();
60    }
61}
62
63impl<T, W> FillWith<W> for WeightedSum<T>
64where
65    T: FillWith<W> + Copy,
66    W: Mul<Output = W> + Copy,
67{
68    #[inline]
69    fn fill_with(&mut self, weight: W) {
70        self.sumw.fill_with(weight);
71        self.sumw2.fill_with(weight * weight);
72    }
73}