13 use crate::euclidean::{Dot, Euclidean}; |
13 use crate::euclidean::{Dot, Euclidean}; |
14 use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow}; |
14 use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow}; |
15 use crate::mapping::Space; |
15 use crate::mapping::Space; |
16 use crate::linops::AXPY; |
16 use crate::linops::AXPY; |
17 use crate::loc::Loc; |
17 use crate::loc::Loc; |
18 use crate::norms::{Norm, PairNorm, NormExponent}; |
18 use crate::norms::{Norm, PairNorm, NormExponent, Normed, HasDual, L2}; |
19 |
19 |
20 #[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)] |
20 #[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)] |
21 pub struct Pair<A, B> (pub A, pub B); |
21 pub struct Pair<A, B> (pub A, pub B); |
22 |
22 |
23 impl<A, B> Pair<A,B> { |
23 impl<A, B> Pair<A,B> { |
466 Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj) |
466 Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj) |
467 } |
467 } |
468 } |
468 } |
469 |
469 |
470 |
470 |
|
471 impl<F : Float, A, B> Normed<F> for Pair<A,B> |
|
472 where |
|
473 A : Normed<F>, |
|
474 B : Normed<F>, |
|
475 { |
|
476 type NormExp = PairNorm<A::NormExp, B::NormExp, L2>; |
|
477 |
|
478 #[inline] |
|
479 fn norm_exponent(&self) -> Self::NormExp { |
|
480 PairNorm(self.0.norm_exponent(), self.1.norm_exponent(), L2) |
|
481 } |
|
482 |
|
483 #[inline] |
|
484 fn is_zero(&self) -> bool { |
|
485 self.0.is_zero() && self.1.is_zero() |
|
486 } |
|
487 } |
|
488 |
|
489 impl<F : Float, A, B> HasDual<F> for Pair<A,B> |
|
490 where |
|
491 A : HasDual<F>, |
|
492 B : HasDual<F>, |
|
493 |
|
494 { |
|
495 type DualSpace = Pair<A::DualSpace, B::DualSpace>; |
|
496 } |