--- a/src/convex.rs Tue Dec 31 08:48:50 2024 -0500 +++ b/src/convex.rs Mon Dec 23 23:27:45 2024 -0500 @@ -4,9 +4,9 @@ use std::marker::PhantomData; use crate::types::*; -use crate::mapping::{Mapping, Space}; +use crate::mapping::{Mapping, Space, ArithmeticTrue}; use crate::linops::IdOp; -use crate::instance::{Instance, InstanceMut, DecompositionMut}; +use crate::instance::{Instance, InstanceMut, DecompositionMut,}; use crate::norms::*; /// Trait for convex mappings. Has no features, just serves as a constraint @@ -85,6 +85,7 @@ E : NormExponent, { type Codomain = F; + type ArithmeticOptIn = ArithmeticTrue; fn apply<I : Instance<Domain>>(&self, d : I) -> F { if d.eval(|x| x.norm(self.0.exponent)) <= F::ONE { @@ -118,6 +119,53 @@ } } +impl<Domain, E, F> Prox<Domain> for NormConjugate<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<'_> { + NormProjection{ α : τ, exponent : self.0.exponent } + } +} + +pub struct NormProjection<F : Float, E : NormExponent> { + α : 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.α) + } +} +*/ + +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; + type ArithmeticOptIn = ArithmeticTrue; + + fn apply<I : Instance<Domain>>(&self, d : I) -> Domain { + d.own().proj_ball(self.α, self.exponent) + } +} /// The zero mapping pub struct Zero<Domain : Space, F : Num>(PhantomData<(Domain, F)>); @@ -130,6 +178,7 @@ impl<Domain : Space, F : Num> Mapping<Domain> for Zero<Domain, F> { type Codomain = F; + type ArithmeticOptIn = ArithmeticTrue; /// Compute the value of `self` at `x`. fn apply<I : Instance<Domain>>(&self, _x : I) -> Self::Codomain { @@ -183,6 +232,7 @@ impl<Domain : Normed<F>, F : Float> Mapping<Domain> for ZeroIndicator<Domain, F> { type Codomain = F; + type ArithmeticOptIn = ArithmeticTrue; /// Compute the value of `self` at `x`. fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain {