src/direct_product.rs

branch
dev
changeset 59
9226980e45a7
parent 57
1b3b1687b9ed
child 60
848ecc05becf
equal deleted inserted replaced
58:1a38447a89fa 59:9226980e45a7
7 7
8 use core::ops::{Mul,MulAssign,Div,DivAssign,Add,AddAssign,Sub,SubAssign,Neg}; 8 use core::ops::{Mul,MulAssign,Div,DivAssign,Add,AddAssign,Sub,SubAssign,Neg};
9 use std::clone::Clone; 9 use std::clone::Clone;
10 use serde::{Serialize, Deserialize}; 10 use serde::{Serialize, Deserialize};
11 use crate::types::{Num, Float}; 11 use crate::types::{Num, Float};
12 use crate::{maybe_lifetime, maybe_ref, impl_vectorspace_ops}; 12 use crate::{maybe_lifetime, maybe_ref};
13 use crate::euclidean::{Dot, Euclidean}; 13 use crate::euclidean::{Dot, Euclidean};
14 14 use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow};
15 #[derive(Debug,Clone,PartialEq,Eq,Serialize,Deserialize)] 15 use crate::mapping::Space;
16 use crate::linops::AXPY;
17 use crate::loc::Loc;
18 use crate::norms::{Norm, PairNorm, NormExponent};
19
20 #[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)]
16 pub struct Pair<A, B> (pub A, pub B); 21 pub struct Pair<A, B> (pub A, pub B);
17 22
18 impl<A, B> Pair<A,B> { 23 impl<A, B> Pair<A,B> {
19 pub fn new(a : A, b : B) -> Pair<A,B> { Pair{ 0 : a, 1 : b } } 24 pub fn new(a : A, b : B) -> Pair<A,B> { Pair(a, b) }
20 } 25 }
21 26
22 impl<A, B> From<(A,B)> for Pair<A,B> { 27 impl<A, B> From<(A,B)> for Pair<A,B> {
23 #[inline] 28 #[inline]
24 fn from((a, b) : (A, B)) -> Pair<A,B> { Pair{ 0 : a, 1 : b } } 29 fn from((a, b) : (A, B)) -> Pair<A,B> { Pair(a, b) }
30 }
31
32 impl<A, B> From<Pair<A,B>> for (A,B) {
33 #[inline]
34 fn from(Pair(a, b) : Pair<A, B>) -> (A,B) { (a, b) }
25 } 35 }
26 36
27 macro_rules! impl_binop { 37 macro_rules! impl_binop {
28 ($trait : ident, $fn : ident, $refl:ident, $refr:ident) => { 38 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refl:ident, $refr:ident) => {
29 impl_binop!(@doit: $trait, $fn; 39 impl_binop!(@doit: $a, $b, $trait, $fn;
30 maybe_lifetime!($refl, &'l Pair<A,B>), 40 maybe_lifetime!($refl, &'l Pair<$a,$b>),
31 (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B)); 41 (maybe_lifetime!($refl, &'l $a),
42 maybe_lifetime!($refl, &'l $b));
32 maybe_lifetime!($refr, &'r Pair<Ai,Bi>), 43 maybe_lifetime!($refr, &'r Pair<Ai,Bi>),
33 (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi)); 44 (maybe_lifetime!($refr, &'r Ai),
45 maybe_lifetime!($refr, &'r Bi));
34 $refl, $refr); 46 $refl, $refr);
35 }; 47 };
36 48
37 (@doit: $trait:ident, $fn:ident; 49 (@doit: $a:ty, $b:ty,
50 $trait:ident, $fn:ident;
38 $self:ty, ($aself:ty, $bself:ty); 51 $self:ty, ($aself:ty, $bself:ty);
39 $in:ty, ($ain:ty, $bin:ty); 52 $in:ty, ($ain:ty, $bin:ty);
40 $refl:ident, $refr:ident) => { 53 $refl:ident, $refr:ident) => {
41 impl<'l, 'r, A, B, Ai, Bi> $trait<$in> 54 impl<'l, 'r, Ai, Bi> $trait<$in>
42 for $self 55 for $self
43 where $aself: $trait<$ain>, 56 where $aself: $trait<$ain>,
44 $bself: $trait<$bin> { 57 $bself: $trait<$bin> {
45 type Output = Pair<<$aself as $trait<$ain>>::Output, 58 type Output = Pair<<$aself as $trait<$ain>>::Output,
46 <$bself as $trait<$bin>>::Output>; 59 <$bself as $trait<$bin>>::Output>;
47 60
48 #[inline] 61 #[inline]
49 fn $fn(self, y : $in) -> Self::Output { 62 fn $fn(self, y : $in) -> Self::Output {
50 Pair { 0 : maybe_ref!($refl, self.0).$fn(maybe_ref!($refr, y.0)), 63 Pair(maybe_ref!($refl, self.0).$fn(maybe_ref!($refr, y.0)),
51 1 : maybe_ref!($refl, self.1).$fn(maybe_ref!($refr, y.1)) } 64 maybe_ref!($refl, self.1).$fn(maybe_ref!($refr, y.1)))
52 } 65 }
53 } 66 }
54 }; 67 };
55 } 68 }
56 69
57 macro_rules! impl_assignop { 70 macro_rules! impl_assignop {
58 ($trait : ident, $fn : ident, $refr:ident) => { 71 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refr:ident) => {
59 impl_assignop!(@doit: $trait, $fn; 72 impl_assignop!(@doit: $a, $b,
73 $trait, $fn;
60 maybe_lifetime!($refr, &'r Pair<Ai,Bi>), 74 maybe_lifetime!($refr, &'r Pair<Ai,Bi>),
61 (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi)); 75 (maybe_lifetime!($refr, &'r Ai),
76 maybe_lifetime!($refr, &'r Bi));
62 $refr); 77 $refr);
63 }; 78 };
64 (@doit: $trait:ident, $fn:ident; 79 (@doit: $a : ty, $b : ty,
80 $trait:ident, $fn:ident;
65 $in:ty, ($ain:ty, $bin:ty); 81 $in:ty, ($ain:ty, $bin:ty);
66 $refr:ident) => { 82 $refr:ident) => {
67 impl<'r, A, B, Ai, Bi> $trait<$in> 83 impl<'r, Ai, Bi> $trait<$in>
68 for Pair<A,B> 84 for Pair<$a,$b>
69 where A: $trait<$ain>, 85 where $a: $trait<$ain>,
70 B: $trait<$bin> { 86 $b: $trait<$bin> {
71 #[inline] 87 #[inline]
72 fn $fn(&mut self, y : $in) -> () { 88 fn $fn(&mut self, y : $in) -> () {
73 self.0.$fn(maybe_ref!($refr, y.0)); 89 self.0.$fn(maybe_ref!($refr, y.0));
74 self.1.$fn(maybe_ref!($refr, y.1)); 90 self.1.$fn(maybe_ref!($refr, y.1));
75 } 91 }
76 } 92 }
77 } 93 }
78 } 94 }
79 95
80 macro_rules! impl_scalarop { 96 macro_rules! impl_scalarop {
81 ($trait : ident, $fn : ident, $refl:ident) => { 97 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident, $refl:ident) => {
82 impl_scalarop!(@doit: $trait, $fn; 98 impl_scalarop!(@doit: $field,
83 maybe_lifetime!($refl, &'l Pair<A,B>), 99 $trait, $fn;
84 (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B)); 100 maybe_lifetime!($refl, &'l Pair<$a,$b>),
101 (maybe_lifetime!($refl, &'l $a),
102 maybe_lifetime!($refl, &'l $b));
85 $refl); 103 $refl);
86 }; 104 };
87 (@doit: $trait:ident, $fn:ident; 105 (@doit: $field : ty,
106 $trait:ident, $fn:ident;
88 $self:ty, ($aself:ty, $bself:ty); 107 $self:ty, ($aself:ty, $bself:ty);
89 $refl:ident) => { 108 $refl:ident) => {
90 // Scalar as Rhs 109 // Scalar as Rhs
91 impl<'l, F : Num, A, B> $trait<F> 110 impl<'l> $trait<$field>
92 for $self 111 for $self
93 where $aself: $trait<F>, 112 where $aself: $trait<$field>,
94 $bself: $trait<F> { 113 $bself: $trait<$field> {
95 type Output = Pair<<$aself as $trait<F>>::Output, 114 type Output = Pair<<$aself as $trait<$field>>::Output,
96 <$bself as $trait<F>>::Output>; 115 <$bself as $trait<$field>>::Output>;
97 #[inline] 116 #[inline]
98 fn $fn(self, a : F) -> Self::Output { 117 fn $fn(self, a : $field) -> Self::Output {
99 Pair{ 0 : maybe_ref!($refl, self.0).$fn(a), 118 Pair(maybe_ref!($refl, self.0).$fn(a),
100 1 : maybe_ref!($refl, self.1).$fn(a)} 119 maybe_ref!($refl, self.1).$fn(a))
101 } 120 }
102 } 121 }
103 } 122 }
104 } 123 }
105 124
106 // Not used due to compiler overflow 125 // Not used due to compiler overflow
107 #[allow(unused_macros)] 126 #[allow(unused_macros)]
108 macro_rules! impl_scalarlhs_op { 127 macro_rules! impl_scalarlhs_op {
109 ($trait:ident, $fn:ident, $refr:ident, $field:ty) => { 128 (($a : ty, $b : ty), $field : ty, $trait:ident, $fn:ident, $refr:ident) => {
110 impl_scalarlhs_op!(@doit: $trait, $fn, 129 impl_scalarlhs_op!(@doit: $trait, $fn,
111 maybe_lifetime!($refr, &'r Pair<Ai,Bi>), 130 maybe_lifetime!($refr, &'r Pair<$a,$b>),
112 (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi)); 131 (maybe_lifetime!($refr, &'r $a),
132 maybe_lifetime!($refr, &'r $b));
113 $refr, $field); 133 $refr, $field);
114 }; 134 };
115 (@doit: $trait:ident, $fn:ident, 135 (@doit: $trait:ident, $fn:ident,
116 $in:ty, ($ain:ty, $bin:ty); 136 $in:ty, ($ain:ty, $bin:ty);
117 $refr:ident, $field:ty) => { 137 $refr:ident, $field:ty) => {
118 impl<'r, Ai, Bi> $trait<$in> 138 impl<'r> $trait<$in>
119 for $field 139 for $field
120 where $field : $trait<$ain> 140 where $field : $trait<$ain>
121 + $trait<$bin> { 141 + $trait<$bin> {
122 type Output = Pair<<$field as $trait<$ain>>::Output, 142 type Output = Pair<<$field as $trait<$ain>>::Output,
123 <$field as $trait<$bin>>::Output>; 143 <$field as $trait<$bin>>::Output>;
124 #[inline] 144 #[inline]
125 fn $fn(self, x : $in) -> Self::Output { 145 fn $fn(self, x : $in) -> Self::Output {
126 Pair{ 0 : self.$fn(maybe_ref!($refr, x.0)), 146 Pair(self.$fn(maybe_ref!($refr, x.0)),
127 1 : self.$fn(maybe_ref!($refr, x.1))} 147 self.$fn(maybe_ref!($refr, x.1)))
128 } 148 }
129 } 149 }
130 }; 150 };
131 } 151 }
132 152
133 macro_rules! impl_scalar_assignop { 153 macro_rules! impl_scalar_assignop {
134 ($trait : ident, $fn : ident) => { 154 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
135 impl<'r, F : Num, A, B> $trait<F> 155 impl<'r> $trait<$field>
136 for Pair<A,B> 156 for Pair<$a, $b>
137 where A: $trait<F>, B: $trait<F> { 157 where $a: $trait<$field>, $b: $trait<$field> {
138 #[inline] 158 #[inline]
139 fn $fn(&mut self, a : F) -> () { 159 fn $fn(&mut self, a : $field) -> () {
140 self.0.$fn(a); 160 self.0.$fn(a);
141 self.1.$fn(a); 161 self.1.$fn(a);
142 } 162 }
143 } 163 }
144 } 164 }
145 } 165 }
146 166
147 macro_rules! impl_unaryop { 167 macro_rules! impl_unaryop {
148 ($trait:ident, $fn:ident, $refl:ident) => { 168 (($a : ty, $b : ty), $trait:ident, $fn:ident, $refl:ident) => {
149 impl_unaryop!(@doit: $trait, $fn; 169 impl_unaryop!(@doit: $trait, $fn;
150 maybe_lifetime!($refl, &'l Pair<A,B>), 170 maybe_lifetime!($refl, &'l Pair<$a,$b>),
151 (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B)); 171 (maybe_lifetime!($refl, &'l $a),
172 maybe_lifetime!($refl, &'l $b));
152 $refl); 173 $refl);
153 }; 174 };
154 (@doit: $trait:ident, $fn:ident; 175 (@doit: $trait:ident, $fn:ident;
155 $self:ty, ($aself:ty, $bself:ty); 176 $self:ty, ($aself:ty, $bself:ty);
156 $refl : ident) => { 177 $refl : ident) => {
157 impl<'l, A, B> $trait 178 impl<'l> $trait
158 for $self 179 for $self
159 where $aself: $trait, 180 where $aself: $trait,
160 $bself: $trait { 181 $bself: $trait {
161 type Output = Pair<<$aself as $trait>::Output, 182 type Output = Pair<<$aself as $trait>::Output,
162 <$bself as $trait>::Output>; 183 <$bself as $trait>::Output>;
163 #[inline] 184 #[inline]
164 fn $fn(self) -> Self::Output { 185 fn $fn(self) -> Self::Output {
165 Pair{ 0 : maybe_ref!($refl, self.0).$fn(), 186 Pair(maybe_ref!($refl, self.0).$fn(),
166 1 : maybe_ref!($refl, self.1).$fn()} 187 maybe_ref!($refl, self.1).$fn())
167 } 188 }
168 } 189 }
169 } 190 }
170 } 191 }
171 192
172 193 #[macro_export]
173 impl_vectorspace_ops!(impl_binop, impl_assignop, impl_scalarop, impl_scalarlhs_op, 194 macro_rules! impl_pair_vectorspace_ops {
174 impl_scalar_assignop, impl_unaryop); 195 (($a:ty, $b:ty), $field:ty) => {
175 196 impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add);
197 impl_pair_vectorspace_ops!(@binary, ($a, $b), Sub, sub);
198 impl_pair_vectorspace_ops!(@assign, ($a, $b), AddAssign, add_assign);
199 impl_pair_vectorspace_ops!(@assign, ($a, $b), SubAssign, sub_assign);
200 impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Mul, mul);
201 impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div);
202 // Compiler overflow
203 // $(
204 // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul);
205 // )*
206 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign);
207 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign);
208 impl_pair_vectorspace_ops!(@unary, ($a, $b), Neg, neg);
209 };
210 (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
211 impl_binop!(($a, $b), $trait, $fn, ref, ref);
212 impl_binop!(($a, $b), $trait, $fn, ref, noref);
213 impl_binop!(($a, $b), $trait, $fn, noref, ref);
214 impl_binop!(($a, $b), $trait, $fn, noref, noref);
215 };
216 (@assign, ($a : ty, $b : ty), $trait : ident, $fn :ident) => {
217 impl_assignop!(($a, $b), $trait, $fn, ref);
218 impl_assignop!(($a, $b), $trait, $fn, noref);
219 };
220 (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => {
221 impl_scalarop!(($a, $b), $field, $trait, $fn, ref);
222 impl_scalarop!(($a, $b), $field, $trait, $fn, noref);
223 };
224 (@scalar_lhs, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
225 impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, ref);
226 impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, noref);
227 };
228 (@scalar_assign, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
229 impl_scalar_assignop!(($a, $b), $field, $trait, $fn);
230 };
231 (@unary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
232 impl_unaryop!(($a, $b), $trait, $fn, ref);
233 impl_unaryop!(($a, $b), $trait, $fn, noref);
234 };
235 }
236
237 impl_pair_vectorspace_ops!((f32, f32), f32);
238 impl_pair_vectorspace_ops!((f64, f64), f64);
176 239
177 impl<A, B, U, V, F> Dot<Pair<U, V>, F> for Pair<A, B> 240 impl<A, B, U, V, F> Dot<Pair<U, V>, F> for Pair<A, B>
178 where 241 where
179 A : Dot<U, F>, 242 A : Dot<U, F>,
180 B : Dot<V, F>, 243 B : Dot<V, F>,
184 fn dot(&self, Pair(ref u, ref v) : &Pair<U, V>) -> F { 247 fn dot(&self, Pair(ref u, ref v) : &Pair<U, V>) -> F {
185 self.0.dot(u) + self.1.dot(v) 248 self.0.dot(u) + self.1.dot(v)
186 } 249 }
187 } 250 }
188 251
189 impl<A, B, F> Euclidean<F> for Pair<A, B> 252 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>;
253
254 impl<A, B, F> Euclidean<F> for Pair<A, B>
190 where 255 where
191 A : Euclidean<F>, 256 A : Euclidean<F>,
192 B : Euclidean<F>, 257 B : Euclidean<F>,
193 F : Float 258 F : Float,
194 { 259 PairOutput<F, A, B> : Euclidean<F>,
195 type Output = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; 260 Self : Sized + Dot<Self,F>
196 261 + Mul<F, Output=PairOutput<F, A, B>> + MulAssign<F>
197 fn similar_origin(&self) -> <Self as Euclidean<F>>::Output { 262 + Div<F, Output=PairOutput<F, A, B>> + DivAssign<F>
263 + Add<Self, Output=PairOutput<F, A, B>>
264 + Sub<Self, Output=PairOutput<F, A, B>>
265 + for<'b> Add<&'b Self, Output=PairOutput<F, A, B>>
266 + for<'b> Sub<&'b Self, Output=PairOutput<F, A, B>>
267 + AddAssign<Self> + for<'b> AddAssign<&'b Self>
268 + SubAssign<Self> + for<'b> SubAssign<&'b Self>
269 + Neg<Output=PairOutput<F, A, B>>
270 {
271 type Output = PairOutput<F, A, B>;
272
273 fn similar_origin(&self) -> PairOutput<F, A, B> {
198 Pair(self.0.similar_origin(), self.1.similar_origin()) 274 Pair(self.0.similar_origin(), self.1.similar_origin())
199 } 275 }
200 276
201 fn dist2_squared(&self, Pair(ref u, ref v) : &Self) -> F { 277 fn dist2_squared(&self, Pair(ref u, ref v) : &Self) -> F {
202 self.0.dist2_squared(u) + self.1.dist2_squared(v) 278 self.0.dist2_squared(u) + self.1.dist2_squared(v)
203 } 279 }
204 } 280 }
205 281
206 use crate::linops::AXPY;
207
208 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> 282 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B>
209 where 283 where
284 U : Space,
285 V : Space,
210 A : AXPY<F, U>, 286 A : AXPY<F, U>,
211 B : AXPY<F, V>, 287 B : AXPY<F, V>,
212 F : Num 288 F : Num
213 { 289 {
214 fn axpy(&mut self, α : F, x : &Pair<U, V>, β : F) { 290
215 self.0.axpy(α, &x.0, β); 291 fn axpy<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I, β : F) {
216 self.1.axpy(α, &x.1, β); 292 let Pair(u, v) = x.decompose();
217 } 293 self.0.axpy(α, u, β);
218 294 self.1.axpy(α, v, β);
219 fn copy_from(&mut self, x : &Pair<U, V>,) { 295 }
220 self.0.copy_from(&x.0); 296
221 self.1.copy_from(&x.1); 297 fn copy_from<I : Instance<Pair<U,V>>>(&mut self, x : I) {
222 } 298 let Pair(u, v) = x.decompose();
223 299 self.0.copy_from(u);
224 fn scale_from(&mut self, α : F, x : &Pair<U, V>) { 300 self.1.copy_from(v);
225 self.0.scale_from(α, &x.0); 301 }
226 self.1.scale_from(α, &x.1); 302
227 } 303 fn scale_from<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I) {
228 } 304 let Pair(u, v) = x.decompose();
305 self.0.scale_from(α, u);
306 self.1.scale_from(α, v);
307 }
308 }
309
310 /// [`Decomposition`] for working with [`Pair`]s.
311 #[derive(Copy, Clone, Debug)]
312 pub struct PairDecomposition<D, Q>(D, Q);
313
314 impl<A : Space, B : Space> Space for Pair<A, B> {
315 type Decomp = PairDecomposition<A::Decomp, B::Decomp>;
316 }
317
318 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D,Q>
319 where
320 A : Space,
321 B : Space,
322 D : Decomposition<A>,
323 Q : Decomposition<B>,
324 {
325 type Decomposition<'b> = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> where Pair<A, B> : 'b;
326 type Reference<'b> = Pair<D::Reference<'b>, Q::Reference<'b>> where Pair<A, B> : 'b;
327
328 #[inline]
329 fn lift<'b>(Pair(u, v) : Self::Reference<'b>) -> Self::Decomposition<'b> {
330 Pair(D::lift(u), Q::lift(v))
331 }
332 }
333
334 impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
335 where
336 A : Space,
337 B : Space,
338 D : Decomposition<A>,
339 Q : Decomposition<B>,
340 U : Instance<A, D>,
341 V : Instance<B, Q>,
342 {
343 #[inline]
344 fn decompose<'b>(self)
345 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
346 where Self : 'b, Pair<A, B> : 'b
347 {
348 Pair(self.0.decompose(), self.1.decompose())
349 }
350
351 #[inline]
352 fn ref_instance(&self)
353 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_>
354 {
355 Pair(self.0.ref_instance(), self.1.ref_instance())
356 }
357
358 #[inline]
359 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b{
360 MyCow::Owned(Pair(self.0.own(), self.1.own()))
361 }
362
363 #[inline]
364 fn own(self) -> Pair<A, B> {
365 Pair(self.0.own(), self.1.own())
366 }
367 }
368
369
370 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V>
371 where
372 A : Space,
373 B : Space,
374 D : Decomposition<A>,
375 Q : Decomposition<B>,
376 U : Instance<A, D>,
377 V : Instance<B, Q>,
378 &'a U : Instance<A, D>,
379 &'a V : Instance<B, Q>,
380 {
381 #[inline]
382 fn decompose<'b>(self)
383 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
384 where Self : 'b, Pair<A, B> : 'b
385 {
386 Pair(D::lift(self.0.ref_instance()), Q::lift(self.1.ref_instance()))
387 }
388
389 #[inline]
390 fn ref_instance(&self)
391 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_>
392 {
393 Pair(self.0.ref_instance(), self.1.ref_instance())
394 }
395
396 #[inline]
397 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b {
398 MyCow::Owned(self.own())
399 }
400
401 #[inline]
402 fn own(self) -> Pair<A, B> {
403 let Pair(ref u, ref v) = self;
404 Pair(u.own(), v.own())
405 }
406
407 }
408
409 impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D,Q>
410 where
411 A : Space,
412 B : Space,
413 D : DecompositionMut<A>,
414 Q : DecompositionMut<B>,
415 {
416 type ReferenceMut<'b> = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> where Pair<A, B> : 'b;
417 }
418
419 impl<A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
420 where
421 A : Space,
422 B : Space,
423 D : DecompositionMut<A>,
424 Q : DecompositionMut<B>,
425 U : InstanceMut<A, D>,
426 V : InstanceMut<B, Q>,
427 {
428 #[inline]
429 fn ref_instance_mut(&mut self)
430 -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_>
431 {
432 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut())
433 }
434 }
435
436 impl<'a, A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for &'a mut Pair<U, V>
437 where
438 A : Space,
439 B : Space,
440 D : DecompositionMut<A>,
441 Q : DecompositionMut<B>,
442 U : InstanceMut<A, D>,
443 V : InstanceMut<B, Q>,
444 {
445 #[inline]
446 fn ref_instance_mut(&mut self)
447 -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_>
448 {
449 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut())
450 }
451 }
452
453
454 impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>>
455 for Pair<A,B>
456 where
457 F : Num,
458 ExpA : NormExponent,
459 ExpB : NormExponent,
460 ExpJ : NormExponent,
461 A : Norm<F, ExpA>,
462 B : Norm<F, ExpB>,
463 Loc<F, 2> : Norm<F, ExpJ>,
464 {
465 fn norm(&self, PairNorm(expa, expb, expj) : PairNorm<ExpA, ExpB, ExpJ>) -> F {
466 Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj)
467 }
468 }
469
470

mercurial