src/convex.rs

branch
dev
changeset 150
c4e394a9c84c
parent 146
3f9a03f95457
child 151
402d717bb5c0
--- 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;
 

mercurial