decompose dev

Wed, 03 Sep 2025 20:19:41 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 03 Sep 2025 20:19:41 -0500
branch
dev
changeset 171
fa8df5a14486
parent 170
221728aeeb7e
child 172
73608862ef54

decompose

src/bisection_tree/btfn.rs file | annotate | diff | comparison | revisions
src/direct_product.rs file | annotate | diff | comparison | revisions
src/fe_model/p2_local_model.rs file | annotate | diff | comparison | revisions
src/instance.rs file | annotate | diff | comparison | revisions
src/linops.rs file | annotate | diff | comparison | revisions
src/loc.rs file | annotate | diff | comparison | revisions
src/mapping.rs file | annotate | diff | comparison | revisions
src/nalgebra_support.rs file | annotate | diff | comparison | revisions
src/operator_arithmetic.rs file | annotate | diff | comparison | revisions
src/sets.rs file | annotate | diff | comparison | revisions
--- a/src/bisection_tree/btfn.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/bisection_tree/btfn.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -435,7 +435,7 @@
     type Codomain = V;
 
     fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain {
-        let xc = x.cow();
+        let xc = x.decompose();
         self.bt
             .iter_at(&*xc)
             .map(|&d| self.generator.support_for(d).apply(&*xc))
@@ -454,7 +454,7 @@
     type Derivative = V;
 
     fn differential_impl<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Derivative {
-        let xc = x.cow();
+        let xc = x.decompose();
         self.bt
             .iter_at(&*xc)
             .map(|&d| self.generator.support_for(d).differential(&*xc))
--- a/src/direct_product.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/direct_product.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -433,29 +433,12 @@
     V: Instance<B, Q>,
 {
     #[inline]
-    fn eval_decompose<'b, R>(
-        self,
-        f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
-    ) -> R
+    fn eval_ref<'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_decompose(|a| self.1.eval_decompose(|b| f(Pair(a, b))))
-    }
-
-    #[inline]
-    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))))
+        self.0.eval_ref(|a| self.1.eval_ref(|b| f(Pair(a, b))))
     }
 
     #[inline]
@@ -470,6 +453,14 @@
     fn own(self) -> Pair<A::Principal, B::Principal> {
         Pair(self.0.own(), self.1.own())
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> Pair<D::Decomposition<'b>, Q::Decomposition<'b>>
+    where
+        Self: 'b,
+    {
+        Pair(self.0.decompose(), self.1.decompose())
+    }
 }
 
 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V>
@@ -483,30 +474,12 @@
     &'a U: Instance<A, D>,
     &'a V: Instance<B, Q>,
 {
-    fn eval_decompose<'b, R>(
-        self,
-        f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
-    ) -> R
+    fn eval_ref<'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(D::lift(a), Q::lift(b))))
-        })
-    }
-
-    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))))
+        self.0.eval_ref(|a| self.1.eval_ref(|b| f(Pair(a, b))))
     }
 
     #[inline]
@@ -522,6 +495,15 @@
         let Pair(ref u, ref v) = self;
         Pair(u.own(), v.own())
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> Pair<D::Decomposition<'b>, Q::Decomposition<'b>>
+    where
+        Self: 'b,
+    {
+        let Pair(u, v) = self;
+        Pair(u.decompose(), v.decompose())
+    }
 }
 
 impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D, Q>
