src/direct_product.rs

branch
dev
changeset 133
2b13f8a0c8ba
parent 132
89371dc4d637
child 134
d65377920b00
child 136
22fd33834ab7
child 138
593912dc3293
--- 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<Output = <Self as AXPY>::Owned>,
 {
     fn dot<I: Instance<Self>>(&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<I: Instance<Self>>(&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<A::Owned, B::Owned>;
 
     fn axpy<I: Instance<Pair<U, V>>>(&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<I: Instance<Pair<U, V>>>(&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<I: Instance<Pair<U, V>>>(&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<A, D>,
     V: Instance<B, Q>,
 {
-    #[inline]
-    fn decompose<'b>(
+    fn eval_decompose<'b, R>(
         self,
-    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
+        f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
+    ) -> R
     where
+        Pair<A, B>: 'b,
         Self: 'b,
-        Pair<A, B>: '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,
-    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> {
-        Pair(self.0.ref_instance(), self.1.ref_instance())
+    fn eval_ref_decompose<'b, R>(
+        &'b self,
+        f: impl FnOnce(Pair<D::Reference<'b>, Q::Reference<'b>>) -> R,
+    ) -> R
+    where
+        Pair<A, B>: '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, D>,
     &'a V: Instance<B, Q>,
 {
-    #[inline]
-    fn decompose<'b>(
+    fn eval_decompose<'b, R>(
         self,
-    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
+        f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
+    ) -> R
     where
+        Pair<A, B>: 'b,
         Self: 'b,
-        Pair<A, B>: '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,
-    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> {
-        Pair(self.0.ref_instance(), self.1.ref_instance())
+    fn eval_ref_decompose<'b, R>(
+        &'b self,
+        f: impl FnOnce(Pair<D::Reference<'b>, Q::Reference<'b>>) -> R,
+    ) -> R
+    where
+        Pair<A, B>: 'b,
+        Self: 'b,
+    {
+        self.0
+            .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b))))
     }
 
     #[inline]

mercurial