diff -r 0a689881b0f1 -r 8264d72aa347 src/euclidean.rs --- a/src/euclidean.rs Mon May 12 16:28:50 2025 -0500 +++ b/src/euclidean.rs Mon May 12 17:10:39 2025 -0500 @@ -3,7 +3,8 @@ */ use crate::instance::Instance; -use crate::norms::{HasDual, Reflexive}; +use crate::linops::AXPY; +use crate::norms::{HasDual, NormExponent, Normed, Reflexive, L2}; use crate::types::*; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; @@ -12,66 +13,68 @@ /// The type should implement vector space operations (addition, subtraction, scalar /// multiplication and scalar division) along with their assignment versions, as well /// as an inner product. -pub trait Euclidean: - HasDual - + Reflexive - + Mul>::Output> - + MulAssign - + Div>::Output> - + DivAssign - + Add>::Output> - + Sub>::Output> - + for<'b> Add<&'b Self, Output = >::Output> - + for<'b> Sub<&'b Self, Output = >::Output> +pub trait Euclidean: + AXPY + + HasDual + //+ Normed + + Reflexive + + Mul::Owned> + + MulAssign + + Div::Owned> + + DivAssign + + Add::Owned> + + Sub::Owned> + + for<'b> Add<&'b Self, Output = ::Owned> + + for<'b> Sub<&'b Self, Output = ::Owned> + AddAssign + for<'b> AddAssign<&'b Self> + SubAssign + for<'b> SubAssign<&'b Self> - + Neg>::Output> + + Neg::Owned> { - type Output: Euclidean; + type Owned_: Euclidean; // Inner product - fn dot>(&self, other: I) -> F; + fn dot>(&self, other: I) -> Self::Field; /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. /// /// This is not automatically implemented to avoid imposing /// `for <'a> &'a Self : Instance` trait bound bloat. - fn norm2_squared(&self) -> F; + fn norm2_squared(&self) -> Self::Field; /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$, /// where `self` is $x$. #[inline] - fn norm2_squared_div2(&self) -> F { - self.norm2_squared() / F::TWO + fn norm2_squared_div2(&self) -> Self::Field { + self.norm2_squared() / Self::Field::TWO } /// Calculate the 2-norm $‖x‖_2$, where `self` is $x$. #[inline] - fn norm2(&self) -> F { + fn norm2(&self) -> Self::Field { self.norm2_squared().sqrt() } /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$. - fn dist2_squared>(&self, y: I) -> F; + fn dist2_squared>(&self, y: I) -> Self::Field; /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$. #[inline] - fn dist2>(&self, y: I) -> F { + fn dist2>(&self, y: I) -> Self::Field { self.dist2_squared(y).sqrt() } /// Projection to the 2-ball. #[inline] - fn proj_ball2(mut self, ρ: F) -> Self { + fn proj_ball2(mut self, ρ: Self::Field) -> Self { self.proj_ball2_mut(ρ); self } /// In-place projection to the 2-ball. #[inline] - fn proj_ball2_mut(&mut self, ρ: F) { + fn proj_ball2_mut(&mut self, ρ: Self::Field) { let r = self.norm2(); if r > ρ { *self *= ρ / r @@ -80,7 +83,7 @@ } /// Trait for [`Euclidean`] spaces with dimensions known at compile time. -pub trait StaticEuclidean: Euclidean { +pub trait StaticEuclidean: Euclidean { /// Returns the origin - fn origin() -> >::Output; + fn origin() -> ::Owned; }