1 /*! |
1 /*! |
2 Norms, projections, etc. |
2 Norms, projections, etc. |
3 */ |
3 */ |
4 |
4 |
5 use serde::Serialize; |
5 use serde::Serialize; |
|
6 use std::marker::PhantomData; |
6 use crate::types::*; |
7 use crate::types::*; |
7 use crate::euclidean::*; |
8 use crate::euclidean::*; |
|
9 use crate::mapping::{Mapping, Space, Instance}; |
8 |
10 |
9 // |
11 // |
10 // Abstract norms |
12 // Abstract norms |
11 // |
13 // |
12 |
14 |
|
15 #[derive(Copy,Clone,Debug)] |
|
16 /// Helper structure to convert a [`NormExponent`] into a [`Mapping`] |
|
17 pub struct NormMapping<F : Float, E : NormExponent>{ |
|
18 pub(crate) exponent : E, |
|
19 _phantoms : PhantomData<F> |
|
20 } |
|
21 |
13 /// An exponent for norms. |
22 /// An exponent for norms. |
14 /// |
23 /// |
15 // Just a collection of desirable attributes for a marker type |
24 // Just a collection of desirable attributes for a marker type |
16 pub trait NormExponent : Copy + Send + Sync + 'static {} |
25 pub trait NormExponent : Copy + Send + Sync + 'static { |
17 |
26 /// Return the norm as a mappin |
|
27 fn as_mapping<F : Float>(self) -> NormMapping<F, Self> { |
|
28 NormMapping{ exponent : self, _phantoms : PhantomData } |
|
29 } |
|
30 } |
18 |
31 |
19 /// Exponent type for the 1-[`Norm`]. |
32 /// Exponent type for the 1-[`Norm`]. |
20 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
33 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
21 pub struct L1; |
34 pub struct L1; |
22 impl NormExponent for L1 {} |
35 impl NormExponent for L1 {} |
34 /// Exponent type for 2,1-[`Norm`]. |
47 /// Exponent type for 2,1-[`Norm`]. |
35 /// (1-norm over a domain Ω, 2-norm of a vector at each point of the domain.) |
48 /// (1-norm over a domain Ω, 2-norm of a vector at each point of the domain.) |
36 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
49 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
37 pub struct L21; |
50 pub struct L21; |
38 impl NormExponent for L21 {} |
51 impl NormExponent for L21 {} |
|
52 |
|
53 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J |
|
54 /// For use with [`crate::direct_product::Pair`] |
|
55 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
|
56 pub struct PairNorm<A, B, J>(pub A, pub B, pub J); |
|
57 |
|
58 impl<A, B, J> NormExponent for PairNorm<A, B, J> |
|
59 where A : NormExponent, B : NormExponent, J : NormExponent {} |
|
60 |
39 |
61 |
40 /// A Huber/Moreau–Yosida smoothed [`L1`] norm. (Not a norm itself.) |
62 /// A Huber/Moreau–Yosida smoothed [`L1`] norm. (Not a norm itself.) |
41 /// |
63 /// |
42 /// The parameter γ of this type is the smoothing factor. Zero means no smoothing, and higher |
64 /// The parameter γ of this type is the smoothing factor. Zero means no smoothing, and higher |
43 /// values more smoothing. Behaviour with γ < 0 is undefined. |
65 /// values more smoothing. Behaviour with γ < 0 is undefined. |
152 fn dist(&self, other : &Self, huber : HuberL1<F>) -> F { |
174 fn dist(&self, other : &Self, huber : HuberL1<F>) -> F { |
153 huber.apply(self.dist2_squared(other)) |
175 huber.apply(self.dist2_squared(other)) |
154 } |
176 } |
155 } |
177 } |
156 |
178 |
|
179 impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { |
|
180 fn norm(&self, _l21 : L21) -> F { |
|
181 self.iter().map(|e| e.norm(L2)).sum() |
|
182 } |
|
183 } |
|
184 |
|
185 impl<F : Float, E : Dist<F, L2>> Dist<F, L21> for Vec<E> { |
|
186 fn dist(&self, other : &Self, _l21 : L21) -> F { |
|
187 self.iter().zip(other.iter()).map(|(e, g)| e.dist(g, L2)).sum() |
|
188 } |
|
189 } |
|
190 |
|
191 impl<E, F, Domain> Mapping<Domain> for NormMapping<F, E> |
|
192 where |
|
193 F : Float, |
|
194 E : NormExponent, |
|
195 Domain : Space + Norm<F, E>, |
|
196 { |
|
197 type Codomain = F; |
|
198 |
|
199 #[inline] |
|
200 fn apply<I : Instance<Domain>>(&self, x : I) -> F { |
|
201 x.eval(|r| r.norm(self.exponent)) |
|
202 } |
|
203 } |
|
204 |