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> { |