src/kernels/linear.rs

branch
dev
changeset 35
b087e3eab191
child 38
0f59c0d02e13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernels/linear.rs	Tue Dec 31 09:25:45 2024 -0500
@@ -0,0 +1,94 @@
+//! Implementation of the linear function
+
+use numeric_literals::replace_float_literals;
+use serde::Serialize;
+use alg_tools::types::*;
+use alg_tools::norms::*;
+use alg_tools::loc::Loc;
+use alg_tools::sets::Cube;
+use alg_tools::bisection_tree::{
+    Support,
+    Bounds,
+    LocalAnalysis,
+    GlobalAnalysis,
+    Bounded,
+};
+use alg_tools::mapping::{Mapping, Instance};
+use alg_tools::maputil::array_init;
+use alg_tools::euclidean::Euclidean;
+
+/// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$.
+#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)]
+pub struct Linear<F : Float, const N : usize> {
+    /// The parameter $ε>0$.
+    pub v : Loc<F, N>,
+}
+
+#[replace_float_literals(F::cast_from(literal))]
+impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Linear<F, N> {
+    type Codomain = F;
+
+    #[inline]
+    fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
+        x.eval(|x| self.v.dot(x))
+    }
+}
+
+
+#[replace_float_literals(F::cast_from(literal))]
+impl<'a, F : Float, const N : usize> Support<F, N> for Linear<F, N> {
+    #[inline]
+    fn support_hint(&self) -> Cube<F,N> {
+        array_init(|| [F::NEG_INFINITY, F::INFINITY]).into()
+    }
+
+    #[inline]
+    fn in_support(&self, _x : &Loc<F,N>) -> bool {
+        true
+    }
+    
+    /*fn fully_in_support(&self, _cube : &Cube<F,N>) -> bool {
+        todo!("Not implemented, but not used at the moment")
+    }*/
+
+    #[inline]
+    fn bisection_hint(&self, _cube : &Cube<F,N>) -> [Option<F>; N] {
+        [None; N]
+    }
+}
+
+
+#[replace_float_literals(F::cast_from(literal))]
+impl<'a, F : Float, const N : usize>
+GlobalAnalysis<F, Bounds<F>>
+for Linear<F, N> {
+    #[inline]
+    fn global_analysis(&self) -> Bounds<F> {
+        Bounds(F::NEG_INFINITY, F::INFINITY)
+    }
+}
+
+impl<'a, F : Float, const N : usize>
+LocalAnalysis<F, Bounds<F>, N>
+for Linear<F, N> {
+    #[inline]
+    fn local_analysis(&self, cube : &Cube<F, N>) -> Bounds<F> {
+        let (lower, upper) = cube.iter_corners()
+                                 .map(|x| self.apply(x))
+                                 .fold((F::INFINITY, F::NEG_INFINITY), |(lower, upper), v| {
+                                      (lower.min(v), upper.max(v))
+                                 });
+        Bounds(lower, upper)
+    }
+}
+
+#[replace_float_literals(F::cast_from(literal))]
+impl<'a, F : Float, const N : usize>
+Norm<F, Linfinity>
+for Linear<F, N> {
+    #[inline]
+    fn norm(&self, _ : Linfinity) -> F {
+        self.bounds().upper()
+    }
+}
+

mercurial