--- a/src/direct_product.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/direct_product.rs Mon Sep 01 20:55:34 2025 -0500 @@ -6,9 +6,7 @@ */ use crate::euclidean::Euclidean; -use crate::instance::{ - ClosedSpace, Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable, -}; +use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable}; use crate::linops::{VectorSpace, AXPY}; use crate::loc::Loc; use crate::mapping::Space; @@ -289,22 +287,24 @@ where A: Euclidean<F>, B: Euclidean<F>, - //Pair<A, B>: Euclidean<F>, - Self: Sized - + Mul<F, Output = <Self as VectorSpace>::Owned> - + MulAssign<F> - + Div<F, Output = <Self as VectorSpace>::Owned> - + DivAssign<F> - + Add<Self, Output = <Self as VectorSpace>::Owned> - + Sub<Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> - + AddAssign<Self> - + for<'b> AddAssign<&'b Self> - + SubAssign<Self> - + for<'b> SubAssign<&'b Self> - + Neg<Output = <Self as VectorSpace>::Owned>, + // //Pair<A, B>: Euclidean<F>, + // Self: Sized + // + Mul<F, Output = Self::OwnedEuclidean> + // + MulAssign<F> + // + Div<F, Output = Self::OwnedEuclidean> + // + DivAssign<F> + // + Add<Self, Output = Self::OwnedEuclidean> + // + Sub<Self, Output = Self::OwnedEuclidean> + // + for<'b> Add<&'b Self, Output = Self::OwnedEuclidean> + // + for<'b> Sub<&'b Self, Output = Self::OwnedEuclidean> + // + AddAssign<Self> + // + for<'b> AddAssign<&'b Self> + // + SubAssign<Self> + // + for<'b> SubAssign<&'b Self> + // + Neg<Output = Self::OwnedEuclidean>, { + type OwnedEuclidean = Pair<A::OwnedEuclidean, B::OwnedEuclidean>; + fn dot<I: Instance<Self>>(&self, other: I) -> F { other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) } @@ -318,16 +318,14 @@ } } -impl<F, A, B, O, P> VectorSpace for Pair<A, B> +impl<F, A, B> VectorSpace for Pair<A, B> where - A: VectorSpace<Field = F, Owned = O, OwnedVariant = O>, - B: VectorSpace<Field = F, Owned = P, OwnedVariant = P>, - O: ClosedSpace + AXPY<A, Field = F, Owned = O, OwnedVariant = O>, - P: ClosedSpace + AXPY<B, Field = F, Owned = P, OwnedVariant = P>, + A: VectorSpace<Field = F>, + B: VectorSpace<Field = F>, F: Num, { type Field = F; - type Owned = Pair<O, P>; + type Owned = Pair<A::Owned, B::Owned>; /// Return a similar zero as `self`. fn similar_origin(&self) -> Self::Owned { @@ -347,8 +345,8 @@ A: AXPY<U, Field = F>, B: AXPY<V, Field = F>, F: Num, - Self: MulAssign<F> + DivAssign<F>, - Pair<A, B>: MulAssign<F> + DivAssign<F>, + // Self: MulAssign<F> + DivAssign<F>, + // Pair<A, B>: MulAssign<F> + DivAssign<F>, { fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { x.eval_decompose(|Pair(u, v)| { @@ -383,6 +381,7 @@ pub struct PairDecomposition<D, Q>(D, Q); impl<A: Space, B: Space> Space for Pair<A, B> { + type OwnedSpace = Pair<A::OwnedSpace, B::OwnedSpace>; type Decomp = PairDecomposition<A::Decomp, B::Decomp>; }