Mon, 01 Sep 2025 20:55:34 -0500
lots of space changes
| src/bisection_tree/support.rs | file | annotate | diff | comparison | revisions | |
| src/convex.rs | file | annotate | diff | comparison | revisions | |
| src/direct_product.rs | file | annotate | diff | comparison | revisions | |
| src/euclidean.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/norms.rs | file | annotate | diff | comparison | revisions | |
| src/operator_arithmetic.rs | file | annotate | diff | comparison | revisions |
--- a/src/bisection_tree/support.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/bisection_tree/support.rs Mon Sep 01 20:55:34 2025 -0500 @@ -4,9 +4,7 @@ use super::aggregator::Bounds; pub use crate::bounds::{GlobalAnalysis, LocalAnalysis}; use crate::loc::Loc; -use crate::mapping::{ - ClosedSpace, DifferentiableImpl, DifferentiableMapping, Instance, Mapping, Space, -}; +use crate::mapping::{ClosedSpace, DifferentiableImpl, DifferentiableMapping, Instance, Mapping}; use crate::maputil::map2; use crate::norms::{Linfinity, Norm, L1, L2}; pub use crate::operator_arithmetic::{Constant, Weighted};
--- a/src/convex.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/convex.rs Mon Sep 01 20:55:34 2025 -0500 @@ -395,7 +395,7 @@ impl<X, F> Prox<X> for Norm222<F> where F: Float, - X: Euclidean<F, Owned = X> + ClosedMul<F>, + X: Euclidean<F>, { type Prox<'a> = Scaled<F> @@ -415,7 +415,7 @@ type Derivative = X::Owned; fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative { - x.own() + x.own().into_owned() } }
--- a/src/direct_product.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/direct_product.rs Mon Sep 01 20:55:34 2025 -0500 @@ -6,9 +6,7 @@ */ use crate::euclidean::Euclidean; -use crate::instance::{ - ClosedSpace, Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable, -}; +use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable}; use crate::linops::{VectorSpace, AXPY}; use crate::loc::Loc; use crate::mapping::Space; @@ -289,22 +287,24 @@ where A: Euclidean<F>, B: Euclidean<F>, - //Pair<A, B>: Euclidean<F>, - Self: Sized - + Mul<F, Output = <Self as VectorSpace>::Owned> - + MulAssign<F> - + Div<F, Output = <Self as VectorSpace>::Owned> - + DivAssign<F> - + Add<Self, Output = <Self as VectorSpace>::Owned> - + Sub<Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> - + AddAssign<Self> - + for<'b> AddAssign<&'b Self> - + SubAssign<Self> - + for<'b> SubAssign<&'b Self> - + Neg<Output = <Self as VectorSpace>::Owned>, + // //Pair<A, B>: Euclidean<F>, + // Self: Sized + // + Mul<F, Output = Self::OwnedEuclidean> + // + MulAssign<F> + // + Div<F, Output = Self::OwnedEuclidean> + // + DivAssign<F> + // + Add<Self, Output = Self::OwnedEuclidean> + // + Sub<Self, Output = Self::OwnedEuclidean> + // + for<'b> Add<&'b Self, Output = Self::OwnedEuclidean> + // + for<'b> Sub<&'b Self, Output = Self::OwnedEuclidean> + // + AddAssign<Self> + // + for<'b> AddAssign<&'b Self> + // + SubAssign<Self> + // + for<'b> SubAssign<&'b Self> + // + Neg<Output = Self::OwnedEuclidean>, { + type OwnedEuclidean = Pair<A::OwnedEuclidean, B::OwnedEuclidean>; + fn dot<I: Instance<Self>>(&self, other: I) -> F { other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) } @@ -318,16 +318,14 @@ } } -impl<F, A, B, O, P> VectorSpace for Pair<A, B> +impl<F, A, B> VectorSpace for Pair<A, B> where - A: VectorSpace<Field = F, Owned = O, OwnedVariant = O>, - B: VectorSpace<Field = F, Owned = P, OwnedVariant = P>, - O: ClosedSpace + AXPY<A, Field = F, Owned = O, OwnedVariant = O>, - P: ClosedSpace + AXPY<B, Field = F, Owned = P, OwnedVariant = P>, + A: VectorSpace<Field = F>, + B: VectorSpace<Field = F>, F: Num, { type Field = F; - type Owned = Pair<O, P>; + type Owned = Pair<A::Owned, B::Owned>; /// Return a similar zero as `self`. fn similar_origin(&self) -> Self::Owned { @@ -347,8 +345,8 @@ A: AXPY<U, Field = F>, B: AXPY<V, Field = F>, F: Num, - Self: MulAssign<F> + DivAssign<F>, - Pair<A, B>: MulAssign<F> + DivAssign<F>, + // Self: MulAssign<F> + DivAssign<F>, + // Pair<A, B>: MulAssign<F> + DivAssign<F>, { fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { x.eval_decompose(|Pair(u, v)| { @@ -383,6 +381,7 @@ pub struct PairDecomposition<D, Q>(D, Q); impl<A: Space, B: Space> Space for Pair<A, B> { + type OwnedSpace = Pair<A::OwnedSpace, B::OwnedSpace>; type Decomp = PairDecomposition<A::Decomp, B::Decomp>; }
--- a/src/euclidean.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/euclidean.rs Mon Sep 01 20:55:34 2025 -0500 @@ -4,9 +4,8 @@ use crate::instance::Instance; use crate::linops::{VectorSpace, AXPY}; -use crate::norms::{HasDual, Reflexive}; +use crate::norms::Reflexive; use crate::types::*; -use std::ops::{Add, AddAssign, Sub, SubAssign}; pub mod wrap; @@ -17,17 +16,13 @@ /// The type should implement vector space operations (addition, subtraction, scalar /// multiplication and scalar division) along with their assignment versions, as well /// as an inner product. -// TODO: remove F parameter, use AXPY::Field +// TODO: remove F parameter, use VectorSpace::Field pub trait Euclidean<F: Float = f64>: - HasDual<F, DualSpace = Self> - + VectorSpace<Field = F> - + Reflexive<F> - // TODO: move the following to AXPY - + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> - + for<'b> AddAssign<&'b Self> - + for<'b> SubAssign<&'b Self> + VectorSpace<Field = F, Owned = Self::OwnedEuclidean> + + Reflexive<F, DualSpace = Self::OwnedEuclidean> { + type OwnedEuclidean: ClosedEuclidean<F>; + // Inner product fn dot<I: Instance<Self>>(&self, other: I) -> F; @@ -71,10 +66,14 @@ } } +pub trait ClosedEuclidean<F: Float = f64>: + Instance<Self> + Euclidean<F, OwnedEuclidean = Self> +{ +} +impl<F: Float, X: Instance<X> + Euclidean<F, OwnedEuclidean = Self>> ClosedEuclidean<F> for X {} + // TODO: remove F parameter, use AXPY::Field -pub trait EuclideanMut<F: Float = f64>: - Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self> -{ +pub trait EuclideanMut<F: Float = f64>: Euclidean<F> + AXPY<Field = F> { /// In-place projection to the 2-ball. #[inline] fn proj_ball2_mut(&mut self, ρ: F) { @@ -85,10 +84,7 @@ } } -impl<X, F: Float> EuclideanMut<F> for X where - X: Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self> -{ -} +impl<X, F: Float> EuclideanMut<F> for X where X: Euclidean<F> + AXPY<Field = F> {} /// Trait for [`Euclidean`] spaces with dimensions known at compile time. pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> {
--- a/src/linops.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/linops.rs Mon Sep 01 20:55:34 2025 -0500 @@ -36,6 +36,8 @@ + Sub<Self, Output = Self::Owned> + Sub<Self::Owned, Output = Self::Owned> + Neg + + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> + + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> { type Field: Num; type Owned: ClosedSpace @@ -69,6 +71,8 @@ + AddAssign<Self::Owned> + SubAssign<Self> + SubAssign<Self::Owned> + + for<'b> AddAssign<&'b Self> + + for<'b> SubAssign<&'b Self> where X: Space, { @@ -89,6 +93,9 @@ fn set_zero(&mut self); } +pub trait ClosedVectorSpace: Instance<Self> + VectorSpace<Owned = Self> {} +impl<X: Instance<X> + VectorSpace<Owned = Self>> ClosedVectorSpace for X {} + /// Efficient in-place application for [`Linear`] operators. #[replace_float_literals(F::cast_from(literal))] pub trait GEMV<F: Num, X: Space, Y = <Self as Mapping<X>>::Codomain>: Linear<X> { @@ -141,7 +148,7 @@ X: Space, Yʹ: Space, { - type AdjointCodomain: Space; + type AdjointCodomain: ClosedSpace; type Adjoint<'a>: Linear<Yʹ, Codomain = Self::AdjointCodomain> where Self: 'a; @@ -163,7 +170,7 @@ pub trait Preadjointable<X: Space, Ypre: Space = <Self as Mapping<X>>::Codomain>: Linear<X> { - type PreadjointCodomain: Space; + type PreadjointCodomain: ClosedSpace; type Preadjoint<'a>: Linear<Ypre, Codomain = Self::PreadjointCodomain> where Self: 'a; @@ -190,10 +197,10 @@ } impl<X: Space> Mapping<X> for IdOp<X> { - type Codomain = X::OwnedVariant; + type Codomain = X::OwnedSpace; - fn apply<I: Instance<X>>(&self, x: I) -> X { - x.own() + fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { + x.own().into_owned() } } @@ -226,10 +233,10 @@ } } -impl<X: Clone + Space> Adjointable<X, X> for IdOp<X> { - type AdjointCodomain = X; +impl<X: Clone + Space> Adjointable<X, X::OwnedSpace> for IdOp<X> { + type AdjointCodomain = X::OwnedSpace; type Adjoint<'a> - = IdOp<X> + = IdOp<X::OwnedSpace> where X: 'a; @@ -238,10 +245,10 @@ } } -impl<X: Clone + Space> Preadjointable<X, X> for IdOp<X> { - type PreadjointCodomain = X; +impl<X: Clone + Space> Preadjointable<X, X::OwnedSpace> for IdOp<X> { + type PreadjointCodomain = X::OwnedSpace; type Preadjoint<'a> - = IdOp<X> + = IdOp<X::OwnedSpace> where X: 'a; @@ -297,7 +304,7 @@ where F: Num, X: VectorSpace<Field = F> + HasDual<F>, - X::DualSpace: VectorSpace<Owned = X::DualSpace>, + X::DualSpace: ClosedVectorSpace, { type AdjointCodomain = X::DualSpace; type Adjoint<'b> @@ -460,9 +467,9 @@ X: HasDual<F, DualSpace = Xprime>, Y: HasDual<F, DualSpace = Yprime>, F: Float, - Xprime: VectorSpace<Field = F, Owned = Xprime>, - Xprime::Owned: AXPY<Field = F>, - Yprime: Space + Instance<Yprime>, + Xprime: ClosedVectorSpace<Field = F>, + //Xprime::Owned: AXPY<Field = F>, + Yprime: ClosedSpace, OY: OriginGenerator<Y>, OXprime: OriginGenerator<X::DualSpace>, { @@ -540,7 +547,7 @@ S: Mapping<A>, T: Mapping<B>, S::Codomain: Add<T::Codomain>, - <S::Codomain as Add<T::Codomain>>::Output: Space, + <S::Codomain as Add<T::Codomain>>::Output: ClosedSpace, { type Codomain = <S::Codomain as Add<T::Codomain>>::Output; @@ -556,7 +563,7 @@ S: Linear<A>, T: Linear<B>, S::Codomain: Add<T::Codomain>, - <S::Codomain as Add<T::Codomain>>::Output: Space, + <S::Codomain as Add<T::Codomain>>::Output: ClosedSpace, { } @@ -693,7 +700,7 @@ A: Space, Xʹ: Space, Yʹ: Space, - R: Space + ClosedAdd, + R: ClosedSpace + ClosedAdd, S: Adjointable<A, Xʹ, AdjointCodomain = R>, T: Adjointable<A, Yʹ, AdjointCodomain = R>, Self: Linear<A>, @@ -718,7 +725,7 @@ A: Space, Xʹ: Space, Yʹ: Space, - R: Space + ClosedAdd, + R: ClosedSpace + ClosedAdd, S: Preadjointable<A, Xʹ, PreadjointCodomain = R>, T: Preadjointable<A, Yʹ, PreadjointCodomain = R>, Self: Linear<A>, @@ -802,7 +809,7 @@ B: Space, Xʹ: Space, Yʹ: Space, - R: Space, + R: ClosedSpace, S: Adjointable<A, Xʹ>, T: Adjointable<B, Yʹ>, Self: Linear<Pair<A, B>>, @@ -825,7 +832,7 @@ B: Space, Xʹ: Space, Yʹ: Space, - R: Space, + R: ClosedSpace, S: Preadjointable<A, Xʹ>, T: Preadjointable<B, Yʹ>, Self: Linear<Pair<A, B>>, @@ -856,7 +863,7 @@ S: BoundedLinear<A, ExpA, ExpR, F>, T: BoundedLinear<B, ExpB, ExpR, F>, S::Codomain: Add<T::Codomain>, - <S::Codomain as Add<T::Codomain>>::Output: Space, + <S::Codomain as Add<T::Codomain>>::Output: ClosedSpace, ExpA: NormExponent, ExpB: NormExponent, ExpR: NormExponent, @@ -912,7 +919,8 @@ impl<Domain, F> Mapping<Domain> for Scaled<F> where F: Float, - Domain: Space + ClosedMul<F>, + Domain: Space + Mul<F>, + <Domain as Mul<F>>::Output: ClosedSpace, { type Codomain = <Domain as Mul<F>>::Output; @@ -925,6 +933,7 @@ impl<Domain, F> Linear<Domain> for Scaled<F> where F: Float, - Domain: Space + ClosedMul<F>, + Domain: Space + Mul<F>, + <Domain as Mul<F>>::Output: ClosedSpace, { }
--- a/src/loc.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/loc.rs Mon Sep 01 20:55:34 2025 -0500 @@ -448,6 +448,8 @@ domination!(L2, L1); impl<F: Float, const N: usize> Euclidean<F> for Loc<N, F> { + type OwnedEuclidean = Self; + /// This implementation is not stabilised as it's meant to be used for very small vectors. /// Use [`nalgebra`] for larger vectors. #[inline]
--- a/src/mapping.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/mapping.rs Mon Sep 01 20:55:34 2025 -0500 @@ -166,8 +166,9 @@ _phantoms: PhantomData<(X, F)>, } -impl<F: Space, X, G> Mapping<X> for FlattenedCodomain<X, F, G> +impl<F, X, G> Mapping<X> for FlattenedCodomain<X, F, G> where + F: ClosedSpace, X: Space, G: Mapping<X, Codomain = Loc<1, F>>, { @@ -200,7 +201,7 @@ impl<'a, X, F, G, const N: usize> Mapping<X> for SlicedCodomain<'a, X, F, G, N> where X: Space, - F: Copy + Space, + F: Copy + ClosedSpace, G: Mapping<X, Codomain = Loc<N, F>>, { type Codomain = F;
--- a/src/nalgebra_support.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/nalgebra_support.rs Mon Sep 01 20:55:34 2025 -0500 @@ -273,10 +273,12 @@ impl<E, M, S> Euclidean<E> for Vector<E, M, S> where M: Dim, - S: StorageMut<E, M> + Clone, + S: Storage<E, M>, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator<M>, { + type OwnedEuclidean = OVector<E, M>; + #[inline] fn dot<I: Instance<Self>>(&self, other: I) -> E { other.eval_ref_decompose(|r| Vector::<E, M, S>::dot(self, r)) @@ -296,7 +298,7 @@ impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> where M: DimName, - S: StorageMut<E, M> + Clone, + S: Storage<E, M>, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator<M>, { @@ -310,7 +312,7 @@ impl<E, M, S> Normed<E> for Vector<E, M, S> where M: Dim, - S: Storage<E, M> + Clone, + S: Storage<E, M>, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator<M>, { @@ -330,12 +332,11 @@ impl<E, M, S> HasDual<E> for Vector<E, M, S> where M: Dim, - S: StorageMut<E, M> + Clone, + S: Storage<E, M>, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator<M>, { - // TODO: Doesn't work with different storage formats. - type DualSpace = Vector<E, M, S>; + type DualSpace = OVector<E, M>; fn dual_origin(&self) -> OVector<E, M> { OVector::zeros_generic(M::from_usize(self.len()), Const)
--- a/src/norms.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/norms.rs Mon Sep 01 20:55:34 2025 -0500 @@ -4,7 +4,7 @@ use crate::euclidean::*; use crate::instance::Ownable; -use crate::linops::VectorSpace; +use crate::linops::{ClosedVectorSpace, VectorSpace}; use crate::mapping::{Instance, Mapping, Space}; use crate::types::*; use serde::{Deserialize, Serialize}; @@ -229,7 +229,7 @@ } pub trait HasDual<F: Num = f64>: Normed<F> + VectorSpace<Field = F> { - type DualSpace: Normed<F> + VectorSpace<Field = F>; + type DualSpace: Normed<F> + ClosedVectorSpace<Field = F>; fn dual_origin(&self) -> <Self::DualSpace as VectorSpace>::Owned; } @@ -237,11 +237,14 @@ /// Automatically implemented trait for reflexive spaces pub trait Reflexive<F: Num = f64>: HasDual<F> where - Self::DualSpace: HasDual<F, DualSpace = Self>, + Self::DualSpace: HasDual<F, DualSpace = Self::OwnedSpace>, { } -impl<F: Num, X: HasDual<F>> Reflexive<F> for X where X::DualSpace: HasDual<F, DualSpace = X> {} +impl<F: Num, X: HasDual<F>> Reflexive<F> for X where + X::DualSpace: HasDual<F, DualSpace = Self::OwnedSpace> +{ +} pub trait HasDualExponent: NormExponent { type DualExp: NormExponent;
--- a/src/operator_arithmetic.rs Mon Sep 01 13:51:03 2025 -0500 +++ b/src/operator_arithmetic.rs Mon Sep 01 20:55:34 2025 -0500 @@ -42,15 +42,15 @@ } } -impl<'a, T, V, D, F, C> Mapping<D> for Weighted<T, C> +impl<'a, T, D, F, C> Mapping<D> for Weighted<T, C> where F: Float, D: Space, - T: Mapping<D, Codomain = V>, - V: Space + ClosedMul<F>, + T: Mapping<D>, + T::Codomain: ClosedMul<F>, C: Constant<Type = F>, { - type Codomain = V; + type Codomain = T::Codomain; #[inline] fn apply<I: Instance<D>>(&self, x: I) -> Self::Codomain {