48 /// Exponent type for 2,1-[`Norm`]. |
48 /// Exponent type for 2,1-[`Norm`]. |
49 /// (1-norm over a domain Ω, 2-norm of a vector at each point of the domain.) |
49 /// (1-norm over a domain Ω, 2-norm of a vector at each point of the domain.) |
50 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
50 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
51 pub struct L21; |
51 pub struct L21; |
52 impl NormExponent for L21 {} |
52 impl NormExponent for L21 {} |
53 |
|
54 impl<C : Constant, E : NormExponent> NormExponent for Weighted<E, C> {} |
|
55 |
53 |
56 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J |
54 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J |
57 /// For use with [`crate::direct_product::Pair`] |
55 /// For use with [`crate::direct_product::Pair`] |
58 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
56 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
59 pub struct PairNorm<A, B, J>(pub A, pub B, pub J); |
57 pub struct PairNorm<A, B, J>(pub A, pub B, pub J); |
177 fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F { |
175 fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F { |
178 huber.apply(self.dist2_squared(other)) |
176 huber.apply(self.dist2_squared(other)) |
179 } |
177 } |
180 } |
178 } |
181 |
179 |
182 impl<C, F, E, D> Norm<F, Weighted<E, C>> for D |
|
183 where |
|
184 F : Float, |
|
185 D : Norm<F, E>, |
|
186 C : Constant<Type = F>, |
|
187 E : NormExponent, |
|
188 { |
|
189 fn norm(&self, e : Weighted<E, C>) -> F { |
|
190 let v = e.weight.value(); |
|
191 assert!(v > F::ZERO); |
|
192 v * self.norm(e.base_fn) |
|
193 } |
|
194 } |
|
195 |
|
196 // impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { |
180 // impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { |
197 // fn norm(&self, _l21 : L21) -> F { |
181 // fn norm(&self, _l21 : L21) -> F { |
198 // self.iter().map(|e| e.norm(L2)).sum() |
182 // self.iter().map(|e| e.norm(L2)).sum() |
199 // } |
183 // } |
200 // } |
184 // } |
281 fn dual_exponent(&self) -> Self::DualExp { |
265 fn dual_exponent(&self) -> Self::DualExp { |
282 L1 |
266 L1 |
283 } |
267 } |
284 } |
268 } |
285 |
269 |
286 impl<C : Constant, E : HasDualExponent> HasDualExponent for Weighted<E, C> { |
270 #[macro_export] |
287 type DualExp = Weighted<E::DualExp, C::Type>; |
271 macro_rules! impl_weighted_norm { |
288 |
272 ($exponent : ty) => { |
289 fn dual_exponent(&self) -> Self::DualExp { |
273 impl<C, F, D> Norm<F, Weighted<$exponent, C>> for D |
290 Weighted { |
274 where |
291 weight : C::Type::ONE / self.weight.value(), |
275 F : Float, |
292 base_fn : self.base_fn.dual_exponent() |
276 D : Norm<F, $exponent>, |
|
277 C : Constant<Type = F>, |
|
278 { |
|
279 fn norm(&self, e : Weighted<$exponent, C>) -> F { |
|
280 let v = e.weight.value(); |
|
281 assert!(v > F::ZERO); |
|
282 v * self.norm(e.base_fn) |
|
283 } |
293 } |
284 } |
294 } |
285 |
295 } |
286 impl<C : Constant> NormExponent for Weighted<$exponent, C> {} |
296 |
287 |
297 impl<C, F, E, T> Projection<F, Weighted<E, C>> for T |
288 impl<C : Constant> HasDualExponent for Weighted<$exponent, C> |
298 where |
289 where $exponent : HasDualExponent { |
299 T : Projection<F, E>, |
290 type DualExp = Weighted<<$exponent as HasDualExponent>::DualExp, C::Type>; |
300 F : Float, |
291 |
301 C : Constant<Type = F>, |
292 fn dual_exponent(&self) -> Self::DualExp { |
302 E : NormExponent, |
293 Weighted { |
303 { |
294 weight : C::Type::ONE / self.weight.value(), |
304 fn proj_ball(self, ρ : F, q : Weighted<E, C>) -> Self { |
295 base_fn : self.base_fn.dual_exponent() |
305 self.proj_ball(ρ / q.weight.value(), q.base_fn) |
296 } |
306 } |
297 } |
307 |
298 } |
308 fn proj_ball_mut(&mut self, ρ : F, q : Weighted<E, C>) { |
299 |
309 self.proj_ball_mut(ρ / q.weight.value(), q.base_fn) |
300 impl<C, F, T> Projection<F, Weighted<$exponent , C>> for T |
310 } |
301 where |
311 } |
302 T : Projection<F, $exponent >, |
|
303 F : Float, |
|
304 C : Constant<Type = F>, |
|
305 { |
|
306 fn proj_ball(self, ρ : F, q : Weighted<$exponent , C>) -> Self { |
|
307 self.proj_ball(ρ / q.weight.value(), q.base_fn) |
|
308 } |
|
309 |
|
310 fn proj_ball_mut(&mut self, ρ : F, q : Weighted<$exponent , C>) { |
|
311 self.proj_ball_mut(ρ / q.weight.value(), q.base_fn) |
|
312 } |
|
313 } |
|
314 } |
|
315 } |
|
316 |
|
317 //impl_weighted_norm!(L1); |
|
318 //impl_weighted_norm!(L2); |
|
319 //impl_weighted_norm!(Linfinity); |
|
320 |