Mon, 01 Dec 2025 19:50:58 -0500
Implement Euclidean for f32 and f64
| src/euclidean.rs | file | annotate | diff | comparison | revisions |
--- a/src/euclidean.rs Fri Nov 28 14:01:14 2025 -0500 +++ b/src/euclidean.rs Mon Dec 01 19:50:58 2025 -0500 @@ -4,7 +4,7 @@ use crate::instance::Instance; use crate::linops::{VectorSpace, AXPY}; -use crate::norms::Reflexive; +use crate::norms::{HasDual, Norm, Normed, Reflexive, L2}; use crate::types::*; pub mod wrap; @@ -92,3 +92,74 @@ /// Returns the origin fn origin() -> <Self as Euclidean<F>>::PrincipalE; } + +macro_rules! scalar_euclidean { + ($f:ident) => { + impl VectorSpace for $f { + type Field = $f; + type PrincipalV = $f; + + #[inline] + fn similar_origin(&self) -> Self::PrincipalV { + 0.0 + } + } + impl AXPY for $f { + #[inline] + fn axpy<I: Instance<$f>>(&mut self, α: $f, x: I, β: $f) { + *self = β * *self + α * x.own() + } + + #[inline] + fn set_zero(&mut self) { + *self = 0.0 + } + } + + impl Norm<L2, $f> for $f { + fn norm(&self, _p: L2) -> $f { + self.abs() + } + } + + impl Normed<$f> for $f { + type NormExp = L2; + + fn norm_exponent(&self) -> Self::NormExp { + L2 + } + } + + impl HasDual<$f> for $f { + type DualSpace = $f; + + #[inline] + fn dual_origin(&self) -> $f { + 0.0 + } + } + + impl Euclidean<$f> for $f { + type PrincipalE = $f; + + #[inline] + fn dot<I: Instance<Self>>(&self, other: I) -> $f { + *self * other.own() + } + + #[inline] + fn norm2_squared(&self) -> $f { + *self * *self + } + + #[inline] + fn dist2_squared<I: Instance<Self>>(&self, y: I) -> $f { + let d = *self - y.own(); + d * d + } + } + }; +} + +scalar_euclidean!(f64); +scalar_euclidean!(f32);