--- a/src/fe_model/p2_local_model.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/fe_model/p2_local_model.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -32,7 +32,7 @@
 impl<'a, F: Float> Set<Loc<1, F>> for RealInterval<F> {
     #[inline]
     fn contains<I: Instance<Loc<1, F>>>(&self, z: I) -> bool {
-        z.eval_ref_decompose(|&Loc([x])| {
+        z.eval_ref(|&Loc([x])| {
             let &[Loc([x0]), Loc([x1])] = &self.0;
             (x0 < x && x < x1) || (x1 < x && x < x0)
         })
@@ -318,12 +318,7 @@
         x0: &Loc<2, F>,
         x1: &Loc<2, F>, /*, v0 : F, v1 : F*/
     ) -> (Loc<2, F>, F) {
-        let &P2LocalModel {
-            a0,
-            a1: Loc([a1, a2]),
-            a2: Loc([a11, a12, a22]),
-            ..
-        } = self;
+        let &P2LocalModel { a0, a1: Loc([a1, a2]), a2: Loc([a11, a12, a22]), .. } = self;
         let &Loc([x00, x01]) = x0;
         let d @ Loc([d0, d1]) = x1 - x0;
         let b0 = a0 + a1 * x00 + a2 * x01 + a11 * x00 * x00 + a12 * x00 * x01 + a22 * x01 * x01;
--- a/src/instance.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/instance.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -328,14 +328,18 @@
 {
     /// Decomposes self according to `decomposer`, and evaluate `f` on the result.
     /// Consumes self.
+    #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R
     where
         X: 'b,
-        Self: 'b;
+        Self: 'b,
+    {
+        f(self.decompose())
+    }
 
     /// Does a light decomposition of self `decomposer`, and evaluates `f` on the result.
     /// Does not consume self.
-    fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R
+    fn eval_ref<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R
     where
         X: 'b,
         Self: 'b;
@@ -345,7 +349,7 @@
     fn either<'b, R>(
         self,
         f: impl FnOnce(D::Decomposition<'b>) -> R,
-        g: impl FnOnce(D::Reference<'b>) -> R,
+        _g: impl FnOnce(D::Reference<'b>) -> R,
     ) -> R
     where
         X: 'b,
@@ -357,6 +361,10 @@
     /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary.
     fn own(self) -> X::Principal;
 
+    fn decompose<'b>(self) -> D::Decomposition<'b>
+    where
+        Self: 'b;
+
     /// Returns an owned instance or reference to `X`, converting non-true instances when necessary.
     ///
     /// Default implementation uses [`Self::own`]. Consumes the input.
@@ -387,16 +395,7 @@
     }
 
     #[inline]
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
-    where
-        X: 'b,
-        Self: 'b,
-    {
-        f(MyCow::Owned(self))
-    }
-
-    #[inline]
-    fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
+    fn eval_ref<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -416,6 +415,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> MyCow<'b, X>
+    where
+        Self: 'b,
+    {
+        MyCow::Owned(self)
+    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a X {
@@ -428,16 +435,7 @@
     }
 
     #[inline]
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
-    where
-        X: 'b,
-        Self: 'b,
-    {
-        f(MyCow::Borrowed(self))
-    }
-
-    #[inline]
-    fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
+    fn eval_ref<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -457,6 +455,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> MyCow<'b, X>
+    where
+        Self: 'b,
+    {
+        MyCow::Borrowed(self)
+    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a mut X {
@@ -469,16 +475,7 @@
     }
 
     #[inline]
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
-    where
-        X: 'b,
-        Self: 'b,
-    {
-        f(EitherDecomp::Borrowed(self))
-    }
-
-    #[inline]
-    fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
+    fn eval_ref<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -498,6 +495,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> MyCow<'b, X>
+    where
+        Self: 'b,
+    {
+        MyCow::Borrowed(self)
+    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for MyCow<'a, X> {
@@ -510,16 +515,7 @@
     }
 
     #[inline]
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
-    where
-        X: 'b,
-        Self: 'b,
-    {
-        f(self)
-    }
-
-    #[inline]
-    fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
+    fn eval_ref<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -542,6 +538,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> MyCow<'b, X>
+    where
+        Self: 'b,
+    {
+        self
+    }
 }
 
 /// Marker type for mutable decompositions to be used with [`InstanceMut`].
--- a/src/linops.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/linops.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -616,7 +616,7 @@
     type Codomain = Pair<S::Codomain, T::Codomain>;
 
     fn apply<I: Instance<A>>(&self, a: I) -> Self::Codomain {
-        Pair(a.eval_ref_decompose(|r| self.0.apply(r)), self.1.apply(a))
+        Pair(a.eval_ref(|r| self.0.apply(r)), self.1.apply(a))
     }
 }
 
@@ -637,18 +637,18 @@
     Self: Linear<X, Codomain = Pair<A, B>>,
 {
     fn gemv<I: Instance<X>>(&self, y: &mut Pair<A, B>, α: F, x: I, β: F) {
-        x.eval_ref_decompose(|r| self.0.gemv(&mut y.0, α, r, β));
+        x.eval_ref(|r| self.0.gemv(&mut y.0, α, r, β));
         self.1.gemv(&mut y.1, α, x, β);
     }
 
     fn apply_mut<I: Instance<X>>(&self, y: &mut Pair<A, B>, x: I) {
-        x.eval_ref_decompose(|r| self.0.apply_mut(&mut y.0, r));
+        x.eval_ref(|r| self.0.apply_mut(&mut y.0, r));
         self.1.apply_mut(&mut y.1, x);
     }
 
     /// Computes `y += Ax`, where `A` is `Self`
     fn apply_add<I: Instance<X>>(&self, y: &mut Pair<A, B>, x: I) {
-        x.eval_ref_decompose(|r| self.0.apply_add(&mut y.0, r));
+        x.eval_ref(|r| self.0.apply_add(&mut y.0, r));
         self.1.apply_add(&mut y.1, x);
     }
 }
--- a/src/loc.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/loc.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -442,7 +442,7 @@
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
     fn dot<I: Instance<Self>>(&self, other: I) -> F {
-        other.eval_ref_decompose(|r| {
+        other.eval_ref(|r| {
             self.0
                 .iter()
                 .zip(r.0.iter())
@@ -458,7 +458,7 @@
     }
 
     fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
-        other.eval_ref_decompose(|r| {
+        other.eval_ref(|r| {
             self.iter().zip(r.iter()).fold(F::ZERO, |m, (&v, &w)| {
                 let d = v - w;
                 m + d * d
@@ -480,9 +480,7 @@
     fn dist2<I: Instance<Self>>(&self, other: I) -> F {
         // Optimisation for N==1 that avoids squaring and square rooting.
         if N == 1 {
-            other.eval_ref_decompose(|r| {
-                unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs()
-            })
+            other.eval_ref(|r| unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs())
         } else {
             self.dist2_squared(other).sqrt()
         }
@@ -643,7 +641,7 @@
 impl<F: Float, const N: usize> Dist<L1, F> for Loc<N, F> {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F {
-        other.eval_ref_decompose(|r| {
+        other.eval_ref(|r| {
             self.iter()
                 .zip(r.iter())
                 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs())
@@ -679,7 +677,7 @@
 impl<F: Float, const N: usize> Dist<Linfinity, F> for Loc<N, F> {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F {
-        other.eval_ref_decompose(|r| {
+        other.eval_ref(|r| {
             self.iter()
                 .zip(r.iter())
                 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs()))
@@ -761,7 +759,7 @@
 impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> {
     #[inline]
     fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) {
-        x.eval(|x̃| {
+        x.eval_ref(|x̃| {
             if β == F::ZERO {
                 map2_mut(self, x̃, |yi, xi| *yi = α * (*xi))
             } else {
@@ -772,7 +770,7 @@
 
     #[inline]
     fn copy_from<I: Instance<Loc<N, F>>>(&mut self, x: I) {
-        x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi))
+        x.eval_ref(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi))
     }
 
     #[inline]
--- a/src/mapping.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/mapping.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -283,7 +283,7 @@
         // }
 
         self.outer
-            .differential_impl(x.eval_ref_decompose(|r| self.inner.apply(r)))
+            .differential_impl(x.eval_ref(|r| self.inner.apply(r)))
             * self.inner.differential_impl(x)
     }
 }
--- a/src/nalgebra_support.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/nalgebra_support.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -159,15 +159,7 @@
     }
 
     #[inline]
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R
-    where
-        Self: 'b,
-    {
-        f(self.into_owned())
-    }
-
-    #[inline]
-    fn eval_ref_decompose<'b, R>(
+    fn eval_ref<'b, R>(
         &'b self,
         f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R,
     ) -> R
@@ -190,6 +182,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> OMatrix<E, M, K>
+    where
+        Self: 'b,
+    {
+        self.into_owned()
+    }
 }
 
 impl<'a, S1, S2, M, K, E> Instance<Matrix<E, M, K, S1>, MatrixDecomposition>
@@ -215,14 +215,7 @@
         g(self.as_view())
     }
 
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R
-    where
-        Self: 'b,
-    {
-        f(self.into_owned())
-    }
-
-    fn eval_ref_decompose<'b, R>(
+    fn eval_ref<'b, R>(
         &'b self,
         f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R,
     ) -> R
@@ -245,6 +238,14 @@
     {
         self.cow_owned()
     }
+
+    #[inline]
+    fn decompose<'b>(self) -> OMatrix<E, M, K>
+    where
+        Self: 'b,
+    {
+        self.into_owned()
+    }
 }
 
 impl<SM, N, M, K, E> Mapping<OMatrix<E, M, K>> for Matrix<E, N, M, SM>
@@ -344,7 +345,7 @@
 
     #[inline]
     fn copy_from<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, y: I) {
-        y.eval(|ỹ| Matrix::copy_from(self, ỹ))
+        y.eval_ref(|ỹ| Matrix::copy_from(self, &ỹ))
     }
 
     #[inline]
@@ -458,7 +459,7 @@
 
     #[inline]
     fn dot<I: Instance<Self>>(&self, other: I) -> E {
-        other.eval_ref_decompose(|ref r| Vector::<E, M, S>::dot(self, r))
+        other.eval_ref(|ref r| Vector::<E, M, S>::dot(self, r))
     }
 
     #[inline]
@@ -468,7 +469,7 @@
 
     #[inline]
     fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E {
-        other.eval_ref_decompose(|ref r| metric_distance_squared(self, r))
+        other.eval_ref(|ref r| metric_distance_squared(self, r))
     }
 }
 
@@ -547,7 +548,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E {
-        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r))
+        other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r))
     }
 }
 
@@ -575,7 +576,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E {
-        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r))
+        other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r))
     }
 }
 
@@ -603,7 +604,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E {
-        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r))
+        other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r))
     }
 }
 
--- a/src/operator_arithmetic.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/operator_arithmetic.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -99,7 +99,7 @@
     type Codomain = M::Codomain;
 
     fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain {
-        x.eval_ref_decompose(|xr| self.0.iter().map(|c| c.apply(xr)).sum())
+        x.eval_ref(|xr| self.0.iter().map(|c| c.apply(xr)).sum())
     }
 }
 
@@ -112,6 +112,6 @@
     type Derivative = M::DerivativeDomain;
 
     fn differential_impl<I: Instance<Domain>>(&self, x: I) -> Self::Derivative {
-        x.eval_ref_decompose(|xr| self.0.iter().map(|c| c.differential(xr)).sum())
+        x.eval_ref(|xr| self.0.iter().map(|c| c.differential(xr)).sum())
     }
 }
--- a/src/sets.rs	Wed Sep 03 19:55:05 2025 -0500
+++ b/src/sets.rs	Wed Sep 03 20:19:41 2025 -0500
@@ -36,7 +36,7 @@
     U: Num + PartialOrd + Sized,
 {
     fn contains<I: Instance<Loc<N, U>>>(&self, item: I) -> bool {
-        item.eval_ref_decompose(|r| self.0.iter().zip(r.iter()).all(|(s, x)| s.contains(x)))
+        item.eval_ref(|r| self.0.iter().zip(r.iter()).all(|(s, x)| s.contains(x)))
     }
 }
 
@@ -145,6 +145,6 @@
     F: Float,
 {
     fn contains<I: Instance<A>>(&self, item: I) -> bool {
-        item.eval_ref_decompose(|r| self.0.iter().all(|halfspace| halfspace.contains(r)))
+        item.eval_ref(|r| self.0.iter().all(|halfspace| halfspace.contains(r)))
     }
 }

mercurial