Mon, 01 Sep 2025 23:03:27 -0500
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>