use super::Reducer;
pub fn cumsum(values: &[f64]) -> Vec<f64> {
let mut total = 0.0f64;
values
.iter()
.map(|&value| {
if value.is_finite() {
total += value;
total
} else {
f64::NAN
}
})
.collect()
}
pub fn diff(values: &[f64]) -> Vec<f64> {
values
.iter()
.enumerate()
.map(
|(index, &value)| match index.checked_sub(1).map(|i| values[i]) {
Some(previous) if previous.is_finite() && value.is_finite() => value - previous,
_ => f64::NAN,
},
)
.collect()
}
pub fn rank(values: &[f64]) -> Vec<f64> {
let mut order: Vec<usize> = (0..values.len())
.filter(|&index| values[index].is_finite())
.collect();
order.sort_by(|&a, &b| values[a].total_cmp(&values[b]));
let mut ranks = vec![f64::NAN; values.len()];
let mut rank = 0usize;
for (position, &index) in order.iter().enumerate() {
if position > 0 && values[order[position - 1]] < values[index] {
rank = position;
}
ranks[index] = rank as f64;
}
ranks
}
pub fn normalize(values: &[f64], basis: Reducer) -> Vec<f64> {
let divisor = basis.reduce(values);
if !divisor.is_finite() || divisor == 0.0 {
return vec![f64::NAN; values.len()];
}
values.iter().map(|&value| value / divisor).collect()
}
#[cfg(test)]
#[path = "tests/map_tests.rs"]
mod tests;