diff -r 89371dc4d637 -r 2b13f8a0c8ba src/direct_product.rs --- a/src/direct_product.rs Mon May 12 19:30:41 2025 -0500 +++ b/src/direct_product.rs Mon May 12 20:40:14 2025 -0500 @@ -285,8 +285,7 @@ + Neg::Owned>, { fn dot>(&self, other: I) -> F { - let Pair(u, v) = other.decompose(); - self.0.dot(u) + self.1.dot(v) + other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) } fn norm2_squared(&self) -> F { @@ -294,8 +293,7 @@ } fn dist2_squared>(&self, other: I) -> F { - let Pair(u, v) = other.decompose(); - self.0.dist2_squared(u) + self.1.dist2_squared(v) + other.eval_decompose(|Pair(u, v)| self.0.dist2_squared(u) + self.1.dist2_squared(v)) } } @@ -316,21 +314,24 @@ type Owned = Pair; fn axpy>>(&mut self, α: F, x: I, β: F) { - let Pair(u, v) = x.decompose(); - self.0.axpy(α, u, β); - self.1.axpy(α, v, β); + x.eval_decompose(|Pair(u, v)| { + self.0.axpy(α, u, β); + self.1.axpy(α, v, β); + }) } fn copy_from>>(&mut self, x: I) { - let Pair(u, v) = x.decompose(); - self.0.copy_from(u); - self.1.copy_from(v); + x.eval_decompose(|Pair(u, v)| { + self.0.copy_from(u); + self.1.copy_from(v); + }) } fn scale_from>>(&mut self, α: F, x: I) { - let Pair(u, v) = x.decompose(); - self.0.scale_from(α, u); - self.1.scale_from(α, v); + x.eval_decompose(|Pair(u, v)| { + self.0.scale_from(α, u); + self.1.scale_from(α, v); + }) } /// Return a similar zero as `self`. @@ -384,22 +385,28 @@ U: Instance, V: Instance, { - #[inline] - fn decompose<'b>( + fn eval_decompose<'b, R>( self, - ) -> as Decomposition>>::Decomposition<'b> + f: impl FnOnce(Pair, Q::Decomposition<'b>>) -> R, + ) -> R where + Pair: 'b, Self: 'b, - Pair: 'b, { - Pair(self.0.decompose(), self.1.decompose()) + self.0 + .eval_decompose(|a| self.1.eval_decompose(|b| f(Pair(a, b)))) } - #[inline] - fn ref_instance( - &self, - ) -> as Decomposition>>::Reference<'_> { - Pair(self.0.ref_instance(), self.1.ref_instance()) + fn eval_ref_decompose<'b, R>( + &'b self, + f: impl FnOnce(Pair, Q::Reference<'b>>) -> R, + ) -> R + where + Pair: 'b, + Self: 'b, + { + self.0 + .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) } #[inline] @@ -427,25 +434,30 @@ &'a U: Instance, &'a V: Instance, { - #[inline] - fn decompose<'b>( + fn eval_decompose<'b, R>( self, - ) -> as Decomposition>>::Decomposition<'b> + f: impl FnOnce(Pair, Q::Decomposition<'b>>) -> R, + ) -> R where + Pair: 'b, Self: 'b, - Pair: 'b, { - Pair( - D::lift(self.0.ref_instance()), - Q::lift(self.1.ref_instance()), - ) + self.0.eval_ref_decompose(|a| { + self.1 + .eval_ref_decompose(|b| f(Pair(D::lift(a), Q::lift(b)))) + }) } - #[inline] - fn ref_instance( - &self, - ) -> as Decomposition>>::Reference<'_> { - Pair(self.0.ref_instance(), self.1.ref_instance()) + fn eval_ref_decompose<'b, R>( + &'b self, + f: impl FnOnce(Pair, Q::Reference<'b>>) -> R, + ) -> R + where + Pair: 'b, + Self: 'b, + { + self.0 + .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) } #[inline]