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