Sat, 06 Sep 2025 23:29:34 -0500
wrap guard interface
| 58 | 1 | /*! |
| 2 | Some convex analysis basics | |
| 3 | */ | |
| 4 | ||
| 112 | 5 | use crate::error::DynResult; |
| 104 | 6 | use crate::euclidean::Euclidean; |
| 150 | 7 | use crate::instance::{ClosedSpace, DecompositionMut, Instance}; |
|
129
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
8 | use crate::linops::{IdOp, Scaled, SimpleZeroOp, AXPY}; |
| 112 | 9 | use crate::mapping::{DifferentiableImpl, LipschitzDifferentiableImpl, Mapping, Space}; |
| 104 | 10 | use crate::norms::*; |
| 72 | 11 | use crate::operator_arithmetic::{Constant, Weighted}; |
| 104 | 12 | use crate::types::*; |
| 106 | 13 | use serde::{Deserialize, Serialize}; |
| 104 | 14 | use std::marker::PhantomData; |
| 58 | 15 | |
| 16 | /// Trait for convex mappings. Has no features, just serves as a constraint | |
| 17 | /// | |
| 18 | /// TODO: should constrain `Mapping::Codomain` to implement a partial order, | |
| 19 | /// but this makes everything complicated with little benefit. | |
| 163 | 20 | pub trait ConvexMapping<Domain: Space, F: Num = f64>: Mapping<Domain, Codomain = F> { |
| 109 | 21 | /// Returns (a lower estimate of) the factor of strong convexity in the norm of `Domain`. |
| 108 | 22 | fn factor_of_strong_convexity(&self) -> F { |
| 23 | F::ZERO | |
| 24 | } | |
| 25 | } | |
| 58 | 26 | |
| 27 | /// Trait for mappings with a Fenchel conjugate | |
| 28 | /// | |
| 29 | /// The conjugate type has to implement [`ConvexMapping`], but a `Conjugable` mapping need | |
| 30 | /// not be convex. | |
|
107
441d30e66a4a
Missing restriction in Conjugable
Tuomo Valkonen <tuomov@iki.fi>
parents:
106
diff
changeset
|
31 | pub trait Conjugable<Domain: HasDual<F>, F: Num = f64>: Mapping<Domain, Codomain = F> { |
| 104 | 32 | type Conjugate<'a>: ConvexMapping<Domain::DualSpace, F> |
| 33 | where | |
| 34 | Self: 'a; | |
| 58 | 35 | |
| 36 | fn conjugate(&self) -> Self::Conjugate<'_>; | |
| 37 | } | |
| 38 | ||
| 39 | /// Trait for mappings with a Fenchel preconjugate | |
| 40 | /// | |
| 41 | /// In contrast to [`Conjugable`], the preconjugate need not implement [`ConvexMapping`], | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
42 | /// but a `Preconjugable` mapping has to be convex. |
| 104 | 43 | pub trait Preconjugable<Domain, Predual, F: Num = f64>: ConvexMapping<Domain, F> |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
44 | where |
| 163 | 45 | Domain: Space, |
| 104 | 46 | Predual: HasDual<F>, |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
47 | { |
|
107
441d30e66a4a
Missing restriction in Conjugable
Tuomo Valkonen <tuomov@iki.fi>
parents:
106
diff
changeset
|
48 | type Preconjugate<'a>: Mapping<Predual, Codomain = F> |
| 104 | 49 | where |
| 50 | Self: 'a; | |
| 58 | 51 | |
| 52 | fn preconjugate(&self) -> Self::Preconjugate<'_>; | |
| 53 | } | |
| 54 | ||
| 55 | /// Trait for mappings with a proximap map | |
| 56 | /// | |
| 57 | /// The conjugate type has to implement [`ConvexMapping`], but a `Conjugable` mapping need | |
| 58 | /// not be convex. | |
| 104 | 59 | pub trait Prox<Domain: Space>: Mapping<Domain> { |
| 164 | 60 | type Prox<'a>: Mapping<Domain, Codomain = Domain::Principal> |
| 104 | 61 | where |
| 62 | Self: 'a; | |
| 58 | 63 | |
| 64 | /// Returns a proximal mapping with weight τ | |
| 104 | 65 | fn prox_mapping(&self, τ: Self::Codomain) -> Self::Prox<'_>; |
| 58 | 66 | |
| 67 | /// Calculate the proximal mapping with weight τ | |
| 164 | 68 | fn prox<I: Instance<Domain>>(&self, τ: Self::Codomain, z: I) -> Domain::Principal { |
| 58 | 69 | self.prox_mapping(τ).apply(z) |
| 70 | } | |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
71 | |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
72 | /// Calculate the proximal mapping with weight τ in-place |
| 164 | 73 | fn prox_mut<'b>(&self, τ: Self::Codomain, y: &'b mut Domain::Principal) |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
74 | where |
| 104 | 75 | Domain::Decomp: DecompositionMut<Domain>, |
| 164 | 76 | for<'a> &'a Domain::Principal: Instance<Domain>, |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
77 | { |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
78 | *y = self.prox(τ, &*y); |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
79 | } |
| 58 | 80 | } |
| 81 | ||
| 88 | 82 | /// Constraint to the unit ball of the norm described by `E`. |
| 106 | 83 | #[derive(Copy, Clone, Debug, Serialize, Deserialize)] |
| 104 | 84 | pub struct NormConstraint<F: Float, E: NormExponent> { |
| 85 | radius: F, | |
| 86 | norm: NormMapping<F, E>, | |
| 72 | 87 | } |
| 88 | ||
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
89 | impl<Domain, E, F> ConvexMapping<Domain, F> for NormMapping<F, E> |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
90 | where |
| 163 | 91 | Domain: Space, |
| 104 | 92 | E: NormExponent, |
| 93 | F: Float, | |
| 94 | Self: Mapping<Domain, Codomain = F>, | |
| 95 | { | |
| 96 | } | |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
97 | |
| 72 | 98 | impl<F, E, Domain> Mapping<Domain> for NormConstraint<F, E> |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
99 | where |
| 163 | 100 | Domain: Space, |
| 164 | 101 | Domain::Principal: Norm<E, F>, |
| 104 | 102 | F: Float, |
| 103 | E: NormExponent, | |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
104 | { |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
105 | type Codomain = F; |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
106 | |
| 104 | 107 | fn apply<I: Instance<Domain>>(&self, d: I) -> F { |
| 72 | 108 | if d.eval(|x| x.norm(self.norm.exponent)) <= self.radius { |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
109 | F::ZERO |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
110 | } else { |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
111 | F::INFINITY |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
112 | } |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
113 | } |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
114 | } |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
115 | |
| 72 | 116 | impl<Domain, E, F> ConvexMapping<Domain, F> for NormConstraint<F, E> |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
117 | where |
| 163 | 118 | Domain: Space, |
| 104 | 119 | E: NormExponent, |
| 120 | F: Float, | |
| 121 | Self: Mapping<Domain, Codomain = F>, | |
| 122 | { | |
| 123 | } | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
124 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
125 | impl<E, F, Domain> Conjugable<Domain, F> for NormMapping<F, E> |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
126 | where |
| 104 | 127 | E: HasDualExponent, |
| 128 | F: Float, | |
| 163 | 129 | Domain: HasDual<F>, |
| 164 | 130 | Domain::Principal: Norm<E, F>, |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
112
diff
changeset
|
131 | <Domain as HasDual<F>>::DualSpace: Norm<E::DualExp, F>, |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
132 | { |
| 104 | 133 | type Conjugate<'a> |
| 134 | = NormConstraint<F, E::DualExp> | |
| 135 | where | |
| 136 | Self: 'a; | |
| 72 | 137 | |
| 138 | fn conjugate(&self) -> Self::Conjugate<'_> { | |
| 146 | 139 | NormConstraint { radius: F::ONE, norm: self.exponent.dual_exponent().as_mapping() } |
| 72 | 140 | } |
| 141 | } | |
| 142 | ||
| 143 | impl<C, E, F, Domain> Conjugable<Domain, F> for Weighted<NormMapping<F, E>, C> | |
| 144 | where | |
| 104 | 145 | C: Constant<Type = F>, |
| 146 | E: HasDualExponent, | |
| 147 | F: Float, | |
| 163 | 148 | Domain: HasDual<F>, |
| 164 | 149 | Domain::Principal: Norm<E, F>, |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
112
diff
changeset
|
150 | <Domain as HasDual<F>>::DualSpace: Norm<E::DualExp, F>, |
| 72 | 151 | { |
| 104 | 152 | type Conjugate<'a> |
| 153 | = NormConstraint<F, E::DualExp> | |
| 154 | where | |
| 155 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
156 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
157 | fn conjugate(&self) -> Self::Conjugate<'_> { |
| 72 | 158 | NormConstraint { |
| 104 | 159 | radius: self.weight.value(), |
| 160 | norm: self.base_fn.exponent.dual_exponent().as_mapping(), | |
| 72 | 161 | } |
| 162 | } | |
| 163 | } | |
| 164 | ||
| 165 | impl<Domain, E, F> Prox<Domain> for NormConstraint<F, E> | |
| 166 | where | |
| 163 | 167 | Domain: Space, |
| 164 | 168 | Domain::Principal: Norm<E, F>, |
| 104 | 169 | E: NormExponent, |
| 170 | F: Float, | |
| 164 | 171 | NormProjection<F, E>: Mapping<Domain, Codomain = Domain::Principal>, |
| 72 | 172 | { |
| 104 | 173 | type Prox<'a> |
| 174 | = NormProjection<F, E> | |
| 175 | where | |
| 176 | Self: 'a; | |
| 72 | 177 | |
| 178 | #[inline] | |
| 104 | 179 | fn prox_mapping(&self, _τ: Self::Codomain) -> Self::Prox<'_> { |
| 72 | 180 | assert!(self.radius >= F::ZERO); |
| 146 | 181 | NormProjection { radius: self.radius, exponent: self.norm.exponent } |
| 72 | 182 | } |
| 183 | } | |
| 184 | ||
| 88 | 185 | /// Projection to the unit ball of the norm described by `E`. |
| 106 | 186 | #[derive(Copy, Clone, Debug, Serialize, Deserialize)] |
| 104 | 187 | pub struct NormProjection<F: Float, E: NormExponent> { |
| 188 | radius: F, | |
| 189 | exponent: E, | |
| 72 | 190 | } |
| 191 | ||
| 192 | /* | |
| 193 | impl<F, Domain> Mapping<Domain> for NormProjection<F, L2> | |
| 194 | where | |
| 195 | Domain : Space + Euclidean<F> + std::ops::MulAssign<F>, | |
| 196 | F : Float, | |
| 197 | { | |
| 198 | type Codomain = Domain; | |
| 199 | ||
| 200 | fn apply<I : Instance<Domain>>(&self, d : I) -> Domain { | |
| 201 | d.own().proj_ball2(self.radius) | |
| 202 | } | |
| 203 | } | |
| 204 | */ | |
| 205 | ||
| 206 | impl<F, E, Domain> Mapping<Domain> for NormProjection<F, E> | |
| 207 | where | |
| 163 | 208 | Domain: Space, |
| 164 | 209 | Domain::Principal: ClosedSpace + Projection<F, E>, |
| 104 | 210 | F: Float, |
| 211 | E: NormExponent, | |
| 72 | 212 | { |
| 164 | 213 | type Codomain = Domain::Principal; |
| 72 | 214 | |
| 150 | 215 | fn apply<I: Instance<Domain>>(&self, d: I) -> Self::Codomain { |
| 72 | 216 | d.own().proj_ball(self.radius, self.exponent) |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
217 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
218 | } |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
219 | |
| 104 | 220 | /// The zero mapping |
| 106 | 221 | #[derive(Copy, Clone, Debug, Serialize, Deserialize)] |
| 104 | 222 | pub struct Zero<Domain: Space, F: Num>(PhantomData<(Domain, F)>); |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
223 | |
| 104 | 224 | impl<Domain: Space, F: Num> Zero<Domain, F> { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
225 | pub fn new() -> Self { |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
226 | Zero(PhantomData) |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
227 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
228 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
229 | |
| 104 | 230 | impl<Domain: Space, F: Num> Mapping<Domain> for Zero<Domain, F> { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
231 | type Codomain = F; |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
232 | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
233 | /// Compute the value of `self` at `x`. |
| 104 | 234 | fn apply<I: Instance<Domain>>(&self, _x: I) -> Self::Codomain { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
235 | F::ZERO |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
236 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
237 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
238 | |
| 163 | 239 | impl<Domain: Space, F: Float> ConvexMapping<Domain, F> for Zero<Domain, F> {} |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
240 | |
| 104 | 241 | impl<Domain: HasDual<F>, F: Float> Conjugable<Domain, F> for Zero<Domain, F> { |
| 242 | type Conjugate<'a> | |
| 243 | = ZeroIndicator<Domain::DualSpace, F> | |
| 244 | where | |
| 245 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
246 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
247 | #[inline] |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
248 | fn conjugate(&self) -> Self::Conjugate<'_> { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
249 | ZeroIndicator::new() |
|
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
250 | } |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
251 | } |
|
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
58
diff
changeset
|
252 | |
| 104 | 253 | impl<Domain, Predual, F: Float> Preconjugable<Domain, Predual, F> for Zero<Domain, F> |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
254 | where |
| 109 | 255 | Domain: Normed<F>, |
| 164 | 256 | Predual: HasDual<F, PrincipalV = Predual>, |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
257 | { |
| 104 | 258 | type Preconjugate<'a> |
| 259 | = ZeroIndicator<Predual, F> | |
| 260 | where | |
| 261 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
262 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
263 | #[inline] |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
264 | fn preconjugate(&self) -> Self::Preconjugate<'_> { |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
265 | ZeroIndicator::new() |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
266 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
267 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
268 | |
| 150 | 269 | impl<Domain: Space, F: Num> Prox<Domain> for Zero<Domain, F> { |
| 104 | 270 | type Prox<'a> |
| 271 | = IdOp<Domain> | |
| 272 | where | |
| 273 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
274 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
275 | #[inline] |
| 104 | 276 | fn prox_mapping(&self, _τ: Self::Codomain) -> Self::Prox<'_> { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
277 | IdOp::new() |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
278 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
279 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
280 | |
| 104 | 281 | /// The zero indicator |
| 106 | 282 | #[derive(Copy, Clone, Debug, Serialize, Deserialize)] |
| 104 | 283 | pub struct ZeroIndicator<Domain: Space, F: Num>(PhantomData<(Domain, F)>); |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
284 | |
| 104 | 285 | impl<Domain: Space, F: Num> ZeroIndicator<Domain, F> { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
286 | pub fn new() -> Self { |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
287 | ZeroIndicator(PhantomData) |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
288 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
289 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
290 | |
| 163 | 291 | impl<Domain, F> Mapping<Domain> for ZeroIndicator<Domain, F> |
| 292 | where | |
| 293 | F: Float, | |
| 294 | Domain: Space, | |
| 164 | 295 | Domain::Principal: Normed<F>, |
| 163 | 296 | { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
297 | type Codomain = F; |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
298 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
299 | /// Compute the value of `self` at `x`. |
| 104 | 300 | fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
301 | x.eval(|x̃| if x̃.is_zero() { F::ZERO } else { F::INFINITY }) |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
302 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
303 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
304 | |
| 163 | 305 | impl<Domain, F: Float> ConvexMapping<Domain, F> for ZeroIndicator<Domain, F> |
| 306 | where | |
| 307 | Domain: Space, | |
| 164 | 308 | Domain::Principal: Normed<F>, |
| 163 | 309 | { |
| 108 | 310 | fn factor_of_strong_convexity(&self) -> F { |
| 311 | F::INFINITY | |
| 312 | } | |
| 313 | } | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
314 | |
| 163 | 315 | impl<Domain, F: Float> Conjugable<Domain, F> for ZeroIndicator<Domain, F> |
| 316 | where | |
| 317 | Domain: HasDual<F>, | |
| 164 | 318 | Domain::PrincipalV: Normed<F>, |
| 163 | 319 | { |
| 104 | 320 | type Conjugate<'a> |
| 321 | = Zero<Domain::DualSpace, F> | |
| 322 | where | |
| 323 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
324 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
325 | #[inline] |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
326 | fn conjugate(&self) -> Self::Conjugate<'_> { |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
327 | Zero::new() |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
328 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
329 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
330 | |
| 104 | 331 | impl<Domain, Predual, F: Float> Preconjugable<Domain, Predual, F> for ZeroIndicator<Domain, F> |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
332 | where |
| 163 | 333 | Domain: Space, |
| 164 | 334 | Domain::Principal: Normed<F>, |
| 104 | 335 | Predual: HasDual<F>, |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
336 | { |
| 104 | 337 | type Preconjugate<'a> |
| 338 | = Zero<Predual, F> | |
| 339 | where | |
| 340 | Self: 'a; | |
|
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
341 | |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
342 | #[inline] |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
343 | fn preconjugate(&self) -> Self::Preconjugate<'_> { |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
344 | Zero::new() |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
345 | } |
|
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
346 | } |
| 104 | 347 | |
|
129
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
348 | impl<Domain, F> Prox<Domain> for ZeroIndicator<Domain, F> |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
349 | where |
| 164 | 350 | Domain: AXPY<Field = F, PrincipalV = Domain> + Normed<F>, |
|
129
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
351 | F: Float, |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
352 | { |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
353 | type Prox<'a> |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
354 | = SimpleZeroOp |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
355 | where |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
356 | Self: 'a; |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
357 | |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
358 | /// Returns a proximal mapping with weight τ |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
359 | fn prox_mapping(&self, _τ: F) -> Self::Prox<'_> { |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
360 | return SimpleZeroOp; |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
361 | } |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
362 | } |
|
d2994e34a5f5
Simplify ZeroOp to SimpleZeroOp, only from X to X. Add Prox for ZeroIndicator. Move F parameter to AXPY::Field.
Tuomo Valkonen <tuomov@iki.fi>
parents:
124
diff
changeset
|
363 | |
| 104 | 364 | /// The squared Euclidean norm divided by two |
| 106 | 365 | #[derive(Copy, Clone, Serialize, Deserialize)] |
| 105 | 366 | pub struct Norm222<F: Float>(PhantomData<F>); |
| 104 | 367 | |
| 105 | 368 | impl</*Domain: Euclidean<F>,*/ F: Float> Norm222<F> { |
| 104 | 369 | pub fn new() -> Self { |
| 370 | Norm222(PhantomData) | |
| 371 | } | |
| 372 | } | |
| 373 | ||
| 112 | 374 | impl<X: Euclidean<F>, F: Float> Mapping<X> for Norm222<F> { |
| 104 | 375 | type Codomain = F; |
| 376 | ||
| 377 | /// Compute the value of `self` at `x`. | |
| 112 | 378 | fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { |
| 104 | 379 | x.eval(|z| z.norm2_squared() / F::TWO) |
| 380 | } | |
| 381 | } | |
| 382 | ||
| 112 | 383 | impl<X: Euclidean<F>, F: Float> ConvexMapping<X, F> for Norm222<F> { |
| 108 | 384 | fn factor_of_strong_convexity(&self) -> F { |
| 385 | F::ONE | |
| 386 | } | |
| 387 | } | |
| 104 | 388 | |
| 112 | 389 | impl<X: Euclidean<F>, F: Float> Conjugable<X, F> for Norm222<F> { |
| 104 | 390 | type Conjugate<'a> |
| 391 | = Self | |
| 392 | where | |
| 393 | Self: 'a; | |
| 394 | ||
| 395 | #[inline] | |
| 396 | fn conjugate(&self) -> Self::Conjugate<'_> { | |
| 397 | Self::new() | |
| 398 | } | |
| 399 | } | |
| 400 | ||
| 112 | 401 | impl<X: Euclidean<F>, F: Float> Preconjugable<X, X, F> for Norm222<F> { |
| 104 | 402 | type Preconjugate<'a> |
| 403 | = Self | |
| 404 | where | |
| 405 | Self: 'a; | |
| 406 | ||
| 407 | #[inline] | |
| 408 | fn preconjugate(&self) -> Self::Preconjugate<'_> { | |
| 409 | Self::new() | |
| 410 | } | |
| 411 | } | |
| 412 | ||
| 112 | 413 | impl<X, F> Prox<X> for Norm222<F> |
| 104 | 414 | where |
| 415 | F: Float, | |
| 151 | 416 | X: Euclidean<F>, |
| 104 | 417 | { |
| 418 | type Prox<'a> | |
| 419 | = Scaled<F> | |
| 420 | where | |
| 421 | Self: 'a; | |
| 422 | ||
| 423 | fn prox_mapping(&self, τ: F) -> Self::Prox<'_> { | |
| 424 | Scaled(F::ONE / (F::ONE + τ)) | |
| 425 | } | |
| 426 | } | |
| 112 | 427 | |
| 428 | impl<X, F> DifferentiableImpl<X> for Norm222<F> | |
| 429 | where | |
| 430 | F: Float, | |
| 150 | 431 | X: Euclidean<F>, |
| 112 | 432 | { |
| 164 | 433 | type Derivative = X::PrincipalV; |
| 112 | 434 | |
| 150 | 435 | fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative { |
| 168 | 436 | x.own() |
| 112 | 437 | } |
| 438 | } | |
| 439 | ||
| 440 | impl<X, F> LipschitzDifferentiableImpl<X, L2> for Norm222<F> | |
| 441 | where | |
| 442 | F: Float, | |
| 150 | 443 | X: Euclidean<F>, |
| 112 | 444 | { |
| 445 | type FloatType = F; | |
| 446 | ||
| 447 | fn diff_lipschitz_factor(&self, _: L2) -> DynResult<Self::FloatType> { | |
| 448 | Ok(F::ONE) | |
| 449 | } | |
| 450 | } |