trueno/vector/ops/norms/mod.rs
1//! Vector norm operations
2//!
3//! This module provides vector norm calculations:
4//! - `norm_l1()` - L1 norm (Manhattan norm)
5//! - `norm_l2()` - L2 norm (Euclidean norm)
6//! - `norm_linf()` - L∞ norm (infinity norm / max norm)
7//!
8//! All three norms share the same `unsafe fn(&[f32]) -> f32` backend
9//! signature, so dispatch is handled by the crate-level
10//! [`dispatch_reduction!`] macro -- no per-module dispatch struct needed.
11
12use crate::backends::VectorBackend;
13use crate::{dispatch_reduction, Result, Vector};
14
15impl Vector<f32> {
16 /// L2 norm (Euclidean norm)
17 ///
18 /// Computes the Euclidean length of the vector: sqrt(sum(a\[i\]^2)).
19 /// This is mathematically equivalent to sqrt(dot(self, self)).
20 ///
21 /// # Performance
22 ///
23 /// Uses optimized SIMD implementations via the dot product operation.
24 ///
25 /// # Examples
26 ///
27 /// ```
28 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
29 /// use trueno::Vector;
30 ///
31 /// let v = Vector::from_slice(&[3.0, 4.0]);
32 /// let norm = v.norm_l2()?;
33 /// assert!((norm - 5.0).abs() < 1e-5); // sqrt(3^2 + 4^2) = 5
34 /// # Ok(())
35 /// # }
36 /// ```
37 ///
38 /// # Empty vectors
39 ///
40 /// Returns 0.0 for empty vectors (consistent with the mathematical definition).
41 ///
42 /// ```
43 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
44 /// use trueno::Vector;
45 ///
46 /// let v: Vector<f32> = Vector::from_slice(&[]);
47 /// assert_eq!(v.norm_l2()?, 0.0);
48 /// # Ok(())
49 /// # }
50 /// ```
51 pub fn norm_l2(&self) -> Result<f32> {
52 if self.data.is_empty() {
53 return Ok(0.0);
54 }
55 Ok(dispatch_reduction!(self.backend, norm_l2, &self.data))
56 }
57
58 /// Compute the L1 norm (Manhattan norm) of the vector
59 ///
60 /// Returns the sum of absolute values: ||v||₁ = sum(|v\[i\]|)
61 ///
62 /// The L1 norm is used in:
63 /// - Machine learning (L1 regularization, Lasso regression)
64 /// - Distance metrics (Manhattan distance)
65 /// - Sparse modeling and feature selection
66 /// - Signal processing
67 ///
68 /// # Examples
69 ///
70 /// ```
71 /// use trueno::Vector;
72 ///
73 /// let v = Vector::from_slice(&[3.0, -4.0, 5.0]);
74 /// let norm = v.norm_l1().unwrap();
75 ///
76 /// // |3| + |-4| + |5| = 12
77 /// assert!((norm - 12.0).abs() < 1e-5);
78 /// ```
79 ///
80 /// # Empty Vector
81 ///
82 /// ```
83 /// use trueno::Vector;
84 ///
85 /// let v: Vector<f32> = Vector::from_slice(&[]);
86 /// assert_eq!(v.norm_l1().unwrap(), 0.0);
87 /// ```
88 pub fn norm_l1(&self) -> Result<f32> {
89 if self.data.is_empty() {
90 return Ok(0.0);
91 }
92 Ok(dispatch_reduction!(self.backend, norm_l1, &self.data))
93 }
94
95 /// Compute the L∞ norm (infinity norm / max norm) of the vector
96 ///
97 /// Returns the maximum absolute value: ||v||∞ = max(|v\[i\]|)
98 ///
99 /// The L∞ norm is used in:
100 /// - Numerical analysis (error bounds, stability analysis)
101 /// - Optimization (Chebyshev approximation)
102 /// - Signal processing (peak detection)
103 /// - Distance metrics (Chebyshev distance)
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// use trueno::Vector;
109 ///
110 /// let v = Vector::from_slice(&[3.0, -7.0, 5.0, -2.0]);
111 /// let norm = v.norm_linf().unwrap();
112 ///
113 /// // max(|3|, |-7|, |5|, |-2|) = 7
114 /// assert!((norm - 7.0).abs() < 1e-5);
115 /// ```
116 ///
117 /// # Empty Vector
118 ///
119 /// ```
120 /// use trueno::Vector;
121 ///
122 /// let v: Vector<f32> = Vector::from_slice(&[]);
123 /// assert_eq!(v.norm_linf().unwrap(), 0.0);
124 /// ```
125 pub fn norm_linf(&self) -> Result<f32> {
126 if self.data.is_empty() {
127 return Ok(0.0);
128 }
129 Ok(dispatch_reduction!(self.backend, norm_linf, &self.data))
130 }
131}
132
133#[cfg(test)]
134mod tests;