src/norms.rs

branch
dev
changeset 70
672aec2e1acd
parent 64
4f6ca107ccb1
child 71
511bf440e24b
equal deleted inserted replaced
69:e5fab0125a8e 70:672aec2e1acd
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 }

mercurial