use crate::set::traits::Finite;
use num::{Float, FromPrimitive, Num};
pub trait WeightedSum<Item, V>
where
V: Copy + Num, {
fn weighted_sum(self) -> V;
}
impl<I, P, Dtype> WeightedSum<(P, Dtype), Dtype> for I
where
I: Iterator<Item = (P, Dtype)>,
P: Finite,
Dtype: Float + FromPrimitive,
{
fn weighted_sum(self) -> Dtype {
crate::stats::kahan_sigma(self, |(interval, value)| {
Dtype::from_usize(interval.size())
.expect("failed to convert from usize to Dtype")
* value
})
}
}
#[cfg(test)]
mod tests {
use crate::{interval::I64Interval, iter::weighted_sum::WeightedSum};
#[test]
fn test_weighted_sum() {
let arr = vec![
(I64Interval::new(2, 5), 2f32),
(I64Interval::new(10, 25), 1.5),
(I64Interval::new(1, 5), 0.5),
];
assert_eq!(arr.into_iter().weighted_sum(), 34.5);
let arr = vec![
(I64Interval::new(0, 9), -2f64),
(I64Interval::new(9, 15), 1.5),
(I64Interval::new(0, 20), 0.5),
];
assert_eq!(arr.into_iter().weighted_sum(), 1.0);
}
}