diff -r d97fcf22a61c -r b53806de0be0 src/direct_product.rs --- a/src/direct_product.rs Thu May 01 00:08:09 2025 -0500 +++ b/src/direct_product.rs Thu May 01 01:05:00 2025 -0500 @@ -320,44 +320,57 @@ type PairOutput = Pair<>::Output, >::Output>; -impl Euclidean for Pair -where - A: Euclidean, - B: Euclidean, - F: Float, - PairOutput: Euclidean, - Self: Sized - + Mul> - + MulAssign - + Div> - + DivAssign - + Add> - + Sub> - + for<'b> Add<&'b Self, Output = PairOutput> - + for<'b> Sub<&'b Self, Output = PairOutput> - + AddAssign - + for<'b> AddAssign<&'b Self> - + SubAssign - + for<'b> SubAssign<&'b Self> - + Neg>, -{ - type Output = PairOutput; +/// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output` +/// to avoid compiler overflows that the requirement +/// ``` +/// Pair<>::Output, >::Output> : Euclidean +/// ``` +/// would generate. - fn dot>(&self, other: I) -> F { - let Pair(u, v) = other.decompose(); - self.0.dot(u) + self.1.dot(v) - } +macro_rules! impl_euclidean { + ($field:ty) => { + impl Euclidean<$field> for Pair + where + A: Euclidean<$field>, + B: Euclidean<$field>, + PairOutput<$field, A, B>: Euclidean<$field>, + Self: Sized + + Mul<$field, Output = PairOutput<$field, A, B>> + + MulAssign<$field> + + Div<$field, Output = PairOutput<$field, A, B>> + + DivAssign<$field> + + Add> + + Sub> + + for<'b> Add<&'b Self, Output = PairOutput<$field, A, B>> + + for<'b> Sub<&'b Self, Output = PairOutput<$field, A, B>> + + AddAssign + + for<'b> AddAssign<&'b Self> + + SubAssign + + for<'b> SubAssign<&'b Self> + + Neg>, + { + type Output = PairOutput<$field, A, B>; - fn norm2_squared(&self) -> F { - self.0.norm2_squared() + self.1.norm2_squared() - } + fn dot>(&self, other: I) -> $field { + let Pair(u, v) = other.decompose(); + self.0.dot(u) + self.1.dot(v) + } + + fn norm2_squared(&self) -> $field { + self.0.norm2_squared() + self.1.norm2_squared() + } - fn dist2_squared>(&self, other: I) -> F { - let Pair(u, v) = other.decompose(); - self.0.dist2_squared(u) + self.1.dist2_squared(v) - } + fn dist2_squared>(&self, other: I) -> $field { + let Pair(u, v) = other.decompose(); + self.0.dist2_squared(u) + self.1.dist2_squared(v) + } + } + }; } +impl_euclidean!(f32); +impl_euclidean!(f64); + impl AXPY> for Pair where U: Space,