| 1 //! Implementation of the linear function |
1 //! Implementation of the linear function |
| 2 |
2 |
| |
3 use alg_tools::bisection_tree::Support; |
| |
4 use alg_tools::bounds::{Bounded, Bounds, GlobalAnalysis, LocalAnalysis}; |
| |
5 use alg_tools::loc::Loc; |
| |
6 use alg_tools::norms::*; |
| |
7 use alg_tools::sets::Cube; |
| |
8 use alg_tools::types::*; |
| 3 use numeric_literals::replace_float_literals; |
9 use numeric_literals::replace_float_literals; |
| 4 use serde::Serialize; |
10 use serde::Serialize; |
| 5 use alg_tools::types::*; |
11 |
| 6 use alg_tools::norms::*; |
12 use alg_tools::euclidean::Euclidean; |
| 7 use alg_tools::loc::Loc; |
13 use alg_tools::mapping::{Instance, Mapping}; |
| 8 use alg_tools::sets::Cube; |
|
| 9 use alg_tools::bisection_tree::{ |
|
| 10 Support, |
|
| 11 Bounds, |
|
| 12 LocalAnalysis, |
|
| 13 GlobalAnalysis, |
|
| 14 Bounded, |
|
| 15 }; |
|
| 16 use alg_tools::mapping::{Mapping, Instance}; |
|
| 17 use alg_tools::maputil::array_init; |
14 use alg_tools::maputil::array_init; |
| 18 use alg_tools::euclidean::Euclidean; |
|
| 19 |
15 |
| 20 /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. |
16 /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. |
| 21 #[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] |
17 #[derive(Copy, Clone, Serialize, Debug, Eq, PartialEq)] |
| 22 pub struct Linear<F : Float, const N : usize> { |
18 pub struct Linear<const N: usize, F: Float = f64> { |
| 23 /// The parameter $ε>0$. |
19 /// The parameter $ε>0$. |
| 24 pub v : Loc<F, N>, |
20 pub v: Loc<N, F>, |
| 25 } |
21 } |
| 26 |
22 |
| 27 #[replace_float_literals(F::cast_from(literal))] |
23 #[replace_float_literals(F::cast_from(literal))] |
| 28 impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Linear<F, N> { |
24 impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Linear<N, F> { |
| 29 type Codomain = F; |
25 type Codomain = F; |
| 30 |
26 |
| 31 #[inline] |
27 #[inline] |
| 32 fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { |
28 fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain { |
| 33 x.eval(|x| self.v.dot(x)) |
29 x.eval(|x| self.v.dot(x)) |
| 34 } |
30 } |
| 35 } |
31 } |
| 36 |
32 |
| 37 |
|
| 38 #[replace_float_literals(F::cast_from(literal))] |
33 #[replace_float_literals(F::cast_from(literal))] |
| 39 impl<'a, F : Float, const N : usize> Support<F, N> for Linear<F, N> { |
34 impl<'a, F: Float, const N: usize> Support<N, F> for Linear<N, F> { |
| 40 #[inline] |
35 #[inline] |
| 41 fn support_hint(&self) -> Cube<F,N> { |
36 fn support_hint(&self) -> Cube<N, F> { |
| 42 array_init(|| [F::NEG_INFINITY, F::INFINITY]).into() |
37 array_init(|| [F::NEG_INFINITY, F::INFINITY]).into() |
| 43 } |
38 } |
| 44 |
39 |
| 45 #[inline] |
40 #[inline] |
| 46 fn in_support(&self, _x : &Loc<F,N>) -> bool { |
41 fn in_support(&self, _x: &Loc<N, F>) -> bool { |
| 47 true |
42 true |
| 48 } |
43 } |
| 49 |
44 |
| 50 /*fn fully_in_support(&self, _cube : &Cube<F,N>) -> bool { |
45 /*fn fully_in_support(&self, _cube : &Cube<F,N>) -> bool { |
| 51 todo!("Not implemented, but not used at the moment") |
46 todo!("Not implemented, but not used at the moment") |
| 52 }*/ |
47 }*/ |
| 53 |
48 |
| 54 #[inline] |
49 #[inline] |
| 55 fn bisection_hint(&self, _cube : &Cube<F,N>) -> [Option<F>; N] { |
50 fn bisection_hint(&self, _cube: &Cube<N, F>) -> [Option<F>; N] { |
| 56 [None; N] |
51 [None; N] |
| 57 } |
52 } |
| 58 } |
53 } |
| 59 |
54 |
| 60 |
|
| 61 #[replace_float_literals(F::cast_from(literal))] |
55 #[replace_float_literals(F::cast_from(literal))] |
| 62 impl<'a, F : Float, const N : usize> |
56 impl<'a, F: Float, const N: usize> GlobalAnalysis<F, Bounds<F>> for Linear<N, F> { |
| 63 GlobalAnalysis<F, Bounds<F>> |
|
| 64 for Linear<F, N> { |
|
| 65 #[inline] |
57 #[inline] |
| 66 fn global_analysis(&self) -> Bounds<F> { |
58 fn global_analysis(&self) -> Bounds<F> { |
| 67 Bounds(F::NEG_INFINITY, F::INFINITY) |
59 Bounds(F::NEG_INFINITY, F::INFINITY) |
| 68 } |
60 } |
| 69 } |
61 } |
| 70 |
62 |
| 71 impl<'a, F : Float, const N : usize> |
63 impl<'a, F: Float, const N: usize> LocalAnalysis<F, Bounds<F>, N> for Linear<N, F> { |
| 72 LocalAnalysis<F, Bounds<F>, N> |
|
| 73 for Linear<F, N> { |
|
| 74 #[inline] |
64 #[inline] |
| 75 fn local_analysis(&self, cube : &Cube<F, N>) -> Bounds<F> { |
65 fn local_analysis(&self, cube: &Cube<N, F>) -> Bounds<F> { |
| 76 let (lower, upper) = cube.iter_corners() |
66 let (lower, upper) = cube |
| 77 .map(|x| self.apply(x)) |
67 .iter_corners() |
| 78 .fold((F::INFINITY, F::NEG_INFINITY), |(lower, upper), v| { |
68 .map(|x| self.apply(x)) |
| 79 (lower.min(v), upper.max(v)) |
69 .fold((F::INFINITY, F::NEG_INFINITY), |(lower, upper), v| { |
| 80 }); |
70 (lower.min(v), upper.max(v)) |
| |
71 }); |
| 81 Bounds(lower, upper) |
72 Bounds(lower, upper) |
| 82 } |
73 } |
| 83 } |
74 } |
| 84 |
75 |
| 85 #[replace_float_literals(F::cast_from(literal))] |
76 #[replace_float_literals(F::cast_from(literal))] |
| 86 impl<'a, F : Float, const N : usize> |
77 impl<'a, F: Float, const N: usize> Norm<Linfinity, F> for Linear<N, F> { |
| 87 Norm<F, Linfinity> |
|
| 88 for Linear<F, N> { |
|
| 89 #[inline] |
78 #[inline] |
| 90 fn norm(&self, _ : Linfinity) -> F { |
79 fn norm(&self, _: Linfinity) -> F { |
| 91 self.bounds().upper() |
80 self.bounds().upper() |
| 92 } |
81 } |
| 93 } |
82 } |
| 94 |
|