NormConstraint with radius dev

Tue, 24 Dec 2024 14:07:52 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 24 Dec 2024 14:07:52 -0500
branch
dev
changeset 72
44a4f258a1ff
parent 71
511bf440e24b
child 73
ca53a962106c

NormConstraint with radius

src/convex.rs file | annotate | diff | comparison | revisions
src/norms.rs file | annotate | diff | comparison | revisions
--- a/src/convex.rs	Tue Dec 24 13:40:36 2024 -0500
+++ b/src/convex.rs	Tue Dec 24 14:07:52 2024 -0500
@@ -7,6 +7,7 @@
 use crate::mapping::{Mapping, Space};
 use crate::linops::IdOp;
 use crate::instance::{Instance, InstanceMut, DecompositionMut};
+use crate::operator_arithmetic::{Constant, Weighted};
 use crate::norms::*;
 
 /// Trait for convex mappings. Has no features, just serves as a constraint
@@ -67,7 +68,11 @@
 }
 
 
-pub struct NormConjugate<F : Float, E : NormExponent>(NormMapping<F, E>);
+pub struct NormConstraint<F : Float, E : NormExponent> {
+    radius : F,
+    norm : NormMapping<F, E>,
+}
+
 
 impl<Domain, E, F> ConvexMapping<Domain, F> for NormMapping<F, E>
 where
@@ -78,7 +83,7 @@
 {}
 
 
-impl<F, E, Domain> Mapping<Domain> for NormConjugate<F, E>
+impl<F, E, Domain> Mapping<Domain> for NormConstraint<F, E>
 where
     Domain : Space + Norm<F, E>,
     F : Float,
@@ -87,7 +92,7 @@
     type Codomain = F;
 
     fn apply<I : Instance<Domain>>(&self, d : I) -> F {
-        if d.eval(|x| x.norm(self.0.exponent)) <= F::ONE {
+        if d.eval(|x| x.norm(self.norm.exponent)) <= self.radius {
             F::ZERO
         } else {
             F::INFINITY
@@ -95,7 +100,7 @@
     }
 }
 
-impl<Domain, E, F> ConvexMapping<Domain, F> for NormConjugate<F, E>
+impl<Domain, E, F> ConvexMapping<Domain, F> for NormConstraint<F, E>
 where
     Domain : Space,
     E : NormExponent,
@@ -111,10 +116,79 @@
     Domain : HasDual<F> + Norm<F, E> + Space,
     <Domain as HasDual<F>>::DualSpace : Norm<F, E::DualExp>
 {
-    type Conjugate<'a> = NormConjugate<F, E::DualExp> where Self : 'a;
+    type Conjugate<'a> = NormConstraint<F, E::DualExp> where Self : 'a;
+
+    fn conjugate(&self) -> Self::Conjugate<'_> {
+        NormConstraint {
+            radius : F::ONE,
+            norm : self.exponent.dual_exponent().as_mapping()
+        }
+    }
+}
+
+impl<C, E, F, Domain> Conjugable<Domain, F> for Weighted<NormMapping<F, E>, C>
+where
+    C : Constant<Type = F>,
+    E : HasDualExponent,
+    F : Float,
+    Domain : HasDual<F> + Norm<F, E> + Space,
+    <Domain as HasDual<F>>::DualSpace : Norm<F, E::DualExp>
+{
+    type Conjugate<'a> = NormConstraint<F, E::DualExp> where Self : 'a;
 
     fn conjugate(&self) -> Self::Conjugate<'_> {
-        NormConjugate(self.exponent.dual_exponent().as_mapping())
+        NormConstraint {
+            radius : self.weight.value(),
+            norm : self.base_fn.exponent.dual_exponent().as_mapping()
+        }
+    }
+}
+
+impl<Domain, E, F> Prox<Domain> for NormConstraint<F, E>
+where
+    Domain : Space + Norm<F, E>,
+    E : NormExponent,
+    F : Float,
+    NormProjection<F, E> : Mapping<Domain, Codomain=Domain>,
+{
+    type Prox<'a> = NormProjection<F, E> where Self : 'a;
+
+    #[inline]
+    fn prox_mapping(&self, _τ : Self::Codomain) -> Self::Prox<'_> {
+        assert!(self.radius >= F::ZERO);
+        NormProjection{ radius : self.radius, exponent : self.norm.exponent }
+    }
+}
+
+pub struct NormProjection<F : Float, E : NormExponent> {
+    radius : F,
+    exponent : E,
+}
+
+/*
+impl<F, Domain> Mapping<Domain> for NormProjection<F, L2>
+where
+    Domain : Space + Euclidean<F> + std::ops::MulAssign<F>,
+    F : Float,
+{
+    type Codomain = Domain;
+
+    fn apply<I : Instance<Domain>>(&self, d : I) -> Domain {
+        d.own().proj_ball2(self.radius)
+    }
+}
+*/
+
+impl<F, E, Domain> Mapping<Domain> for NormProjection<F, E>
+where
+    Domain : Space + Projection<F, E> + std::ops::MulAssign<F>,
+    F : Float,
+    E : NormExponent,
+{
+    type Codomain = Domain;
+
+    fn apply<I : Instance<Domain>>(&self, d : I) -> Domain {
+        d.own().proj_ball(self.radius, self.exponent)
     }
 }
 
--- a/src/norms.rs	Tue Dec 24 13:40:36 2024 -0500
+++ b/src/norms.rs	Tue Dec 24 14:07:52 2024 -0500
@@ -7,7 +7,6 @@
 use crate::types::*;
 use crate::euclidean::*;
 use crate::mapping::{Mapping, Space, Instance};
-use crate::operator_arithmetic::{Constant, Weighted};
 
 //
 // Abstract norms

mercurial