data_beans/alg/
normalization.rs1pub trait NormalizeDistance: Iterator<Item = f32> + Sized {
3 fn exp_sum(self, lambda: f32) -> f32
4 where
5 Self: Sized,
6 {
7 self.map(|d| (-d * lambda).exp()).sum()
8 }
9
10 fn normalized_exp(self, target_exp_sum: f32) -> Vec<f32>
11 where
12 Self: Clone,
13 {
14 let dmin = self.clone().fold(f32::INFINITY, |a, b| a.min(b));
16 let dist = self.map(move |d| d - dmin);
17
18 let mut lambda = 10.0;
20 let mut fval = target_exp_sum - dist.clone().exp_sum(lambda);
21 let max_iter = 100;
22
23 for _ in 0..max_iter {
24 let lambda_old = lambda;
25 if fval < 0.0 {
26 lambda *= 2.0; } else {
28 lambda *= 0.5; }
30
31 let fval_new = target_exp_sum - dist.clone().exp_sum(lambda);
32
33 if fval_new.abs() > fval.abs() {
34 lambda = lambda_old;
35 break;
36 }
37
38 fval = fval_new;
39 }
40
41 dist.map(|v| (-v * lambda).exp()).collect()
43 }
44}
45
46impl<I> NormalizeDistance for I where I: Iterator<Item = f32> {}