5 use serde::Serialize; |
5 use serde::Serialize; |
6 use std::marker::PhantomData; |
6 use std::marker::PhantomData; |
7 use crate::types::*; |
7 use crate::types::*; |
8 use crate::euclidean::*; |
8 use crate::euclidean::*; |
9 use crate::mapping::{Mapping, Space, Instance}; |
9 use crate::mapping::{Mapping, Space, Instance}; |
|
10 use crate::operator_arithmetic::{Constant, Weighted}; |
10 |
11 |
11 // |
12 // |
12 // Abstract norms |
13 // Abstract norms |
13 // |
14 // |
14 |
15 |
47 /// Exponent type for 2,1-[`Norm`]. |
48 /// Exponent type for 2,1-[`Norm`]. |
48 /// (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.) |
49 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
50 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
50 pub struct L21; |
51 pub struct L21; |
51 impl NormExponent for L21 {} |
52 impl NormExponent for L21 {} |
|
53 |
|
54 impl<C : Constant, E : NormExponent> NormExponent for Weighted<E, C> {} |
52 |
55 |
53 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J |
56 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J |
54 /// For use with [`crate::direct_product::Pair`] |
57 /// For use with [`crate::direct_product::Pair`] |
55 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
58 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] |
56 pub struct PairNorm<A, B, J>(pub A, pub B, pub J); |
59 pub struct PairNorm<A, B, J>(pub A, pub B, pub J); |
174 fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F { |
177 fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F { |
175 huber.apply(self.dist2_squared(other)) |
178 huber.apply(self.dist2_squared(other)) |
176 } |
179 } |
177 } |
180 } |
178 |
181 |
|
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 |
179 // impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { |
196 // impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { |
180 // fn norm(&self, _l21 : L21) -> F { |
197 // fn norm(&self, _l21 : L21) -> F { |
181 // self.iter().map(|e| e.norm(L2)).sum() |
198 // self.iter().map(|e| e.norm(L2)).sum() |
182 // } |
199 // } |
183 // } |
200 // } |
264 fn dual_exponent(&self) -> Self::DualExp { |
281 fn dual_exponent(&self) -> Self::DualExp { |
265 L1 |
282 L1 |
266 } |
283 } |
267 } |
284 } |
268 |
285 |
269 |
286 impl<C : Constant, E : HasDualExponent> HasDualExponent for Weighted<E, C> { |
270 |
287 type DualExp = Weighted<E::DualExp, C::Type>; |
271 |
288 |
|
289 fn dual_exponent(&self) -> Self::DualExp { |
|
290 Weighted { |
|
291 weight : C::Type::ONE / self.weight.value(), |
|
292 base_fn : self.base_fn.dual_exponent() |
|
293 } |
|
294 } |
|
295 } |
|
296 |
|
297 impl<C, F, E, T> Projection<F, Weighted<E, C>> for T |
|
298 where |
|
299 T : Projection<F, E>, |
|
300 F : Float, |
|
301 C : Constant<Type = F>, |
|
302 E : NormExponent, |
|
303 { |
|
304 fn proj_ball(self, ρ : F, q : Weighted<E, C>) -> Self { |
|
305 self.proj_ball(ρ / q.weight.value(), q.base_fn) |
|
306 } |
|
307 |
|
308 fn proj_ball_mut(&mut self, ρ : F, q : Weighted<E, C>) { |
|
309 self.proj_ball_mut(ρ / q.weight.value(), q.base_fn) |
|
310 } |
|
311 } |