src/kernels/linear.rs

Thu, 06 Feb 2025 23:52:22 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 06 Feb 2025 23:52:22 -0500
branch
dev
changeset 47
4a6b803d8aca
parent 35
b087e3eab191
child 38
0f59c0d02e13
permissions
-rw-r--r--

radon rearrangements

//! 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