-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathweighted_average.rs
More file actions
39 lines (37 loc) · 1.36 KB
/
weighted_average.rs
File metadata and controls
39 lines (37 loc) · 1.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use core::ops::{Add, Div, Mul, Sub};
/// Computes the weighted average of two values.
///
/// Returns `(first_value * first_weight + second_value * second_weight) / (first_weight + second_weight)`.
///
/// # Panics
///
/// Panics on division by zero if both weights are zero.
pub fn weighted_average<T>(first_value: T, first_weight: T, second_value: T, second_weight: T) -> T
where
T: Add<Output = T> + Mul<Output = T> + Div<Output = T> + Clone,
{
let weight_sum = first_weight.clone() + second_weight.clone();
let weighted_sum = first_value * first_weight + second_value * second_weight;
weighted_sum / weight_sum
}
/// Computes the weighted average of two values, rounded up (ceiling division).
///
/// Equivalent to [`weighted_average`], but rounds the result up instead of truncating:
/// `(weighted_sum + weight_sum - 1) / weight_sum`.
///
/// # Panics
///
/// Panics on division by zero if both weights are zero.
pub fn weighted_average_round_up<T>(
first_value: T,
first_weight: T,
second_value: T,
second_weight: T,
) -> T
where
T: Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T> + Clone + From<u32>,
{
let weight_sum = first_weight.clone() + second_weight.clone();
let weighted_sum = first_value * first_weight + second_value * second_weight;
(weighted_sum + weight_sum.clone() - T::from(1u32)) / weight_sum
}