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