arms/core/
point.rs

1//! # Point
2//!
3//! A position in dimensional space. The fundamental primitive.
4//!
5//! Dimensionality is NOT fixed - configure it for your model.
6//! 768-dim, 1024-dim, 4096-dim, or any size you need.
7//!
8//! The point IS the thought's position.
9//! The position IS its relationship to all other thoughts.
10
11/// A point in dimensional space
12#[derive(Clone, Debug, PartialEq)]
13pub struct Point {
14    dims: Vec<f32>,
15}
16
17impl Point {
18    /// Create a new point from a vector of dimensions
19    ///
20    /// # Example
21    /// ```
22    /// use arms::Point;
23    /// let p = Point::new(vec![1.0, 2.0, 3.0]);
24    /// assert_eq!(p.dimensionality(), 3);
25    /// ```
26    pub fn new(dims: Vec<f32>) -> Self {
27        Self { dims }
28    }
29
30    /// Create an origin point (all zeros) of given dimensionality
31    ///
32    /// # Example
33    /// ```
34    /// use arms::Point;
35    /// let origin = Point::origin(768);
36    /// assert_eq!(origin.dimensionality(), 768);
37    /// assert!(origin.dims().iter().all(|&x| x == 0.0));
38    /// ```
39    pub fn origin(dims: usize) -> Self {
40        Self {
41            dims: vec![0.0; dims],
42        }
43    }
44
45    /// Get the dimensionality of this point
46    pub fn dimensionality(&self) -> usize {
47        self.dims.len()
48    }
49
50    /// Access the dimensions as a slice
51    pub fn dims(&self) -> &[f32] {
52        &self.dims
53    }
54
55    /// Mutable access to dimensions
56    pub fn dims_mut(&mut self) -> &mut [f32] {
57        &mut self.dims
58    }
59
60    /// Calculate the magnitude (L2 norm) of this point
61    ///
62    /// # Example
63    /// ```
64    /// use arms::Point;
65    /// let p = Point::new(vec![3.0, 4.0]);
66    /// assert!((p.magnitude() - 5.0).abs() < 0.0001);
67    /// ```
68    pub fn magnitude(&self) -> f32 {
69        self.dims.iter().map(|x| x * x).sum::<f32>().sqrt()
70    }
71
72    /// Check if this point is normalized (magnitude ≈ 1.0)
73    pub fn is_normalized(&self) -> bool {
74        let mag = self.magnitude();
75        (mag - 1.0).abs() < 0.001
76    }
77
78    /// Return a normalized copy of this point
79    ///
80    /// If magnitude is zero, returns a clone of self.
81    ///
82    /// # Example
83    /// ```
84    /// use arms::Point;
85    /// let p = Point::new(vec![3.0, 4.0]);
86    /// let normalized = p.normalize();
87    /// assert!(normalized.is_normalized());
88    /// ```
89    pub fn normalize(&self) -> Self {
90        let mag = self.magnitude();
91        if mag == 0.0 {
92            return self.clone();
93        }
94        Self {
95            dims: self.dims.iter().map(|x| x / mag).collect(),
96        }
97    }
98
99    /// Add another point to this one (element-wise)
100    pub fn add(&self, other: &Point) -> Self {
101        assert_eq!(
102            self.dimensionality(),
103            other.dimensionality(),
104            "Points must have same dimensionality"
105        );
106        Self {
107            dims: self
108                .dims
109                .iter()
110                .zip(other.dims.iter())
111                .map(|(a, b)| a + b)
112                .collect(),
113        }
114    }
115
116    /// Scale this point by a scalar
117    pub fn scale(&self, scalar: f32) -> Self {
118        Self {
119            dims: self.dims.iter().map(|x| x * scalar).collect(),
120        }
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn test_new_point() {
130        let p = Point::new(vec![1.0, 2.0, 3.0]);
131        assert_eq!(p.dimensionality(), 3);
132        assert_eq!(p.dims(), &[1.0, 2.0, 3.0]);
133    }
134
135    #[test]
136    fn test_origin() {
137        let origin = Point::origin(768);
138        assert_eq!(origin.dimensionality(), 768);
139        assert!(origin.dims().iter().all(|&x| x == 0.0));
140    }
141
142    #[test]
143    fn test_magnitude() {
144        let p = Point::new(vec![3.0, 4.0]);
145        assert!((p.magnitude() - 5.0).abs() < 0.0001);
146    }
147
148    #[test]
149    fn test_normalize() {
150        let p = Point::new(vec![3.0, 4.0]);
151        let normalized = p.normalize();
152        assert!(normalized.is_normalized());
153        assert!((normalized.dims()[0] - 0.6).abs() < 0.0001);
154        assert!((normalized.dims()[1] - 0.8).abs() < 0.0001);
155    }
156
157    #[test]
158    fn test_normalize_zero() {
159        let p = Point::origin(3);
160        let normalized = p.normalize();
161        assert_eq!(normalized.dims(), &[0.0, 0.0, 0.0]);
162    }
163
164    #[test]
165    fn test_add() {
166        let a = Point::new(vec![1.0, 2.0]);
167        let b = Point::new(vec![3.0, 4.0]);
168        let c = a.add(&b);
169        assert_eq!(c.dims(), &[4.0, 6.0]);
170    }
171
172    #[test]
173    fn test_scale() {
174        let p = Point::new(vec![1.0, 2.0]);
175        let scaled = p.scale(2.0);
176        assert_eq!(scaled.dims(), &[2.0, 4.0]);
177    }
178
179    #[test]
180    #[should_panic(expected = "same dimensionality")]
181    fn test_add_different_dims_panics() {
182        let a = Point::new(vec![1.0, 2.0]);
183        let b = Point::new(vec![1.0, 2.0, 3.0]);
184        let _ = a.add(&b);
185    }
186}