src/kernels/linear.rs

branch
dev
changeset 61
4f468d35fa29
parent 35
b087e3eab191
equal deleted inserted replaced
60:9738b51d90d7 61:4f468d35fa29
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

mercurial