fubar draft dev

Mon, 01 Sep 2025 23:03:27 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 01 Sep 2025 23:03:27 -0500
branch
dev
changeset 152
dab30b331f49
parent 151
402d717bb5c0

fubar

src/bisection_tree/btfn.rs file | annotate | diff | comparison | revisions
src/convex.rs file | annotate | diff | comparison | revisions
src/direct_product.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/nalgebra_support.rs file | annotate | diff | comparison | revisions
--- a/src/bisection_tree/btfn.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/bisection_tree/btfn.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -1,4 +1,4 @@
-use crate::instance::{ClosedSpace, Instance, Ownable, Space};
+use crate::instance::{ClosedSpace, Instance, MyCow, Ownable, Space};
 use crate::mapping::{BasicDecomposition, DifferentiableImpl, DifferentiableMapping, Mapping};
 use crate::types::Float;
 use numeric_literals::replace_float_literals;
@@ -48,10 +48,23 @@
         self
     }
 
-    /// Returns an owned instance of a reference.
     fn clone_owned(&self) -> Self::OwnedVariant {
         self.clone()
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        MyCow::Owned(self.into_owned())
+    }
+
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        MyCow::Owned(self.into_owned())
+    }
 }
 
 impl<F: Float, G, BT, const N: usize> Space for BTFN<F, G, BT, N>
--- a/src/convex.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/convex.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -4,7 +4,7 @@
 
 use crate::error::DynResult;
 use crate::euclidean::Euclidean;
-use crate::instance::{ClosedSpace, DecompositionMut, Instance};
+use crate::instance::{DecompositionMut, Instance};
 use crate::linops::{IdOp, Scaled, SimpleZeroOp, AXPY};
 use crate::mapping::{DifferentiableImpl, LipschitzDifferentiableImpl, Mapping, Space};
 use crate::norms::*;
@@ -202,7 +202,6 @@
 impl<F, E, Domain> Mapping<Domain> for NormProjection<F, E>
 where
     Domain: Normed<F> + Projection<F, E>,
-    Domain::OwnedSpace: ClosedSpace,
     F: Float,
     E: NormExponent,
 {
@@ -412,10 +411,10 @@
     F: Float,
     X: Euclidean<F>,
 {
-    type Derivative = X::Owned;
+    type Derivative = X::OwnedEuclidean;
 
     fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative {
-        x.own().into_owned()
+        x.into_owned()
     }
 }
 
--- a/src/direct_product.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/direct_product.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -6,7 +6,9 @@
 */
 
 use crate::euclidean::Euclidean;
-use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable};
+use crate::instance::{
+    Decomposition, DecompositionMut, EitherDecomp, Instance, InstanceMut, MyCow, Ownable,
+};
 use crate::linops::{VectorSpace, AXPY};
 use crate::loc::Loc;
 use crate::mapping::Space;
@@ -279,6 +281,14 @@
     fn clone_owned(&self) -> Self::OwnedVariant {
         Pair(self.0.clone_owned(), self.1.clone_owned())
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> {
+        EitherDecomp::Owned(self.into_owned())
+    }
+
+    fn ref_owned_cow<'b>(&self) -> MyCow<'b, Self::OwnedVariant> {
+        EitherDecomp::Owned(self.into_owned())
+    }
 }
 
 /// We only support 'closed' `Euclidean` `Pair`s, as more general ones cause
@@ -439,19 +449,6 @@
         self.0
             .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b))))
     }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>>
-    where
-        Self: 'b,
-    {
-        MyCow::Owned(Pair(self.0.own(), self.1.own()))
-    }
-
-    #[inline]
-    fn own(self) -> Pair<A, B> {
-        Pair(self.0.own(), self.1.own())
-    }
 }
 
 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V>
@@ -490,20 +487,6 @@
         self.0
             .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b))))
     }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>>
-    where
-        Self: 'b,
-    {
-        MyCow::Owned(self.own())
-    }
-
-    #[inline]
-    fn own(self) -> Pair<A, B> {
-        let Pair(ref u, ref v) = self;
-        Pair(u.own(), v.own())
-    }
 }
 
 impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D, Q>
--- a/src/instance.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/instance.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -24,7 +24,7 @@
 }
 
 /// Trait for ownable-by-consumption objects
