pub mod angular_momentum;
pub mod enums;
pub mod functions;
pub mod kinematics;
pub mod reaction;
pub mod variables;
pub mod vectors;
pub mod wigner;
pub fn get_bin_edges(bins: usize, range: (f64, f64)) -> Vec<f64> {
let bin_width = (range.1 - range.0) / (bins as f64);
(0..=bins)
.map(|i| range.0 + (i as f64 * bin_width))
.collect()
}
pub fn get_bin_index(value: f64, bins: usize, range: (f64, f64)) -> Option<usize> {
if value >= range.0 && value < range.1 {
let bin_width = (range.1 - range.0) / bins as f64;
let bin_index = ((value - range.0) / bin_width).floor() as usize;
Some(bin_index.min(bins - 1))
} else {
None
}
}
pub struct Histogram {
pub counts: Vec<f64>,
pub bin_edges: Vec<f64>,
}
pub fn histogram<T: AsRef<[f64]>>(
values: T,
bins: usize,
range: (f64, f64),
weights: Option<T>,
) -> Histogram {
assert!(bins > 0, "Number of bins must be greater than zero!");
assert!(
range.1 > range.0,
"The lower edge of the range must be smaller than the upper edge!"
);
if let Some(w) = &weights {
assert_eq!(
values.as_ref().len(),
w.as_ref().len(),
"`values` and `weights` must have the same length!"
);
}
let mut counts = vec![0.0; bins];
for (i, &value) in values.as_ref().iter().enumerate() {
if let Some(bin_index) = get_bin_index(value, bins, range) {
let weight = weights.as_ref().map_or(1.0, |w| w.as_ref()[i]);
counts[bin_index] += weight;
}
}
Histogram {
counts,
bin_edges: get_bin_edges(bins, range),
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::{
data::test_dataset,
traits::Variable,
utils::{get_bin_index, histogram},
Mass,
};
#[test]
fn test_binning() {
let mut v = Mass::new(["kshort1"]);
let dataset = Arc::new(test_dataset());
v.bind(dataset.metadata()).unwrap();
let values = v.value_on(&dataset).unwrap();
let bin_index = get_bin_index(values[0], 3, (0.0, 1.0));
assert_eq!(bin_index, Some(1));
let bin_index = get_bin_index(0.0, 3, (0.0, 1.0));
assert_eq!(bin_index, Some(0));
let bin_index = get_bin_index(0.1, 3, (0.0, 1.0));
assert_eq!(bin_index, Some(0));
let bin_index = get_bin_index(0.9, 3, (0.0, 1.0));
assert_eq!(bin_index, Some(2));
let bin_index = get_bin_index(1.0, 3, (0.0, 1.0));
assert_eq!(bin_index, None);
let bin_index = get_bin_index(2.0, 3, (0.0, 1.0));
assert_eq!(bin_index, None);
let weights = dataset.weights();
let histogram = histogram(&values, 3, (0.0, 1.0), Some(&weights));
assert_eq!(histogram.counts, vec![0.0, 0.48, 0.0]);
assert_eq!(histogram.bin_edges, vec![0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0])
}
}