| 14 |
14 |
| 15 /// Trait for convex mappings. Has no features, just serves as a constraint |
15 /// Trait for convex mappings. Has no features, just serves as a constraint |
| 16 /// |
16 /// |
| 17 /// TODO: should constrain `Mapping::Codomain` to implement a partial order, |
17 /// TODO: should constrain `Mapping::Codomain` to implement a partial order, |
| 18 /// but this makes everything complicated with little benefit. |
18 /// but this makes everything complicated with little benefit. |
| 19 pub trait ConvexMapping<Domain: Space, F: Num = f64>: Mapping<Domain, Codomain = F> {} |
19 pub trait ConvexMapping<Domain: Space, F: Num = f64>: Mapping<Domain, Codomain = F> { |
| |
20 /// Returns (a lower estimate of) the factor of strong convexity. |
| |
21 /// |
| |
22 /// TODO: should include a specification of the respective norm. |
| |
23 fn factor_of_strong_convexity(&self) -> F { |
| |
24 F::ZERO |
| |
25 } |
| |
26 } |
| 20 |
27 |
| 21 /// Trait for mappings with a Fenchel conjugate |
28 /// Trait for mappings with a Fenchel conjugate |
| 22 /// |
29 /// |
| 23 /// The conjugate type has to implement [`ConvexMapping`], but a `Conjugable` mapping need |
30 /// The conjugate type has to implement [`ConvexMapping`], but a `Conjugable` mapping need |
| 24 /// not be convex. |
31 /// not be convex. |
| 291 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { |
298 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { |
| 292 x.eval(|x̃| if x̃.is_zero() { F::ZERO } else { F::INFINITY }) |
299 x.eval(|x̃| if x̃.is_zero() { F::ZERO } else { F::INFINITY }) |
| 293 } |
300 } |
| 294 } |
301 } |
| 295 |
302 |
| 296 impl<Domain: Normed<F>, F: Float> ConvexMapping<Domain, F> for ZeroIndicator<Domain, F> {} |
303 impl<Domain: Normed<F>, F: Float> ConvexMapping<Domain, F> for ZeroIndicator<Domain, F> { |
| |
304 fn factor_of_strong_convexity(&self) -> F { |
| |
305 F::INFINITY |
| |
306 } |
| |
307 } |
| 297 |
308 |
| 298 impl<Domain: HasDual<F>, F: Float> Conjugable<Domain, F> for ZeroIndicator<Domain, F> { |
309 impl<Domain: HasDual<F>, F: Float> Conjugable<Domain, F> for ZeroIndicator<Domain, F> { |
| 299 type Conjugate<'a> |
310 type Conjugate<'a> |
| 300 = Zero<Domain::DualSpace, F> |
311 = Zero<Domain::DualSpace, F> |
| 301 where |
312 where |
| 340 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { |
351 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { |
| 341 x.eval(|z| z.norm2_squared() / F::TWO) |
352 x.eval(|z| z.norm2_squared() / F::TWO) |
| 342 } |
353 } |
| 343 } |
354 } |
| 344 |
355 |
| 345 impl<Domain: Euclidean<F>, F: Float> ConvexMapping<Domain, F> for Norm222<F> {} |
356 impl<Domain: Euclidean<F>, F: Float> ConvexMapping<Domain, F> for Norm222<F> { |
| |
357 fn factor_of_strong_convexity(&self) -> F { |
| |
358 F::ONE |
| |
359 } |
| |
360 } |
| 346 |
361 |
| 347 impl<Domain: Euclidean<F>, F: Float> Conjugable<Domain, F> for Norm222<F> { |
362 impl<Domain: Euclidean<F>, F: Float> Conjugable<Domain, F> for Norm222<F> { |
| 348 type Conjugate<'a> |
363 type Conjugate<'a> |
| 349 = Self |
364 = Self |
| 350 where |
365 where |