-pub trait Ownable {
+pub trait Ownable: Sized {
     type OwnedVariant: Clone;
 
     /// Returns an owned instance, possibly consuming the original,
@@ -33,22 +33,45 @@
 
     /// Returns an owned instance of a reference.
     fn clone_owned(&self) -> Self::OwnedVariant;
+
+    /// Returns either an owned instance or a reference to one
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b;
+
+    /// Returns either an owned instance or a reference to one, preferring a reference.
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b;
 }
 
 impl<'a, X: Ownable> Ownable for &'a X {
     type OwnedVariant = X::OwnedVariant;
 
     #[inline]
-    /// Returns an owned instance.
     fn into_owned(self) -> Self::OwnedVariant {
         self.clone_owned()
     }
 
     #[inline]
-    /// Returns an owned instance.
     fn clone_owned(&self) -> Self::OwnedVariant {
         (*self).into_owned()
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        (*self).ref_owned_cow()
+    }
+
+    #[inline]
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        (*self).ref_owned_cow()
+    }
 }
 
 impl<'a, X: Ownable> Ownable for &'a mut X {
@@ -65,6 +88,21 @@
     fn clone_owned(&self) -> Self::OwnedVariant {
         (&**self).into_owned()
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        (&*self).ref_owned_cow()
+    }
+
+    #[inline]
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        (&**self).ref_owned_cow()
+    }
 }
 
 impl<'a, X: Ownable> Ownable for MyCow<'a, X> {
@@ -87,6 +125,24 @@
             EitherDecomp::Borrowed(x) => x.into_owned(),
         }
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        match self {
+            EitherDecomp::Owned(x) => x.owned_cow(),
+            EitherDecomp::Borrowed(x) => x.ref_owned_cow(),
+        }
+    }
+
+    #[inline]
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        (&**self).ref_owned_cow()
+    }
 }
 
 /// Trait for abitrary mathematical spaces.
@@ -134,6 +190,16 @@
             fn clone_owned(&self) -> Self::OwnedVariant {
                 *self
             }
+
+            #[inline]
+            fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b {
+                EitherDecomp::Owned(self)
+            }
+
+            #[inline]
+            fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b{
+                EitherDecomp::Owned(*self)
+            }
         }
     };
 }
