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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use axis;
use utils::PairWise;
#[derive(Debug)]
pub struct Histogram {
pub bin_bounds: Vec<f64>,
pub bin_counts: Vec<u32>,
pub bin_densities: Vec<f64>,
pub x_axis: axis::Axis,
pub y_axis: axis::Axis,
}
impl Histogram {
pub fn from_vec(v: &[f64], num_bins: u32) -> Histogram {
let max = v.iter().fold(-1. / 0., |a, &b| f64::max(a, b));
let min = v.iter().fold(1. / 0., |a, &b| f64::min(a, b));
let num_bins = num_bins as usize;
let mut bins = vec![0; num_bins];
let range = max - min;
let bin_width = (max - min) / num_bins as f64;
let mut bounds: Vec<f64> =
(0..num_bins).map(|n| (n as f64 / num_bins as f64) * range + min).collect();
bounds.push(max);
let bounds = bounds;
for &val in v.iter() {
let bin = bounds.pairwise()
.enumerate()
.skip_while(|&(_, (&l, &u))| !(val >= l && val <= u))
.map(|(i, (_, _))| i)
.next()
.unwrap();
bins[bin] += 1;
}
let density_per_bin = bins.iter().map(|&x| x as f64 / bin_width).collect();
let x_min = *bounds.first().expect("ERROR: There are no ticks for the x-axis");
let x_max = *bounds.last().expect("ERROR: There are no ticks for the x-axis");
let x_axis = axis::Axis::new(x_min, x_max);
let largest_bin_count = *bins.iter().max().expect("ERROR: There are no bins");
let y_axis = axis::Axis::new(0.0, largest_bin_count as f64);
Histogram {
bin_bounds: bounds,
bin_counts: bins,
bin_densities: density_per_bin,
x_axis: x_axis,
y_axis: y_axis,
}
}
pub fn num_bins(&self) -> usize {
self.bin_counts.len()
}
}