diff -r 26ef556870fd -r 2f1798c65fd6 src/euclidean/wrap.rs --- a/src/euclidean/wrap.rs Mon Sep 01 00:04:16 2025 -0500 +++ b/src/euclidean/wrap.rs Mon Sep 01 00:04:22 2025 -0500 @@ -2,185 +2,193 @@ Wrappers for implemention [`Euclidean`] operations. */ -pub trait Wrapped { - type Unwrapped; - type UnwrappedMut; - type UnwrappedOutput; +use crate::euclidean::Euclidean; +use crate::instance::Space; +use crate::types::Float; + +pub trait Wrapped: Space { + type WrappedField: Float; + type Unwrapped: Euclidean; + type UnwrappedMut: Euclidean; + type UnwrappedOutput: Euclidean; + type WrappedOutput; fn get_view(&self) -> Self::Unwrapped; fn get_view_mut(&mut self) -> Self::UnwrappedMut; - fn wrap(output: Self::UnwrappedOutput) -> Self; + fn wrap(output: Self::UnwrappedOutput) -> Self::WrappedOutput; } #[macro_export] macro_rules! wrap { - (impl_unary<$($qual:tt)*> $type:ty, $trait:path, $fn:ident) => { - impl<$($qual)*> $trait for $type { - type Output = Self::WrappedOutput; + // Rust macros are totally fucked up. $trait:path does not work, have to + // manually code paths through $($trait:ident)::+. + (impl_unary $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+ for $type { + type Output = ::WrappedOutput; fn $fn(self) -> Self::Output { Self::wrap(self.get_view().$fn()) } } }; - (impl_binary<$($qual:tt)*> $type:ty, $trait:path, $fn:ident) => { - impl<$($qual)*> $trait<$type> for $type { - type Output = Self::WrappedOutput; - fn $fn(self, other: $type) -> Self::Output { - Self::wrap(self.get_view().$fn(other.get_view())) - } - } - - impl<'a, $($qual)*> $trait<$type> for &'a $type { - type Output = Self::WrappedOutput; + (impl_binary $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+<$type> for $type { + type Output = ::WrappedOutput; fn $fn(self, other: $type) -> Self::Output { Self::wrap(self.get_view().$fn(other.get_view())) } } - impl<'a, 'b, $($qual)*> $trait<&'b $type> for &'a $type { - type Output = Self::WrappedOutput; + impl<'a, $($qual)*> $($trait)::+<$type> for &'a $type { + type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; fn $fn(self, other: $type) -> Self::Output { - Self::wrap(self.get_view().$fn(other.get_view())) + <$type>::wrap(self.get_view().$fn(other.get_view())) } } - impl<'b, $($qual)*> $trait<&'b $type> for $type { - type Output = Self::WrappedOutput; - fn $fn(self, other: $type) -> Self::Output { + impl<'a, 'b, $($qual)*> $($trait)::+<&'b $type> for &'a $type { + type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; + fn $fn(self, other: &'b $type) -> Self::Output { + <$type>::wrap(self.get_view().$fn(other.get_view())) + } + } + + impl<'b, $($qual)*> $($trait)::+<&'b $type> for $type { + type Output = ::WrappedOutput; + fn $fn(self, other: &'b $type) -> Self::Output { Self::wrap(self.get_view().$fn(other.get_view())) } } }; - (impl_scalar<$($qual:tt)*> $type:ty, $trait:path, $fn:ident) => { - impl<$($qual)*, F: Num> $trait for $type, - where - $type::Unwrapped: $trait, + (impl_scalar $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+<$F> for $type + // where + // $type: $crate::euclidean::wrap::Wrapped, + // //$type::Unwrapped: $($trait)::+, { - type Output = Self::WrappedOutput; - fn $fn(self, t: F) -> Self::Output { + type Output = ::WrappedOutput; + fn $fn(self, t: $F) -> Self::Output { Self::wrap(self.get_view().$fn(t)) } } - impl<'a, $($qual)*, F: Num> $trait for &'a $type, - where - $type::Unwrapped: $trait, + impl<'a, $($qual)*> $($trait)::+<$F> for &'a $type + // where + // $type: $crate::euclidean::wrap::Wrapped, + // //$type::Unwrapped: $($trait)::+, { - type Output = Self::WrappedOutput; - fn $fn(self, t: F) -> Self::Output { - Self::wrap(self.get_view().$fn(t)) + type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; + fn $fn(self, t: $F) -> Self::Output { + <$type>::wrap(self.get_view().$fn(t)) } } }; - (impl_scalar_lhs<$($qual:tt)*> $type:ty, $trait:path, $fn:ident, $F:ty) => { - impl<$($qual)*> $trait<$type> for $F - where - $F: $type::Unwrapped, + (impl_scalar_lhs $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+<$type> for $F + // where + // $type: $crate::euclidean::wrap::Wrapped, + // // where + // // $F: $($trait)::+<$type::Unwrapped>, { - type Output = Self::WrappedOutput; + type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; fn $fn(self, rhs: $type) -> Self::Output { - Self::wrap(self.$fn(rhs.get_view())) + <$type>::wrap(self.$fn(rhs.get_view())) } } }; - (impl_binary_mut<$($qual:tt)*> $type:ty, $trait:path, $fn:ident) => { - impl<$($qual)*> $trait<$type> for $type { + (impl_binary_mut $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+<$type> for $type { fn $fn(&mut self, rhs: $type) { self.get_view_mut().$fn(rhs.get_view()) } } - impl<'b, $($qual)*> $trait<&'b $type> for $type { - fn $fn(&mut self, rhs: $type) { + impl<'b, $($qual)*> $($trait)::+<&'b $type> for $type { + fn $fn(&mut self, rhs: &'b $type) { self.get_view_mut().$fn(rhs.get_view()) } } }; - (impl_scalar_mut<$($qual:tt)*> $type:ty, $trait:path, $fn:ident) => { - impl<$($qual)*> $trait for $type - where - $type::UnwrappedMut: $trait, + (impl_scalar_mut $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { + impl<$($qual)*> $($trait)::+<$F> for $type + // where + // $type: $crate::euclidean::wrap::Wrapped, + // // where + // // $type::UnwrappedMut: $($trait)::+<$($trait)::+>, { - fn $fn(&mut self, t: F) { - self.unwrap_mut().$fn(t) + fn $fn(&mut self, t: $F) { + self.get_view_mut().$fn(t) } } }; - ($type:ty) => { - $crate::wrap!(imp<> do $type); - }; - (imp<$($qual:tt)*> $type:ty) => { - $crate::wrap!(impl_unary<$($qual)*> $type, std::ops::Neg, neg); - $crate::wrap!(impl_binary<$($qual)*> $type, std::ops::Add, add); - $crate::wrap!(impl_binary<$($qual)*> $type, std::ops::Sub, sub); - $crate::wrap!(impl_scalar<$($qual)*> $type, std::ops::Mul, mul); - $crate::wrap!(impl_scalar<$($qual)*> $type, std::ops::Div, div); - $crate::wrap!(impl_scalar_lhs<$($qual)*> $type, std::ops::Mul, mul, f32); - $crate::wrap!(impl_scalar_lhs<$($qual)*> $type, std::ops::Mul, mul, f64); - $crate::wrap!(impl_scalar_lhs<$($qual)*> $type, std::ops::Div, div, f32); - $crate::wrap!(impl_scalar_lhs<$($qual)*> $type, std::ops::Div, div, f64); - $crate::wrap!(impl_binary_mut<$($qual)*> $type, std::ops::AddAssign, add_assign); - $crate::wrap!(impl_binary_mut<$($qual)*> $type, std::ops::SubAssign, sub_assign); - $crate::wrap!(impl_scalar_mut<$($qual)*> $type, std::ops::MulAssign, mul_assign); - $crate::wrap!(impl_scalar_mut<$($qual)*> $type, std::ops::DivAssign, div_assign); + // ($type:ty) => { + // $crate::wrap!(imp<> do $type); + // }; + ($F:ty; $type:ty where $($qual:tt)*) => { + $crate::wrap!(impl_unary $type, std::ops::Neg, neg where $($qual)*); + $crate::wrap!(impl_binary $type, std::ops::Add, add where $($qual)*); + $crate::wrap!(impl_binary $type, std::ops::Sub, sub where $($qual)*); + $crate::wrap!(impl_scalar $F, $type, std::ops::Mul, mul where $($qual)*); + $crate::wrap!(impl_scalar $F, $type, std::ops::Div, div where $($qual)*); + $crate::wrap!(impl_scalar_lhs $F, $type, std::ops::Mul, mul where $($qual)*); + $crate::wrap!(impl_binary_mut $type, std::ops::AddAssign, add_assign where $($qual)*); + $crate::wrap!(impl_binary_mut $type, std::ops::SubAssign, sub_assign where $($qual)*); + $crate::wrap!(impl_scalar_mut $F, $type, std::ops::MulAssign, mul_assign where $($qual)*); + $crate::wrap!(impl_scalar_mut $F, $type, std::ops::DivAssign, div_assign where $($qual)*); - /// We only support 'closed' `Euclidean` `Pair`s, as more general ones cause - /// compiler overflows. - impl<$($qual)* F: $crate::types::Float> $crate::euclidean::Euclidean for $type - where - //Pair: Euclidean, - Self: $crate::euclidean::wrap::Wrapped - + Sized - + std::ops::Mul::Owned> - + std::ops::MulAssign - + std::ops::Div::Owned> - + std::ops::DivAssign - + std::ops::Add::Owned> - + std::ops::Sub::Owned> - + for<'b> std::ops::Add<&'b Self, Output = ::Owned> - + for<'b> std::ops::Sub<&'b Self, Output = ::Owned> - + std::ops::AddAssign - + for<'b> std::ops::AddAssign<&'b Self> - + std::ops::SubAssign - + for<'b> std::ops::SubAssign<&'b Self> - + std::ops::Neg::Owned>, + impl<$($qual)*> $crate::euclidean::Euclidean<$F> for $type + // where + // Self: $crate::euclidean::wrap::Wrapped + // + Sized + // + std::ops::Mul::Owned> + // + std::ops::MulAssign + // + std::ops::Div::Owned> + // + std::ops::DivAssign + // + std::ops::Add::Owned> + // + std::ops::Sub::Owned> + // + for<'b> std::ops::Add<&'b Self, Output = ::Owned> + // + for<'b> std::ops::Sub<&'b Self, Output = ::Owned> + // + std::ops::AddAssign + // + for<'b> std::ops::AddAssign<&'b Self> + // + std::ops::SubAssign + // + for<'b> std::ops::SubAssign<&'b Self> + // + std::ops::Neg::Owned>, { - fn dot>(&self, other: I) -> F { - other.eval_decompose(|x| self.get_view().dot(x.get_view())) + fn dot>(&self, other: I) -> $F { + other.eval_decompose(|x| self.get_view().dot(&x.get_view())) } - fn norm2_squared(&self) -> F { + fn norm2_squared(&self) -> $F { self.get_view().norm2_squared() } - fn dist2_squared>(&self, other: I) -> F { + fn dist2_squared>(&self, other: I) -> $F { other.eval_decompose(|x| self.get_view().dist2_squared(x.get_view())) } } - impl<$($qual)* F : $crate::types::Float> $crate::linops::AXPY for $type - where - Self : $crate::euclidean::wrap::Wrapped, - Self::Unwrapped : $crate::linops::AXPY, - Self: std::ops::MulAssign + std::ops::DivAssign, - Self::Unwrapped: std::ops::MulAssign + std::ops::DivAssign, + impl<$($qual)*> $crate::linops::AXPY for $type + // where + // Self : $crate::euclidean::wrap::Wrapped, + // Self::Unwrapped : $crate::linops::AXPY, + // Self: std::ops::MulAssign + std::ops::DivAssign, + // Self::Unwrapped: std::ops::MulAssign + std::ops::DivAssign, { - type Field = F; + type Field = $F; type Owned = Self; - fn axpy>(&mut self, α: F, x: I, β: F) { + fn axpy>(&mut self, α: $F, x: I, β: $F) { x.eval_decompose(|v| { - self.get_mut_view().axpy(α, v.get_view(), β) + self.get_view_mut().axpy(α, v.get_view(), β) }) } fn copy_from>(&mut self, x: I) { - x.eval_decompose(|Pair(u, v)| { - self.get_mut_view().copy_from(v.get_view()) + x.eval_decompose(|v| { + self.get_view_mut().copy_from(v.get_view()) }) } - fn scale_from>(&mut self, α: F, x: I) { + fn scale_from>(&mut self, α: $F, x: I) { x.eval_decompose(|v| { self.get_mut_view().scale_from(α, v.get_view()) }) @@ -197,9 +205,8 @@ } } - impl<$($qual)*> $crate::instance::Space for $type - where Self : $crate::euclidean::wrap::Wrapped { - type Decomp = Self::Unwrapped::Decomp; + impl<$($qual)*> $crate::instance::Space for $type { + type Decomp = <::Unwrapped as $crate::instance::Space>::Decomp; } }; }