@@ -186,7 +252,8 @@
 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`].
 ///
 /// This is used, for example, by [`crate::mapping::Mapping::apply`].
-pub trait Instance<X, D = <X as Space>::Decomp>: Sized + Ownable
+pub trait Instance<X, D = <X as Space>::Decomp>:
+    Sized + Ownable<OwnedVariant = X::OwnedSpace>
 where
     X: Space,
     D: Decomposition<X>,
@@ -205,26 +272,40 @@
         X: 'b,
         Self: 'b;
 
+    // fn eval_<'b, R>(
+    //     &'b self,
+    //     _f: impl FnOnce(D::Decomposition<'b>) -> R,
+    //     g: impl FnOnce(D::Reference<'b>) -> R,
+    // ) -> R
+    // where
+    //     X: 'b,
+    //     Self: 'b,
+    // {
+    //     self.eval_ref_decompose(g)
+    // }
+
     /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary.
-    fn own(self) -> X;
+    fn own(self) -> X::OwnedSpace {
+        self.into_owned()
+    }
 
     // ************** automatically implemented methods below from here **************
 
     /// Returns an owned instance or reference to `X`, converting non-true instances when necessary.
     ///
     /// Default implementation uses [`Self::own`]. Consumes the input.
-    fn cow<'b>(self) -> MyCow<'b, X>
+    fn cow<'b>(self) -> MyCow<'b, X::OwnedSpace>
     where
         Self: 'b,
     {
-        MyCow::Owned(self.own())
+        self.owned_cow()
     }
 
     #[inline]
     /// Evaluates `f` on a reference to self.
     ///
     /// Default implementation uses [`Self::cow`]. Consumes the input.
-    fn eval<'b, R>(self, f: impl FnOnce(&X) -> R) -> R
+    fn eval<'b, R>(self, f: impl FnOnce(&X::OwnedSpace) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -236,7 +317,11 @@
     /// Evaluates `f` or `g` depending on whether a reference or owned value is available.
     ///
     /// Default implementation uses [`Self::cow`]. Consumes the input.
-    fn either<'b, R>(self, f: impl FnOnce(X) -> R, g: impl FnOnce(&X) -> R) -> R
+    fn either<'b, R>(
+        self,
+        f: impl FnOnce(X::OwnedSpace) -> R,
+        g: impl FnOnce(&X::OwnedSpace) -> R,
+    ) -> R
     where
         Self: 'b,
     {
@@ -265,19 +350,6 @@
     {
         f(self)
     }
-
-    #[inline]
-    fn own(self) -> X {
-        self
-    }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, X>
-    where
-        Self: 'b,
-    {
-        MyCow::Owned(self)
-    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a X {
@@ -298,19 +370,6 @@
     {
         f(*self)
     }
-
-    #[inline]
-    fn own(self) -> X {
-        self.into_owned()
-    }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, X>
-    where
-        Self: 'b,
-    {
-        MyCow::Borrowed(self)
-    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a mut X {
@@ -331,19 +390,6 @@
     {
         f(*self)
     }
-
-    #[inline]
-    fn own(self) -> X {
-        self.into_owned()
-    }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, X>
-    where
-        Self: 'b,
-    {
-        EitherDecomp::Borrowed(self)
-    }
 }
 
 impl<'a, X: Space> Instance<X, BasicDecomposition> for MyCow<'a, X> {
@@ -367,25 +413,6 @@
             MyCow::Owned(b) => f(&b),
         }
     }
-
-    #[inline]
-    fn own(self) -> X {
-        match self {
-            MyCow::Borrowed(a) => a.own(),
-            MyCow::Owned(b) => b.own(),
-        }
-    }
-
-    #[inline]
-    fn cow<'b>(self) -> MyCow<'b, X>
-    where
-        Self: 'b,
-    {
-        match self {
-            MyCow::Borrowed(a) => a.cow(),
-            MyCow::Owned(b) => b.cow(),
-        }
-    }
 }
 
 /// Marker type for mutable decompositions to be used with [`InstanceMut`].
--- a/src/linops.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/linops.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -200,7 +200,7 @@
     type Codomain = X::OwnedSpace;
 
     fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
-        x.own().into_owned()
+        x.into_owned()
     }
 }
 
--- a/src/loc.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/loc.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -4,7 +4,7 @@
 */
 
 use crate::euclidean::*;
-use crate::instance::{BasicDecomposition, Instance, Ownable};
+use crate::instance::{BasicDecomposition, Instance, MyCow, Ownable};
 use crate::linops::{Linear, Mapping, VectorSpace, AXPY};
 use crate::mapping::Space;
 use crate::maputil::{map1, map1_mut, map2, map2_mut, FixedLength, FixedLengthMut};
@@ -40,6 +40,21 @@
     fn clone_owned(&self) -> Self::OwnedVariant {
         self.clone()
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        MyCow::Owned(self)
+    }
+
+    #[inline]
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        MyCow::Borrowed(self)
+    }
 }
 
 impl<F: Display, const N: usize> Display for Loc<N, F> {
--- a/src/nalgebra_support.rs	Mon Sep 01 20:55:34 2025 -0500
+++ b/src/nalgebra_support.rs	Mon Sep 01 23:03:27 2025 -0500
@@ -9,17 +9,17 @@
 */
 
 use crate::euclidean::*;
-use crate::instance::{Instance, Ownable};
+use crate::instance::{Decomposition, EitherDecomp, Instance, MyCow, Ownable};
 use crate::linops::*;
-use crate::mapping::{BasicDecomposition, Space};
+use crate::mapping::Space;
 use crate::norms::*;
 use crate::types::Float;
 use nalgebra::base::allocator::Allocator;
 use nalgebra::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
 use nalgebra::base::dimension::*;
 use nalgebra::{
-    ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, OMatrix, OVector,
-    RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, Vector,
+    ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, MatrixView, OMatrix,
+    OVector, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, Vector,
 };
 use num_traits::identities::{One, Zero};
 use std::ops::Mul;
@@ -43,6 +43,20 @@
     fn clone_owned(&self) -> Self::OwnedVariant {
         Matrix::clone_owned(self)
     }
+
+    fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        EitherDecomp::Owned(self.into_owned())
+    }
+
+    fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant>
+    where
+        Self: 'b,
+    {
+        EitherDecomp::Owned(self.into_owned())
+    }
 }
 
 impl<SM, N, M, E> Space for Matrix<E, N, M, SM>
@@ -54,7 +68,61 @@
     DefaultAllocator: Allocator<N, M>,
 {
     type OwnedSpace = OMatrix<E, N, M>;
-    type Decomp = BasicDecomposition;
+    type Decomp = MatrixDecomposition;
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct MatrixDecomposition;
+
+impl<E, M, K, S> Decomposition<Matrix<E, M, K, S>> for MatrixDecomposition
+where
+    S: Storage<E, M, K>,
+    M: Dim,
+    K: Dim,
+    E: Scalar + Zero + One,
+    DefaultAllocator: Allocator<M, K>,
+{
+    type Decomposition<'b>
+        = OMatrix<E, M, K>
+    where
+        Matrix<E, M, K, S>: 'b;
+    type Reference<'b>
+        = &'b MatrixView<'b, E, M, K, Dyn, Dyn>
+    where
+        Matrix<E, M, K, S>: 'b;
+
+    #[inline]
+    fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b> {
+        r.into_owned()
+    }
+}
+
+impl<SM, SV, M, K, E> Instance<Matrix<E, M, K, SM>> for Matrix<E, M, K, SV>
+where
+    SM: Storage<E, M, K>,
+    SV: Storage<E, M, K>,
+    M: Dim,
+    K: Dim,
+    E: Scalar + Zero + One,
+    DefaultAllocator: Allocator<M, K>,
+{
+    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>(
+        &'b self,
+        f: impl FnOnce(&'b MatrixView<'b, E, M, K, Dyn, Dyn>) -> R,
+    ) -> R
+    where
+        Self: 'b,
+        Matrix<E, M, K, SM>: 'b,
+    {
+        f(&self.as_view::<M, K, Dyn, Dyn>())
+    }
 }
 
 impl<SM, SV, N, M, K, E> Mapping<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM>

mercurial