1use rand::{Rng};
2use rand_distr::StandardNormal;
3
4pub fn dot(a: &[f32], b: &[f32]) -> f32 {
5 assert_eq!(a.len(), b.len());
6
7 let mut acc = 0f32;
8 for index in 0..a.len() {
9 acc += a[index] * b[index];
10 }
11
12 return acc;
13}
14
15pub fn modified_cosine_distance(a: &[f32], b: &[f32]) -> f32 {
17 let d = dot(a, b);
18 (2f32 - (d + 1f32)).max(0f32)
19}
20
21pub fn euclidean_distance(a: &[f32], b: &[f32]) -> f32 {
22 assert_eq!(a.len(), b.len());
23
24 let mut acc = 0f32;
25 for index in 0..a.len() {
26 acc += (a[index] - b[index]).powf(2f32);
27 }
28 acc = acc.sqrt();
29
30 return acc;
31}
32
33pub fn random_unit_vector<R:Rng>(dimension:usize, rng: &mut R) -> Vec<f32>
34{
35 let mut v : Vec<f32> = rng.sample_iter(&StandardNormal).take(dimension).collect::<Vec<f32>>();
37
38 let length = v.iter()
40 .map(|a| *a as f64)
41 .map(|a| a * a)
42 .sum::<f64>()
43 .sqrt();
44
45 for i in 0..dimension {
47 v[i] /= length as f32;
48 }
49
50 v
51}