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 |