| 12 Bounds, |
12 Bounds, |
| 13 LocalAnalysis, |
13 LocalAnalysis, |
| 14 GlobalAnalysis, |
14 GlobalAnalysis, |
| 15 Bounded, |
15 Bounded, |
| 16 }; |
16 }; |
| 17 use alg_tools::mapping::Apply; |
17 use alg_tools::mapping::{Mapping, Instance}; |
| 18 use alg_tools::maputil::{array_init}; |
18 use alg_tools::maputil::array_init; |
| |
19 use crate::types::Lipschitz; |
| 19 |
20 |
| 20 /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. |
21 /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. |
| 21 #[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] |
22 #[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] |
| 22 pub struct Hat<C : Constant, const N : usize> { |
23 pub struct Hat<C : Constant, const N : usize> { |
| 23 /// The parameter $ε>0$. |
24 /// The parameter $ε>0$. |
| 24 pub width : C, |
25 pub width : C, |
| 25 } |
26 } |
| 26 |
27 |
| 27 #[replace_float_literals(C::Type::cast_from(literal))] |
28 #[replace_float_literals(C::Type::cast_from(literal))] |
| 28 impl<'a, C : Constant, const N : usize> Apply<&'a Loc<C::Type, N>> for Hat<C, N> { |
29 impl<'a, C : Constant, const N : usize> Mapping<Loc<C::Type, N>> for Hat<C, N> { |
| 29 type Output = C::Type; |
30 type Codomain = C::Type; |
| |
31 |
| 30 #[inline] |
32 #[inline] |
| 31 fn apply(&self, x : &'a Loc<C::Type, N>) -> Self::Output { |
33 fn apply<I : Instance<Loc<C::Type, N>>>(&self, x : I) -> Self::Codomain { |
| 32 let ε = self.width.value(); |
34 let ε = self.width.value(); |
| 33 0.0.max(1.0-x.norm(L1)/ε) |
35 0.0.max(1.0-x.cow().norm(L1)/ε) |
| 34 } |
36 } |
| 35 } |
37 } |
| 36 |
|
| 37 #[replace_float_literals(C::Type::cast_from(literal))] |
|
| 38 impl<C : Constant, const N : usize> Apply<Loc<C::Type, N>> for Hat<C, N> { |
|
| 39 type Output = C::Type; |
|
| 40 #[inline] |
|
| 41 fn apply(&self, x : Loc<C::Type, N>) -> Self::Output { |
|
| 42 self.apply(&x) |
|
| 43 } |
|
| 44 } |
|
| 45 |
|
| 46 |
38 |
| 47 #[replace_float_literals(C::Type::cast_from(literal))] |
39 #[replace_float_literals(C::Type::cast_from(literal))] |
| 48 impl<'a, C : Constant, const N : usize> Support<C::Type, N> for Hat<C, N> { |
40 impl<'a, C : Constant, const N : usize> Support<C::Type, N> for Hat<C, N> { |
| 49 #[inline] |
41 #[inline] |
| 50 fn support_hint(&self) -> Cube<C::Type,N> { |
42 fn support_hint(&self) -> Cube<C::Type,N> { |
| 92 fn global_analysis(&self) -> Bounds<C::Type> { |
84 fn global_analysis(&self) -> Bounds<C::Type> { |
| 93 Bounds(0.0, 1.0) |
85 Bounds(0.0, 1.0) |
| 94 } |
86 } |
| 95 } |
87 } |
| 96 |
88 |
| |
89 #[replace_float_literals(C::Type::cast_from(literal))] |
| |
90 impl<'a, C : Constant, const N : usize> Lipschitz<L1> for Hat<C, N> { |
| |
91 type FloatType = C::Type; |
| |
92 |
| |
93 fn lipschitz_factor(&self, _l1 : L1) -> Option<C::Type> { |
| |
94 Some(1.0/self.width.value()) |
| |
95 } |
| |
96 } |
| |
97 |
| |
98 #[replace_float_literals(C::Type::cast_from(literal))] |
| |
99 impl<'a, C : Constant, const N : usize> Lipschitz<L2> for Hat<C, N> { |
| |
100 type FloatType = C::Type; |
| |
101 |
| |
102 fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> { |
| |
103 self.lipschitz_factor(L1).map(|l1| |
| |
104 <L2 as Dominated<C::Type, L1, Loc<C::Type,N>>>::from_norm(&L2, l1, L1) |
| |
105 ) |
| |
106 } |
| |
107 } |
| |
108 |
| 97 impl<'a, C : Constant, const N : usize> |
109 impl<'a, C : Constant, const N : usize> |
| 98 LocalAnalysis<C::Type, Bounds<C::Type>, N> |
110 LocalAnalysis<C::Type, Bounds<C::Type>, N> |
| 99 for Hat<C, N> { |
111 for Hat<C, N> { |
| 100 #[inline] |
112 #[inline] |
| 101 fn local_analysis(&self, cube : &Cube<C::Type, N>) -> Bounds<C::Type> { |
113 fn local_analysis(&self, cube : &Cube<C::Type, N>) -> Bounds<C::Type> { |