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
use rand::{Rng};
use rand_distr::StandardNormal;
pub fn dot(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let mut acc = 0f32;
for index in 0..a.len() {
acc += a[index] * b[index];
}
return acc;
}
pub fn modified_cosine_distance(a: &[f32], b: &[f32]) -> f32 {
let d = dot(a, b);
(2f32 - (d + 1f32)).max(0f32)
}
pub fn euclidean_distance(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let mut acc = 0f32;
for index in 0..a.len() {
acc += (a[index] - b[index]).powf(2f32);
}
acc = acc.sqrt();
return acc;
}
pub fn random_unit_vector<R:Rng>(dimension:usize, rng: &mut R) -> Vec<f32>
{
let mut v : Vec<f32> = rng.sample_iter(&StandardNormal).take(dimension).collect::<Vec<f32>>();
let length = v.iter()
.map(|a| *a as f64)
.map(|a| a * a)
.sum::<f64>()
.sqrt();
for i in 0..dimension {
v[i] /= length as f32;
}
v
}