1 /*! |
1 /*! |
2 Implementations of the distance function and the distance function squared, on manifolds. |
2 Implementations of the distance function and the distance function squared, on manifolds. |
3 */ |
3 */ |
4 |
4 |
5 use alg_tools::mapping::Apply; |
5 use alg_tools::mapping::Apply; |
|
6 use alg_tools::euclidean::Euclidean; |
6 use crate::manifold::ManifoldPoint; |
7 use crate::manifold::ManifoldPoint; |
7 use crate::fb::{Grad, Desc}; |
8 use crate::fb::{Grad, Desc, Prox}; |
8 |
9 |
9 /// Structure for distance-to functions |
10 /// Structure for distance-to functions |
10 pub struct DistTo<M : ManifoldPoint>(pub M); |
11 pub struct DistTo<M : ManifoldPoint>(pub M); |
11 |
12 |
12 impl<M : ManifoldPoint> Apply<M> for DistTo<M> { |
13 impl<M : ManifoldPoint> Apply<M> for DistTo<M> { |
56 impl<M : ManifoldPoint> Grad<M> for DistToSquaredDiv2<M> { |
57 impl<M : ManifoldPoint> Grad<M> for DistToSquaredDiv2<M> { |
57 fn grad(&self, x : &M) -> M::Tangent { |
58 fn grad(&self, x : &M) -> M::Tangent { |
58 x.log(&self.0) |
59 x.log(&self.0) |
59 } |
60 } |
60 } |
61 } |
|
62 |
|
63 impl<M : ManifoldPoint> Prox<M> for DistTo<M> { |
|
64 /// This is proximal map is a type of soft-thresholding on manifolds. |
|
65 fn prox(&self, τ : f64, x : M) -> M { |
|
66 let v = x.log(&self.0); |
|
67 let d = v.norm2(); |
|
68 if d <= τ { |
|
69 self.0.clone() |
|
70 } else { |
|
71 x.exp( &(v * (τ / d)) ) |
|
72 } |
|
73 } |
|
74 } |