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