oxios_kernel/memory/
normalizer.rs1pub fn l2_normalize_f32(vector: &mut [f32]) {
11 let norm: f32 = vector.iter().map(|v| v * v).sum::<f32>().sqrt();
12 if norm > 0.0 {
13 for v in vector.iter_mut() {
14 *v /= norm;
15 }
16 }
17}
18
19pub fn l2_normalize_f64(vector: &mut [f64]) {
21 let norm: f64 = vector.iter().map(|v| v * v).sum::<f64>().sqrt();
22 if norm > 0.0 {
23 for v in vector.iter_mut() {
24 *v /= norm;
25 }
26 }
27}
28
29pub fn l2_norm_f32(vector: &[f32]) -> f32 {
31 vector.iter().map(|v| v * v).sum::<f32>().sqrt()
32}
33
34pub fn l2_norm_f64(vector: &[f64]) -> f64 {
36 vector.iter().map(|v| v * v).sum::<f64>().sqrt()
37}
38
39pub fn dot_product_f32(a: &[f32], b: &[f32]) -> f32 {
41 a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
42}
43
44pub fn cosine_similarity_f32(a: &[f32], b: &[f32]) -> f32 {
46 let dot = dot_product_f32(a, b);
47 let na = l2_norm_f32(a);
48 let nb = l2_norm_f32(b);
49 if na == 0.0 || nb == 0.0 {
50 return 0.0;
51 }
52 dot / (na * nb)
53}
54
55#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_l2_normalize_unit_vector() {
65 let mut v = vec![1.0f32, 0.0, 0.0];
66 l2_normalize_f32(&mut v);
67 assert!((l2_norm_f32(&v) - 1.0).abs() < 1e-6);
68 }
69
70 #[test]
71 fn test_l2_normalize_general() {
72 let mut v = vec![3.0f32, 4.0];
73 l2_normalize_f32(&mut v);
74 assert!((l2_norm_f32(&v) - 1.0).abs() < 1e-6);
75 assert!((v[0] - 0.6).abs() < 1e-6);
76 assert!((v[1] - 0.8).abs() < 1e-6);
77 }
78
79 #[test]
80 fn test_l2_normalize_zero() {
81 let mut v = vec![0.0f32, 0.0, 0.0];
82 l2_normalize_f32(&mut v);
83 assert_eq!(v, vec![0.0, 0.0, 0.0]);
84 }
85
86 #[test]
87 fn test_cosine_similarity_identical() {
88 let v = vec![1.0f32, 0.0, 0.0];
89 let sim = cosine_similarity_f32(&v, &v);
90 assert!((sim - 1.0).abs() < 1e-6);
91 }
92
93 #[test]
94 fn test_cosine_similarity_orthogonal() {
95 let a = vec![1.0f32, 0.0, 0.0];
96 let b = vec![0.0f32, 1.0, 0.0];
97 let sim = cosine_similarity_f32(&a, &b);
98 assert!(sim.abs() < 1e-6);
99 }
100
101 #[test]
102 fn test_cosine_similarity_opposite() {
103 let a = vec![1.0f32, 0.0];
104 let b = vec![-1.0f32, 0.0];
105 let sim = cosine_similarity_f32(&a, &b);
106 assert!((sim - (-1.0)).abs() < 1e-6);
107 }
108
109 #[test]
110 fn test_dot_product() {
111 let a = vec![1.0f32, 2.0, 3.0];
112 let b = vec![4.0f32, 5.0, 6.0];
113 assert_eq!(dot_product_f32(&a, &b), 32.0);
114 }
115
116 #[test]
117 fn test_l2_normalize_f64() {
118 let mut v = vec![3.0f64, 4.0];
119 l2_normalize_f64(&mut v);
120 assert!((l2_norm_f64(&v) - 1.0).abs() < 1e-12);
121 }
122}