src/kernels/ball_indicator.rs

branch
dev
changeset 35
b087e3eab191
parent 0
eb3c7813b67a
child 38
0f59c0d02e13
--- a/src/kernels/ball_indicator.rs	Thu Aug 29 00:00:00 2024 -0500
+++ b/src/kernels/ball_indicator.rs	Tue Dec 31 09:25:45 2024 -0500
@@ -1,6 +1,6 @@
 
 //! Implementation of the indicator function of a ball with respect to various norms.
-use float_extras::f64::{tgamma as gamma};
+use float_extras::f64::tgamma as gamma;
 use numeric_literals::replace_float_literals;
 use serde::Serialize;
 use alg_tools::types::*;
@@ -14,10 +14,16 @@
     LocalAnalysis,
     GlobalAnalysis,
 };
-use alg_tools::mapping::Apply;
+use alg_tools::mapping::{
+    Mapping,
+    Differential,
+    DifferentiableImpl,
+};
+use alg_tools::instance::Instance;
+use alg_tools::euclidean::StaticEuclidean;
 use alg_tools::maputil::array_init;
 use alg_tools::coefficients::factorial;
-
+use crate::types::*;
 use super::base::*;
 
 /// Representation of the indicator of the ball $𝔹_q = \\{ x ∈ ℝ^N \mid \\|x\\|\_q ≤ r \\}$,
@@ -36,14 +42,17 @@
 
 #[replace_float_literals(C::Type::cast_from(literal))]
 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
-Apply<&'a Loc<C::Type, N>>
+Mapping<Loc<C::Type, N>>
 for BallIndicator<C, Exponent, N>
-where Loc<F, N> : Norm<F, Exponent> {
-    type Output = C::Type;
+where
+    Loc<F, N> : Norm<F, Exponent>
+{
+    type Codomain = C::Type;
+
     #[inline]
-    fn apply(&self, x : &'a Loc<C::Type, N>) -> Self::Output {
+    fn apply<I : Instance<Loc<C::Type, N>>>(&self, x : I) -> Self::Codomain {
         let r = self.r.value();
-        let n = x.norm(self.exponent);
+        let n = x.eval(|x| x.norm(self.exponent));
         if n <= r {
             1.0
         } else {
@@ -52,14 +61,79 @@
     }
 }
 
+impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
+DifferentiableImpl<Loc<C::Type, N>>
+for BallIndicator<C, Exponent, N>
+where
+    C : Constant,
+     Loc<F, N> : Norm<F, Exponent>
+{
+    type Derivative = Loc<C::Type, N>;
+
+    #[inline]
+    fn differential_impl<I : Instance<Loc<C::Type, N>>>(&self, _x : I) -> Self::Derivative {
+        Self::Derivative::origin()
+    }
+}
+
 impl<F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
-Apply<Loc<C::Type, N>>
+Lipschitz<L2>
 for BallIndicator<C, Exponent, N>
-where Loc<F, N> : Norm<F, Exponent> {
-    type Output = C::Type;
-    #[inline]
-    fn apply(&self, x : Loc<C::Type, N>) -> Self::Output {
-        self.apply(&x)
+where C : Constant,
+      Loc<F, N> : Norm<F, Exponent> {
+    type FloatType = C::Type;
+
+    fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
+        None
+    }
+}
+
+impl<'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
+Lipschitz<L2>
+for Differential<'b, Loc<F, N>, BallIndicator<C, Exponent, N>>
+where C : Constant,
+      Loc<F, N> : Norm<F, Exponent> {
+    type FloatType = C::Type;
+
+    fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
+        None
+    }
+}
+
+impl<'a, 'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
+Lipschitz<L2>
+for Differential<'b, Loc<F, N>, &'a BallIndicator<C, Exponent, N>>
+where C : Constant,
+      Loc<F, N> : Norm<F, Exponent> {
+    type FloatType = C::Type;
+
+    fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
+        None
+    }
+}
+
+
+impl<'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
+NormBounded<L2>
+for Differential<'b, Loc<F, N>, BallIndicator<C, Exponent, N>>
+where C : Constant,
+      Loc<F, N> : Norm<F, Exponent> {
+    type FloatType = C::Type;
+
+    fn norm_bound(&self, _l2 : L2) -> C::Type {
+        F::INFINITY
+    }
+}
+
+impl<'a, 'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
+NormBounded<L2>
+for Differential<'b, Loc<F, N>, &'a BallIndicator<C, Exponent, N>>
+where C : Constant,
+      Loc<F, N> : Norm<F, Exponent> {
+    type FloatType = C::Type;
+
+    fn norm_bound(&self, _l2 : L2) -> C::Type {
+        F::INFINITY
     }
 }
 
@@ -188,32 +262,21 @@
 
 
 #[replace_float_literals(F::cast_from(literal))]
-impl<'a, F : Float, R, const N : usize> Apply<&'a Loc<F, N>>
+impl<'a, F : Float, R, const N : usize> Mapping<Loc<F, N>>
 for AutoConvolution<CubeIndicator<R, N>>
 where R : Constant<Type=F> {
-    type Output = F;
+    type Codomain = F;
 
     #[inline]
-    fn apply(&self, y : &'a Loc<F, N>) -> F {
+    fn apply<I : Instance<Loc<F, N>>>(&self, y : I) -> F {
         let two_r = 2.0 * self.0.r.value();
         // This is just a product of one-dimensional versions
-        y.iter().map(|&x| {
+        y.cow().iter().map(|&x| {
             0.0.max(two_r - x.abs())
         }).product()
     }
 }
 
-impl<F : Float, R, const N : usize> Apply<Loc<F, N>>
-for AutoConvolution<CubeIndicator<R, N>>
-where R : Constant<Type=F> {
-    type Output = F;
-
-    #[inline]
-    fn apply(&self, y : Loc<F, N>) -> F {
-        self.apply(&y)
-    }
-}
-
 #[replace_float_literals(F::cast_from(literal))]
 impl<F : Float, R, const N : usize> Support<F, N>
 for AutoConvolution<CubeIndicator<R, N>>

mercurial