Thu, 01 May 2025 01:55:57 -0500
restrict
| src/direct_product.rs | file | annotate | diff | comparison | revisions |
--- a/src/direct_product.rs Thu May 01 01:31:25 2025 -0500 +++ b/src/direct_product.rs Thu May 01 01:55:57 2025 -0500 @@ -224,6 +224,9 @@ }; } +impl_binary!(Add, add); +impl_binary!(Sub, sub); + macro_rules! impl_binary_mut { ($trait:ident, $fn:ident) => { impl<'a, A, B, C, D> $trait<Pair<C, D>> for Pair<A, B> @@ -252,11 +255,28 @@ }; } -impl_binary!(Add, add); -impl_binary!(Sub, sub); impl_binary_mut!(AddAssign, add_assign); impl_binary_mut!(SubAssign, sub_assign); +macro_rules! impl_scalar_mut { + ($trait:ident, $fn:ident) => { + impl<'a, A, B, F> $trait<F> for Pair<A, B> + where + A: $trait<F>, + B: $trait<F>, + { + fn $fn(&mut self, t: F) { + let Pair(ref mut a, ref mut b) = self; + a.$fn(t); + b.$fn(t); + } + } + }; +} + +impl_scalar_mut!(MulAssign, mul_assign); +impl_scalar_mut!(DivAssign, div_assign); + #[macro_export] macro_rules! impl_pair_vectorspace_ops { (($a:ty, $b:ty), $field:ty) => { @@ -270,14 +290,6 @@ // $( // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul); // )* - impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign); - impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign); - }; - (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => { - impl_binop!(($a, $b), $trait, $fn, ref, ref); - impl_binop!(($a, $b), $trait, $fn, ref, noref); - impl_binop!(($a, $b), $trait, $fn, noref, ref); - impl_binop!(($a, $b), $trait, $fn, noref, noref); }; (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => { impl_scalarop!(($a, $b), $field, $trait, $fn, ref); @@ -305,16 +317,6 @@ // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, MulAssign, mul_assign); // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, DivAssign, div_assign); }; - // (@binary, $trait : ident, $fn : ident) => { - // impl_binop_gen!(($a, $b), $trait, $fn, ref, ref); - // impl_binop_gen!(($a, $b), $trait, $fn, ref, noref); - // impl_binop_gen!(($a, $b), $trait, $fn, noref, ref); - // impl_binop_gen!(($a, $b), $trait, $fn, noref, noref); - // }; - // (@assign, $trait : ident, $fn :ident) => { - // impl_assignop_gen!(($a, $b), $trait, $fn, ref); - // impl_assignop_gen!(($a, $b), $trait, $fn, noref); - // }; (@scalar, $field : ty, $trait : ident, $fn :ident) => { impl_scalarop_gen!($field, $trait, $fn, ref); impl_scalarop_gen!($field, $trait, $fn, noref); @@ -331,61 +333,48 @@ impl_pair_vectorspace_ops_gen!(f32); impl_pair_vectorspace_ops_gen!(f64); -impl_pair_vectorspace_ops!((f32, f32), f32); -impl_pair_vectorspace_ops!((f64, f64), f64); - -type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; +//impl_pair_vectorspace_ops!((f32, f32), f32); +//impl_pair_vectorspace_ops!((f64, f64), f64); /// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output` -/// to avoid compiler overflows that the requirement -/// ``` -/// Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output> : Euclidean<F> -/// ``` -/// would generate. -macro_rules! impl_euclidean { - ($field:ty) => { - impl<A, B> Euclidean<$field> for Pair<A, B> - 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<Self, Output = PairOutput<$field, A, B>> - + Sub<Self, Output = PairOutput<$field, A, B>> - + for<'b> Add<&'b Self, Output = PairOutput<$field, A, B>> - + for<'b> Sub<&'b Self, Output = PairOutput<$field, A, B>> - + AddAssign<Self> - + for<'b> AddAssign<&'b Self> - + SubAssign<Self> - + for<'b> SubAssign<&'b Self>, //+ Neg<Output = PairOutput<$field, A, B>>, - { - type Output = PairOutput<$field, A, B>; +impl<A, B, F: Float> Euclidean<F> for Pair<A, B> +where + A: Euclidean<F>, + B: Euclidean<F>, + //Pair<A, B>: Euclidean<F>, + Self: Sized + + Mul<F, Output = Pair<A, B>> + + MulAssign<F> + + Div<F, Output = Pair<A, B>> + + DivAssign<F> + + Add<Self, Output = Pair<A, B>> + + Sub<Self, Output = Pair<A, B>> + + for<'b> Add<&'b Self, Output = Pair<A, B>> + + for<'b> Sub<&'b Self, Output = Pair<A, B>> + + AddAssign<Self> + + for<'b> AddAssign<&'b Self> + + SubAssign<Self> + + for<'b> SubAssign<&'b Self> + + Neg<Output = Pair<A, B>>, +{ + type Output = Pair<A, B>; - fn dot<I: Instance<Self>>(&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 dot<I: Instance<Self>>(&self, other: I) -> F { + let Pair(u, v) = other.decompose(); + self.0.dot(u) + self.1.dot(v) + } - fn dist2_squared<I: Instance<Self>>(&self, other: I) -> $field { - let Pair(u, v) = other.decompose(); - self.0.dist2_squared(u) + self.1.dist2_squared(v) - } - } - }; + fn norm2_squared(&self) -> F { + self.0.norm2_squared() + self.1.norm2_squared() + } + + fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { + let Pair(u, v) = other.decompose(); + self.0.dist2_squared(u) + self.1.dist2_squared(v) + } } -impl_euclidean!(f32); -impl_euclidean!(f64); - impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> where U: Space,