diff -r efa60bc4f743 -r b087e3eab191 src/kernels/ball_indicator.rs --- 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, Exponent : NormExponent, const N : usize> -Apply<&'a Loc> +Mapping> for BallIndicator -where Loc : Norm { - type Output = C::Type; +where + Loc : Norm +{ + type Codomain = C::Type; + #[inline] - fn apply(&self, x : &'a Loc) -> Self::Output { + fn apply>>(&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, Exponent : NormExponent, const N : usize> +DifferentiableImpl> +for BallIndicator +where + C : Constant, + Loc : Norm +{ + type Derivative = Loc; + + #[inline] + fn differential_impl>>(&self, _x : I) -> Self::Derivative { + Self::Derivative::origin() + } +} + impl, Exponent : NormExponent, const N : usize> -Apply> +Lipschitz for BallIndicator -where Loc : Norm { - type Output = C::Type; - #[inline] - fn apply(&self, x : Loc) -> Self::Output { - self.apply(&x) +where C : Constant, + Loc : Norm { + type FloatType = C::Type; + + fn lipschitz_factor(&self, _l2 : L2) -> Option { + None + } +} + +impl<'b, F : Float, C : Constant, Exponent : NormExponent, const N : usize> +Lipschitz +for Differential<'b, Loc, BallIndicator> +where C : Constant, + Loc : Norm { + type FloatType = C::Type; + + fn lipschitz_factor(&self, _l2 : L2) -> Option { + None + } +} + +impl<'a, 'b, F : Float, C : Constant, Exponent : NormExponent, const N : usize> +Lipschitz +for Differential<'b, Loc, &'a BallIndicator> +where C : Constant, + Loc : Norm { + type FloatType = C::Type; + + fn lipschitz_factor(&self, _l2 : L2) -> Option { + None + } +} + + +impl<'b, F : Float, C : Constant, Exponent : NormExponent, const N : usize> +NormBounded +for Differential<'b, Loc, BallIndicator> +where C : Constant, + Loc : Norm { + type FloatType = C::Type; + + fn norm_bound(&self, _l2 : L2) -> C::Type { + F::INFINITY + } +} + +impl<'a, 'b, F : Float, C : Constant, Exponent : NormExponent, const N : usize> +NormBounded +for Differential<'b, Loc, &'a BallIndicator> +where C : Constant, + Loc : Norm { + 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> +impl<'a, F : Float, R, const N : usize> Mapping> for AutoConvolution> where R : Constant { - type Output = F; + type Codomain = F; #[inline] - fn apply(&self, y : &'a Loc) -> F { + fn apply>>(&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 Apply> -for AutoConvolution> -where R : Constant { - type Output = F; - - #[inline] - fn apply(&self, y : Loc) -> F { - self.apply(&y) - } -} - #[replace_float_literals(F::cast_from(literal))] impl Support for AutoConvolution>