Skip to main content

weavatrix_semantic/
vector.rs

1use crate::{Result, SemanticError};
2use weavatrix_graph::NodeId;
3
4/// One graph node represented in a named embedding space.
5#[derive(Debug, Clone, PartialEq)]
6pub struct SemanticVector {
7    node_id: NodeId,
8    values: Vec<f32>,
9    norm: f64,
10}
11
12impl SemanticVector {
13    /// Creates and validates a finite, non-zero embedding vector.
14    ///
15    /// # Errors
16    ///
17    /// Returns an error for an empty node identifier, empty vector, non-finite
18    /// component, or zero-magnitude vector.
19    pub fn new(node_id: impl Into<String>, values: Vec<f32>) -> Result<Self> {
20        let node_id = NodeId::new(node_id)?;
21        if values.is_empty() {
22            return Err(SemanticError::EmptyVector {
23                node: node_id.to_string(),
24            });
25        }
26
27        let mut squared_norm = 0.0_f64;
28        for (index, value) in values.iter().copied().enumerate() {
29            if !value.is_finite() {
30                return Err(SemanticError::NonFiniteVectorValue {
31                    node: node_id.to_string(),
32                    index,
33                });
34            }
35            squared_norm += f64::from(value) * f64::from(value);
36        }
37        if squared_norm == 0.0 {
38            return Err(SemanticError::ZeroVector {
39                node: node_id.to_string(),
40            });
41        }
42
43        Ok(Self {
44            node_id,
45            values,
46            norm: squared_norm.sqrt(),
47        })
48    }
49
50    /// Graph node represented by this vector.
51    #[must_use]
52    pub const fn node_id(&self) -> &NodeId {
53        &self.node_id
54    }
55
56    /// Embedding components.
57    #[must_use]
58    pub fn values(&self) -> &[f32] {
59        &self.values
60    }
61
62    /// Number of embedding dimensions.
63    #[must_use]
64    pub const fn dimension(&self) -> usize {
65        self.values.len()
66    }
67
68    pub(crate) const fn norm(&self) -> f64 {
69        self.norm
70    }
71}