--- a/src/convex.rs Mon Sep 01 00:04:22 2025 -0500 +++ b/src/convex.rs Mon Sep 01 13:51:03 2025 -0500 @@ -4,7 +4,7 @@ use crate::error::DynResult; use crate::euclidean::Euclidean; -use crate::instance::{DecompositionMut, Instance, InstanceMut}; +use crate::instance::{ClosedSpace, DecompositionMut, Instance}; use crate::linops::{IdOp, Scaled, SimpleZeroOp, AXPY}; use crate::mapping::{DifferentiableImpl, LipschitzDifferentiableImpl, Mapping, Space}; use crate::norms::*; @@ -57,7 +57,7 @@ /// The conjugate type has to implement [`ConvexMapping`], but a `Conjugable` mapping need /// not be convex. pub trait Prox<Domain: Space>: Mapping<Domain> { - type Prox<'a>: Mapping<Domain, Codomain = Domain> + type Prox<'a>: Mapping<Domain, Codomain = Domain::OwnedSpace> where Self: 'a; @@ -65,16 +65,15 @@ fn prox_mapping(&self, τ: Self::Codomain) -> Self::Prox<'_>; /// Calculate the proximal mapping with weight τ - fn prox<I: Instance<Domain>>(&self, τ: Self::Codomain, z: I) -> Domain { + fn prox<I: Instance<Domain>>(&self, τ: Self::Codomain, z: I) -> Domain::OwnedSpace { self.prox_mapping(τ).apply(z) } /// Calculate the proximal mapping with weight τ in-place - fn prox_mut<'b>(&self, τ: Self::Codomain, y: &'b mut Domain) + fn prox_mut<'b>(&self, τ: Self::Codomain, y: &'b mut Domain::OwnedSpace) where - &'b mut Domain: InstanceMut<Domain>, Domain::Decomp: DecompositionMut<Domain>, - for<'a> &'a Domain: Instance<Domain>, + for<'a> &'a Domain::OwnedSpace: Instance<Domain>, { *y = self.prox(τ, &*y); } @@ -165,7 +164,7 @@ Domain: Space + Norm<E, F>, E: NormExponent, F: Float, - NormProjection<F, E>: Mapping<Domain, Codomain = Domain>, + NormProjection<F, E>: Mapping<Domain, Codomain = Domain::OwnedSpace>, { type Prox<'a> = NormProjection<F, E> @@ -203,12 +202,13 @@ impl<F, E, Domain> Mapping<Domain> for NormProjection<F, E> where Domain: Normed<F> + Projection<F, E>, + Domain::OwnedSpace: ClosedSpace, F: Float, E: NormExponent, { - type Codomain = Domain; + type Codomain = Domain::OwnedSpace; - fn apply<I: Instance<Domain>>(&self, d: I) -> Domain { + fn apply<I: Instance<Domain>>(&self, d: I) -> Self::Codomain { d.own().proj_ball(self.radius, self.exponent) } } @@ -262,7 +262,7 @@ } } -impl<Domain: Space + Clone, F: Num> Prox<Domain> for Zero<Domain, F> { +impl<Domain: Space, F: Num> Prox<Domain> for Zero<Domain, F> { type Prox<'a> = IdOp<Domain> where @@ -395,7 +395,7 @@ impl<X, F> Prox<X> for Norm222<F> where F: Float, - X: Euclidean<F, Owned = X>, + X: Euclidean<F, Owned = X> + ClosedMul<F>, { type Prox<'a> = Scaled<F> @@ -410,11 +410,11 @@ impl<X, F> DifferentiableImpl<X> for Norm222<F> where F: Float, - X: Euclidean<F, Owned = X>, + X: Euclidean<F>, { - type Derivative = X; + type Derivative = X::Owned; - fn differential_impl<I: Instance<X>>(&self, x: I) -> X { + fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative { x.own() } } @@ -422,7 +422,7 @@ impl<X, F> LipschitzDifferentiableImpl<X, L2> for Norm222<F> where F: Float, - X: Euclidean<F, Owned = X>, + X: Euclidean<F>, { type FloatType = F;