# HG changeset patch # User Tuomo Valkonen # Date 1756778134 18000 # Node ID 402d717bb5c0c8424a2f4c408b0c3dd795a30d0d # Parent c4e394a9c84ca6f0523592b8e142a4e90176ea32 lots of space changes diff -r c4e394a9c84c -r 402d717bb5c0 src/bisection_tree/support.rs --- 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}; diff -r c4e394a9c84c -r 402d717bb5c0 src/convex.rs --- 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 Prox for Norm222 where F: Float, - X: Euclidean + ClosedMul, + X: Euclidean, { type Prox<'a> = Scaled @@ -415,7 +415,7 @@ type Derivative = X::Owned; fn differential_impl>(&self, x: I) -> Self::Derivative { - x.own() + x.own().into_owned() } } diff -r c4e394a9c84c -r 402d717bb5c0 src/direct_product.rs --- 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, B: Euclidean, - //Pair: Euclidean, - Self: Sized - + Mul::Owned> - + MulAssign - + Div::Owned> - + DivAssign - + Add::Owned> - + Sub::Owned> - + for<'b> Add<&'b Self, Output = ::Owned> - + for<'b> Sub<&'b Self, Output = ::Owned> - + AddAssign - + for<'b> AddAssign<&'b Self> - + SubAssign - + for<'b> SubAssign<&'b Self> - + Neg::Owned>, + // //Pair: Euclidean, + // Self: Sized + // + Mul + // + MulAssign + // + Div + // + DivAssign + // + Add + // + Sub + // + for<'b> Add<&'b Self, Output = Self::OwnedEuclidean> + // + for<'b> Sub<&'b Self, Output = Self::OwnedEuclidean> + // + AddAssign + // + for<'b> AddAssign<&'b Self> + // + SubAssign + // + for<'b> SubAssign<&'b Self> + // + Neg, { + type OwnedEuclidean = Pair; + fn dot>(&self, other: I) -> F { other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) } @@ -318,16 +318,14 @@ } } -impl VectorSpace for Pair +impl VectorSpace for Pair where - A: VectorSpace, - B: VectorSpace, - O: ClosedSpace + AXPY, - P: ClosedSpace + AXPY, + A: VectorSpace, + B: VectorSpace, F: Num, { type Field = F; - type Owned = Pair; + type Owned = Pair; /// Return a similar zero as `self`. fn similar_origin(&self) -> Self::Owned { @@ -347,8 +345,8 @@ A: AXPY, B: AXPY, F: Num, - Self: MulAssign + DivAssign, - Pair: MulAssign + DivAssign, + // Self: MulAssign + DivAssign, + // Pair: MulAssign + DivAssign, { fn axpy>>(&mut self, α: F, x: I, β: F) { x.eval_decompose(|Pair(u, v)| { @@ -383,6 +381,7 @@ pub struct PairDecomposition(D, Q); impl Space for Pair { + type OwnedSpace = Pair; type Decomp = PairDecomposition; } diff -r c4e394a9c84c -r 402d717bb5c0 src/euclidean.rs --- 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: - HasDual - + VectorSpace - + Reflexive - // TODO: move the following to AXPY - + for<'b> Add<&'b Self, Output = ::Owned> - + for<'b> Sub<&'b Self, Output = ::Owned> - + for<'b> AddAssign<&'b Self> - + for<'b> SubAssign<&'b Self> + VectorSpace + + Reflexive { + type OwnedEuclidean: ClosedEuclidean; + // Inner product fn dot>(&self, other: I) -> F; @@ -71,10 +66,14 @@ } } +pub trait ClosedEuclidean: + Instance + Euclidean +{ +} +impl + Euclidean> ClosedEuclidean for X {} + // TODO: remove F parameter, use AXPY::Field -pub trait EuclideanMut: - Euclidean + AXPY + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self> -{ +pub trait EuclideanMut: Euclidean + AXPY { /// In-place projection to the 2-ball. #[inline] fn proj_ball2_mut(&mut self, ρ: F) { @@ -85,10 +84,7 @@ } } -impl EuclideanMut for X where - X: Euclidean + AXPY + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self> -{ -} +impl EuclideanMut for X where X: Euclidean + AXPY {} /// Trait for [`Euclidean`] spaces with dimensions known at compile time. pub trait StaticEuclidean: Euclidean { diff -r c4e394a9c84c -r 402d717bb5c0 src/linops.rs --- 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 + Sub + Neg + + for<'b> Add<&'b Self, Output = ::Owned> + + for<'b> Sub<&'b Self, Output = ::Owned> { type Field: Num; type Owned: ClosedSpace @@ -69,6 +71,8 @@ + AddAssign + SubAssign + SubAssign + + 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 + VectorSpace {} +impl + VectorSpace> ClosedVectorSpace for X {} + /// Efficient in-place application for [`Linear`] operators. #[replace_float_literals(F::cast_from(literal))] pub trait GEMV>::Codomain>: Linear { @@ -141,7 +148,7 @@ X: Space, Yʹ: Space, { - type AdjointCodomain: Space; + type AdjointCodomain: ClosedSpace; type Adjoint<'a>: Linear where Self: 'a; @@ -163,7 +170,7 @@ pub trait Preadjointable>::Codomain>: Linear { - type PreadjointCodomain: Space; + type PreadjointCodomain: ClosedSpace; type Preadjoint<'a>: Linear where Self: 'a; @@ -190,10 +197,10 @@ } impl Mapping for IdOp { - type Codomain = X::OwnedVariant; + type Codomain = X::OwnedSpace; - fn apply>(&self, x: I) -> X { - x.own() + fn apply>(&self, x: I) -> Self::Codomain { + x.own().into_owned() } } @@ -226,10 +233,10 @@ } } -impl Adjointable for IdOp { - type AdjointCodomain = X; +impl Adjointable for IdOp { + type AdjointCodomain = X::OwnedSpace; type Adjoint<'a> - = IdOp + = IdOp where X: 'a; @@ -238,10 +245,10 @@ } } -impl Preadjointable for IdOp { - type PreadjointCodomain = X; +impl Preadjointable for IdOp { + type PreadjointCodomain = X::OwnedSpace; type Preadjoint<'a> - = IdOp + = IdOp where X: 'a; @@ -297,7 +304,7 @@ where F: Num, X: VectorSpace + HasDual, - X::DualSpace: VectorSpace, + X::DualSpace: ClosedVectorSpace, { type AdjointCodomain = X::DualSpace; type Adjoint<'b> @@ -460,9 +467,9 @@ X: HasDual, Y: HasDual, F: Float, - Xprime: VectorSpace, - Xprime::Owned: AXPY, - Yprime: Space + Instance, + Xprime: ClosedVectorSpace, + //Xprime::Owned: AXPY, + Yprime: ClosedSpace, OY: OriginGenerator, OXprime: OriginGenerator, { @@ -540,7 +547,7 @@ S: Mapping, T: Mapping, S::Codomain: Add, - >::Output: Space, + >::Output: ClosedSpace, { type Codomain = >::Output; @@ -556,7 +563,7 @@ S: Linear, T: Linear, S::Codomain: Add, - >::Output: Space, + >::Output: ClosedSpace, { } @@ -693,7 +700,7 @@ A: Space, Xʹ: Space, Yʹ: Space, - R: Space + ClosedAdd, + R: ClosedSpace + ClosedAdd, S: Adjointable, T: Adjointable, Self: Linear, @@ -718,7 +725,7 @@ A: Space, Xʹ: Space, Yʹ: Space, - R: Space + ClosedAdd, + R: ClosedSpace + ClosedAdd, S: Preadjointable, T: Preadjointable, Self: Linear, @@ -802,7 +809,7 @@ B: Space, Xʹ: Space, Yʹ: Space, - R: Space, + R: ClosedSpace, S: Adjointable, T: Adjointable, Self: Linear>, @@ -825,7 +832,7 @@ B: Space, Xʹ: Space, Yʹ: Space, - R: Space, + R: ClosedSpace, S: Preadjointable, T: Preadjointable, Self: Linear>, @@ -856,7 +863,7 @@ S: BoundedLinear, T: BoundedLinear, S::Codomain: Add, - >::Output: Space, + >::Output: ClosedSpace, ExpA: NormExponent, ExpB: NormExponent, ExpR: NormExponent, @@ -912,7 +919,8 @@ impl Mapping for Scaled where F: Float, - Domain: Space + ClosedMul, + Domain: Space + Mul, + >::Output: ClosedSpace, { type Codomain = >::Output; @@ -925,6 +933,7 @@ impl Linear for Scaled where F: Float, - Domain: Space + ClosedMul, + Domain: Space + Mul, + >::Output: ClosedSpace, { } diff -r c4e394a9c84c -r 402d717bb5c0 src/loc.rs --- 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 Euclidean for Loc { + 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] diff -r c4e394a9c84c -r 402d717bb5c0 src/mapping.rs --- 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 Mapping for FlattenedCodomain +impl Mapping for FlattenedCodomain where + F: ClosedSpace, X: Space, G: Mapping>, { @@ -200,7 +201,7 @@ impl<'a, X, F, G, const N: usize> Mapping for SlicedCodomain<'a, X, F, G, N> where X: Space, - F: Copy + Space, + F: Copy + ClosedSpace, G: Mapping>, { type Codomain = F; diff -r c4e394a9c84c -r 402d717bb5c0 src/nalgebra_support.rs --- 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 Euclidean for Vector where M: Dim, - S: StorageMut + Clone, + S: Storage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, { + type OwnedEuclidean = OVector; + #[inline] fn dot>(&self, other: I) -> E { other.eval_ref_decompose(|r| Vector::::dot(self, r)) @@ -296,7 +298,7 @@ impl StaticEuclidean for Vector where M: DimName, - S: StorageMut + Clone, + S: Storage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, { @@ -310,7 +312,7 @@ impl Normed for Vector where M: Dim, - S: Storage + Clone, + S: Storage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, { @@ -330,12 +332,11 @@ impl HasDual for Vector where M: Dim, - S: StorageMut + Clone, + S: Storage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, { - // TODO: Doesn't work with different storage formats. - type DualSpace = Vector; + type DualSpace = OVector; fn dual_origin(&self) -> OVector { OVector::zeros_generic(M::from_usize(self.len()), Const) diff -r c4e394a9c84c -r 402d717bb5c0 src/norms.rs --- 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: Normed + VectorSpace { - type DualSpace: Normed + VectorSpace; + type DualSpace: Normed + ClosedVectorSpace; fn dual_origin(&self) -> ::Owned; } @@ -237,11 +237,14 @@ /// Automatically implemented trait for reflexive spaces pub trait Reflexive: HasDual where - Self::DualSpace: HasDual, + Self::DualSpace: HasDual, { } -impl> Reflexive for X where X::DualSpace: HasDual {} +impl> Reflexive for X where + X::DualSpace: HasDual +{ +} pub trait HasDualExponent: NormExponent { type DualExp: NormExponent; diff -r c4e394a9c84c -r 402d717bb5c0 src/operator_arithmetic.rs --- 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 for Weighted +impl<'a, T, D, F, C> Mapping for Weighted where F: Float, D: Space, - T: Mapping, - V: Space + ClosedMul, + T: Mapping, + T::Codomain: ClosedMul, C: Constant, { - type Codomain = V; + type Codomain = T::Codomain; #[inline] fn apply>(&self, x: I) -> Self::Codomain {