|
1 /*! |
|
2 Implementation of scaling of functions on a manifold by a scalar. |
|
3 */ |
|
4 |
|
5 use alg_tools::mapping::Apply; |
|
6 use crate::manifold::ManifoldPoint; |
|
7 use crate::fb::{Grad, Desc, Prox}; |
|
8 |
|
9 /// Structure for a function of type `G`, scaled by a scalar. |
|
10 pub struct Scaled<G> { |
|
11 α : f64, |
|
12 g : G, |
|
13 } |
|
14 |
|
15 impl<G> Scaled<G> { |
|
16 #[allow(dead_code)] |
|
17 pub fn new(α : f64, g : G) -> Self { |
|
18 Scaled{ α, g } |
|
19 } |
|
20 } |
|
21 |
|
22 impl<M, G : Apply<M, Output=f64>> Apply<M> for Scaled< G> { |
|
23 type Output = f64; |
|
24 |
|
25 fn apply(&self, x : M) -> Self::Output { |
|
26 self.g.apply(x) * self.α |
|
27 } |
|
28 } |
|
29 |
|
30 impl<M : ManifoldPoint, G : Desc<M>> Desc<M> for Scaled<G> { |
|
31 fn desc(&self, τ : f64, x : M) -> M { |
|
32 self.g.desc(τ * self.α, x) |
|
33 } |
|
34 } |
|
35 |
|
36 impl<M : ManifoldPoint, G : Grad<M>> Grad<M> for Scaled<G> { |
|
37 fn grad(&self, x : &M) -> M::Tangent { |
|
38 self.g.grad(x) * self.α |
|
39 } |
|
40 } |
|
41 |
|
42 impl<M : ManifoldPoint, G : Prox<M>> Prox<M> for Scaled<G> { |
|
43 fn prox(&self, τ : f64, x : M) -> M { |
|
44 self.g.prox(τ * self.α, x) |
|
45 } |
|
46 } |