hypernonsense/
vector.rs

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
15//distance metric based on cosine distance which is offset from [-1,1] range into the [0,2] range
16pub 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    // Generate a random vector
36    let mut v : Vec<f32> = rng.sample_iter(&StandardNormal).take(dimension).collect::<Vec<f32>>();
37
38    // Calculate vector length
39    let length = v.iter()
40        .map(|a| *a as f64)
41        .map(|a| a * a)
42        .sum::<f64>()
43        .sqrt();
44
45    // Normalize
46    for i in 0..dimension {
47        v[i] /= length as f32;
48    }
49
50    v
51}