--- a/src/kernels/linear.rs Sun Apr 27 15:03:51 2025 -0500 +++ b/src/kernels/linear.rs Thu Feb 26 11:38:43 2026 -0500 @@ -1,94 +1,82 @@ //! Implementation of the linear function +use alg_tools::bisection_tree::Support; +use alg_tools::bounds::{Bounded, Bounds, GlobalAnalysis, LocalAnalysis}; +use alg_tools::loc::Loc; +use alg_tools::norms::*; +use alg_tools::sets::Cube; +use alg_tools::types::*; 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::euclidean::Euclidean; +use alg_tools::mapping::{Instance, Mapping}; 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> { +#[derive(Copy, Clone, Serialize, Debug, Eq, PartialEq)] +pub struct Linear<const N: usize, F: Float = f64> { /// The parameter $ε>0$. - pub v : Loc<F, N>, + pub v: Loc<N, F>, } #[replace_float_literals(F::cast_from(literal))] -impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Linear<F, N> { +impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Linear<N, F> { type Codomain = F; #[inline] - fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { + fn apply<I: Instance<Loc<N, F>>>(&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> { +impl<'a, F: Float, const N: usize> Support<N, F> for Linear<N, F> { #[inline] - fn support_hint(&self) -> Cube<F,N> { + fn support_hint(&self) -> Cube<N, F> { array_init(|| [F::NEG_INFINITY, F::INFINITY]).into() } #[inline] - fn in_support(&self, _x : &Loc<F,N>) -> bool { + fn in_support(&self, _x: &Loc<N, F>) -> 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] { + fn bisection_hint(&self, _cube: &Cube<N, F>) -> [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> { +impl<'a, F: Float, const N: usize> GlobalAnalysis<F, Bounds<F>> for Linear<N, F> { #[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> { +impl<'a, F: Float, const N: usize> LocalAnalysis<F, Bounds<F>, N> for Linear<N, F> { #[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)) - }); + fn local_analysis(&self, cube: &Cube<N, F>) -> 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> { +impl<'a, F: Float, const N: usize> Norm<Linfinity, F> for Linear<N, F> { #[inline] - fn norm(&self, _ : Linfinity) -> F { + fn norm(&self, _: Linfinity) -> F { self.bounds().upper() } } -