I have a general algorithm for calculating the weighted mean that "should" work for almost anything that can be multiplied, divided and added together.
However when trying to send an iterator of floats (f64), I was surprised that it doesn't implement Mul and Div with usize. Does anyone know the reason behind it (I understand that f32 cannot represent every u32, but is this the case for f64 as well?) Is there any easy workaround for this?
Due to the orphan rule, I cannot "just" implement Mul and Div for f64...
pub fn weighted_mean<T: Mul<usize, Output = T> + Add<Output = T> + Div<usize, Output = T> >(input: impl IntoIterator<Item = (T, usize)>) -> T {
let mut iter = input.into_iter();
let first = iter.next().expect("a non-empty iterator");
let (weighted_sum, total_weight) = iter.fold((first.0 * first.1, first.1), |(weighted_sum, total_weight), item| (item.0 * item.1 + weighted_sum, total_weight + item.1));
weighted_sum / total_weight
}
Rust only implements math operators when both sides are the same type. Otherwise, you run into problems with type inference where the compiler is often unable to figure out what integer type something should be.
No, but you can cast your usize to f64 and perform the division.
Well most general I could do is this, but the compiler is not smart enough to figure out all type params unfotunately, and at least the first parameter needs to be supplied.