src/kernels/ball_indicator.rs

branch
dev
changeset 35
b087e3eab191
parent 0
eb3c7813b67a
child 38
0f59c0d02e13
equal deleted inserted replaced
34:efa60bc4f743 35:b087e3eab191
1 1
2 //! Implementation of the indicator function of a ball with respect to various norms. 2 //! Implementation of the indicator function of a ball with respect to various norms.
3 use float_extras::f64::{tgamma as gamma}; 3 use float_extras::f64::tgamma as gamma;
4 use numeric_literals::replace_float_literals; 4 use numeric_literals::replace_float_literals;
5 use serde::Serialize; 5 use serde::Serialize;
6 use alg_tools::types::*; 6 use alg_tools::types::*;
7 use alg_tools::norms::*; 7 use alg_tools::norms::*;
8 use alg_tools::loc::Loc; 8 use alg_tools::loc::Loc;
12 Constant, 12 Constant,
13 Bounds, 13 Bounds,
14 LocalAnalysis, 14 LocalAnalysis,
15 GlobalAnalysis, 15 GlobalAnalysis,
16 }; 16 };
17 use alg_tools::mapping::Apply; 17 use alg_tools::mapping::{
18 Mapping,
19 Differential,
20 DifferentiableImpl,
21 };
22 use alg_tools::instance::Instance;
23 use alg_tools::euclidean::StaticEuclidean;
18 use alg_tools::maputil::array_init; 24 use alg_tools::maputil::array_init;
19 use alg_tools::coefficients::factorial; 25 use alg_tools::coefficients::factorial;
20 26 use crate::types::*;
21 use super::base::*; 27 use super::base::*;
22 28
23 /// Representation of the indicator of the ball $𝔹_q = \\{ x ∈ ℝ^N \mid \\|x\\|\_q ≤ r \\}$, 29 /// Representation of the indicator of the ball $𝔹_q = \\{ x ∈ ℝ^N \mid \\|x\\|\_q ≤ r \\}$,
24 /// where $q$ is the `Exponent`, and $r$ is the radius [`Constant`] `C`. 30 /// where $q$ is the `Exponent`, and $r$ is the radius [`Constant`] `C`.
25 #[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] 31 #[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)]
34 /// $𝔹_∞ = \\{ x ∈ ℝ^N \mid \\|x\\|\_∞ ≤ c \\}$. 40 /// $𝔹_∞ = \\{ x ∈ ℝ^N \mid \\|x\\|\_∞ ≤ c \\}$.
35 pub type CubeIndicator<C, const N : usize> = BallIndicator<C, Linfinity, N>; 41 pub type CubeIndicator<C, const N : usize> = BallIndicator<C, Linfinity, N>;
36 42
37 #[replace_float_literals(C::Type::cast_from(literal))] 43 #[replace_float_literals(C::Type::cast_from(literal))]
38 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize> 44 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
39 Apply<&'a Loc<C::Type, N>> 45 Mapping<Loc<C::Type, N>>
40 for BallIndicator<C, Exponent, N> 46 for BallIndicator<C, Exponent, N>
41 where Loc<F, N> : Norm<F, Exponent> { 47 where
42 type Output = C::Type; 48 Loc<F, N> : Norm<F, Exponent>
43 #[inline] 49 {
44 fn apply(&self, x : &'a Loc<C::Type, N>) -> Self::Output { 50 type Codomain = C::Type;
51
52 #[inline]
53 fn apply<I : Instance<Loc<C::Type, N>>>(&self, x : I) -> Self::Codomain {
45 let r = self.r.value(); 54 let r = self.r.value();
46 let n = x.norm(self.exponent); 55 let n = x.eval(|x| x.norm(self.exponent));
47 if n <= r { 56 if n <= r {
48 1.0 57 1.0
49 } else { 58 } else {
50 0.0 59 0.0
51 } 60 }
52 } 61 }
53 } 62 }
54 63
64 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
65 DifferentiableImpl<Loc<C::Type, N>>
66 for BallIndicator<C, Exponent, N>
67 where
68 C : Constant,
69 Loc<F, N> : Norm<F, Exponent>
70 {
71 type Derivative = Loc<C::Type, N>;
72
73 #[inline]
74 fn differential_impl<I : Instance<Loc<C::Type, N>>>(&self, _x : I) -> Self::Derivative {
75 Self::Derivative::origin()
76 }
77 }
78
55 impl<F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize> 79 impl<F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
56 Apply<Loc<C::Type, N>> 80 Lipschitz<L2>
57 for BallIndicator<C, Exponent, N> 81 for BallIndicator<C, Exponent, N>
58 where Loc<F, N> : Norm<F, Exponent> { 82 where C : Constant,
59 type Output = C::Type; 83 Loc<F, N> : Norm<F, Exponent> {
60 #[inline] 84 type FloatType = C::Type;
61 fn apply(&self, x : Loc<C::Type, N>) -> Self::Output { 85
62 self.apply(&x) 86 fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
87 None
88 }
89 }
90
91 impl<'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
92 Lipschitz<L2>
93 for Differential<'b, Loc<F, N>, BallIndicator<C, Exponent, N>>
94 where C : Constant,
95 Loc<F, N> : Norm<F, Exponent> {
96 type FloatType = C::Type;
97
98 fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
99 None
100 }
101 }
102
103 impl<'a, 'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
104 Lipschitz<L2>
105 for Differential<'b, Loc<F, N>, &'a BallIndicator<C, Exponent, N>>
106 where C : Constant,
107 Loc<F, N> : Norm<F, Exponent> {
108 type FloatType = C::Type;
109
110 fn lipschitz_factor(&self, _l2 : L2) -> Option<C::Type> {
111 None
112 }
113 }
114
115
116 impl<'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
117 NormBounded<L2>
118 for Differential<'b, Loc<F, N>, BallIndicator<C, Exponent, N>>
119 where C : Constant,
120 Loc<F, N> : Norm<F, Exponent> {
121 type FloatType = C::Type;
122
123 fn norm_bound(&self, _l2 : L2) -> C::Type {
124 F::INFINITY
125 }
126 }
127
128 impl<'a, 'b, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
129 NormBounded<L2>
130 for Differential<'b, Loc<F, N>, &'a BallIndicator<C, Exponent, N>>
131 where C : Constant,
132 Loc<F, N> : Norm<F, Exponent> {
133 type FloatType = C::Type;
134
135 fn norm_bound(&self, _l2 : L2) -> C::Type {
136 F::INFINITY
63 } 137 }
64 } 138 }
65 139
66 140
67 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize> 141 impl<'a, F : Float, C : Constant<Type=F>, Exponent : NormExponent, const N : usize>
186 indicator_local_analysis!(L2); 260 indicator_local_analysis!(L2);
187 indicator_local_analysis!(Linfinity); 261 indicator_local_analysis!(Linfinity);
188 262
189 263
190 #[replace_float_literals(F::cast_from(literal))] 264 #[replace_float_literals(F::cast_from(literal))]
191 impl<'a, F : Float, R, const N : usize> Apply<&'a Loc<F, N>> 265 impl<'a, F : Float, R, const N : usize> Mapping<Loc<F, N>>
192 for AutoConvolution<CubeIndicator<R, N>> 266 for AutoConvolution<CubeIndicator<R, N>>
193 where R : Constant<Type=F> { 267 where R : Constant<Type=F> {
194 type Output = F; 268 type Codomain = F;
195 269
196 #[inline] 270 #[inline]
197 fn apply(&self, y : &'a Loc<F, N>) -> F { 271 fn apply<I : Instance<Loc<F, N>>>(&self, y : I) -> F {
198 let two_r = 2.0 * self.0.r.value(); 272 let two_r = 2.0 * self.0.r.value();
199 // This is just a product of one-dimensional versions 273 // This is just a product of one-dimensional versions
200 y.iter().map(|&x| { 274 y.cow().iter().map(|&x| {
201 0.0.max(two_r - x.abs()) 275 0.0.max(two_r - x.abs())
202 }).product() 276 }).product()
203 }
204 }
205
206 impl<F : Float, R, const N : usize> Apply<Loc<F, N>>
207 for AutoConvolution<CubeIndicator<R, N>>
208 where R : Constant<Type=F> {
209 type Output = F;
210
211 #[inline]
212 fn apply(&self, y : Loc<F, N>) -> F {
213 self.apply(&y)
214 } 277 }
215 } 278 }
216 279
217 #[replace_float_literals(F::cast_from(literal))] 280 #[replace_float_literals(F::cast_from(literal))]
218 impl<F : Float, R, const N : usize> Support<F, N> 281 impl<F : Float, R, const N : usize> Support<F, N>

mercurial