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
use num_traits::{Float, One, NumAssignOps};
struct Matrix<T> {
values: Vec<T>,
dim: usize,
}
impl<T: PartialEq + Clone> Matrix<T> {
pub fn new(init_value: T, dim: usize) -> Matrix<T> {
Matrix {
values: vec![init_value; dim * dim],
dim: dim,
}
}
#[inline(always)]
pub fn get(&self, ix: (usize, usize)) -> &T {
unsafe { self.values.get_unchecked(ix.0 * self.dim + ix.1) }
}
#[inline(always)]
pub fn set(&mut self, ix: (usize, usize), value: T) {
let mut v = unsafe { self.values.get_unchecked_mut(ix.0 * self.dim + ix.1) };
*v = value;
}
}
pub fn get_jenks_breaks<T>(sorted_values: &[T], nb_class: u32) -> Vec<T>
where T: Float + NumAssignOps
{
let k: usize = nb_class as usize;
let nb_elem: usize = sorted_values.len();
let mut v1 = Matrix::new(1, nb_elem);
let mut v2 = Matrix::new(Float::max_value(), nb_elem);
let (mut v, mut val, mut s1, mut s2, mut w, mut i3, mut i4): (T, T, T, T, T, usize, usize);
for l in 2..(nb_elem + 1) {
s1 = T::zero();
s2 = T::zero();
w = T::zero();
for m in 1..(l + 1) {
i3 = l - m + 1;
val = unsafe { *sorted_values.get_unchecked(i3 - 1) };
s2 += val * val;
s1 += val;
w += One::one();
v = s2 - (s1 * s1) / w;
i4 = i3 - 1;
if i4 != 0 {
for j in 2..k + 1 {
let _v = v + *v2.get((i4 - 1, j - 2));
if *v2.get((l - 1, j - 1)) >= _v {
v2.set((l - 1, j - 1), _v);
v1.set((l - 1, j - 1), i3);
}
}
}
v1.set((l - 1, 0), 1);
v2.set((l - 1, 0), v);
}
}
let mut kclass = vec![0usize; k];
let mut n = nb_elem;
let mut j = k;
while j > 1 {
n = *v1.get(((n - 1), (j - 1))) - 1usize;
kclass[(j - 2)] = n;
j -= 1;
}
let mut breaks = Vec::with_capacity(k);
breaks.push(sorted_values[0]);
for i in 1..k {
breaks.push(sorted_values[(kclass[i - 1usize] - 1)]);
}
breaks.push(sorted_values[(nb_elem - 1)]);
breaks
}