| 37 fn from(Pair(a, b): Pair<A, B>) -> (A, B) { |
37 fn from(Pair(a, b): Pair<A, B>) -> (A, B) { |
| 38 (a, b) |
38 (a, b) |
| 39 } |
39 } |
| 40 } |
40 } |
| 41 |
41 |
| 42 macro_rules! impl_binop { |
42 macro_rules! impl_unary { |
| 43 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refl:ident, $refr:ident) => { |
43 ($trait:ident, $fn:ident) => { |
| 44 impl_binop!(@doit: $a, $b, $trait, $fn; |
44 impl<A, B> $trait for Pair<A, B> |
| 45 maybe_lifetime!($refl, &'l Pair<$a,$b>), |
45 where |
| 46 (maybe_lifetime!($refl, &'l $a), |
46 A: $trait, |
| 47 maybe_lifetime!($refl, &'l $b)); |
47 B: $trait, |
| 48 maybe_lifetime!($refr, &'r Pair<Ai,Bi>), |
48 { |
| 49 (maybe_lifetime!($refr, &'r Ai), |
49 type Output = Pair<A::Output, B::Output>; |
| 50 maybe_lifetime!($refr, &'r Bi)); |
50 fn $fn(self) -> Self::Output { |
| 51 $refl, $refr); |
51 let Pair(a, b) = self; |
| |
52 Pair(a.$fn(), b.$fn()) |
| |
53 } |
| |
54 } |
| |
55 |
| |
56 // Compiler overflow |
| |
57 // impl<'a, A, B> $trait for &'a Pair<A, B> |
| |
58 // where |
| |
59 // &'a A: $trait, |
| |
60 // &'a B: $trait, |
| |
61 // { |
| |
62 // type Output = Pair<<&'a A as $trait>::Output, <&'a B as $trait>::Output>; |
| |
63 // fn $fn(self) -> Self::Output { |
| |
64 // let Pair(ref a, ref b) = self; |
| |
65 // Pair(a.$fn(), b.$fn()) |
| |
66 // } |
| |
67 // } |
| 52 }; |
68 }; |
| 53 |
69 } |
| 54 (@doit: $a:ty, $b:ty, |
70 |
| 55 $trait:ident, $fn:ident; |
71 impl_unary!(Neg, neg); |
| 56 $self:ty, ($aself:ty, $bself:ty); |
72 |
| 57 $in:ty, ($ain:ty, $bin:ty); |
73 macro_rules! impl_binary { |
| 58 $refl:ident, $refr:ident) => { |
74 ($trait:ident, $fn:ident) => { |
| 59 impl<'l, 'r, Ai, Bi> $trait<$in> |
75 impl<A, B, C, D> $trait<Pair<C, D>> for Pair<A, B> |
| 60 for $self |
76 where |
| 61 where $aself: $trait<$ain>, |
77 A: $trait<C>, |
| 62 $bself: $trait<$bin> { |
78 B: $trait<D>, |
| 63 type Output = Pair<<$aself as $trait<$ain>>::Output, |
79 { |
| 64 <$bself as $trait<$bin>>::Output>; |
80 type Output = Pair<A::Output, B::Output>; |
| 65 |
81 fn $fn(self, Pair(c, d): Pair<C, D>) -> Self::Output { |
| 66 #[inline] |
82 let Pair(a, b) = self; |
| 67 fn $fn(self, y : $in) -> Self::Output { |
83 Pair(a.$fn(c), b.$fn(d)) |
| 68 Pair(maybe_ref!($refl, self.0).$fn(maybe_ref!($refr, y.0)), |
84 } |
| 69 maybe_ref!($refl, self.1).$fn(maybe_ref!($refr, y.1))) |
85 } |
| |
86 |
| |
87 impl<'a, A, B, C, D> $trait<Pair<C, D>> for &'a Pair<A, B> |
| |
88 where |
| |
89 &'a A: $trait<C>, |
| |
90 &'a B: $trait<D>, |
| |
91 { |
| |
92 type Output = Pair<<&'a A as $trait<C>>::Output, <&'a B as $trait<D>>::Output>; |
| |
93 fn $fn(self, Pair(c, d): Pair<C, D>) -> Self::Output { |
| |
94 let Pair(ref a, ref b) = self; |
| |
95 Pair(a.$fn(c), b.$fn(d)) |
| |
96 } |
| |
97 } |
| |
98 |
| |
99 impl<'a, 'b, A, B, C, D> $trait<&'b Pair<C, D>> for &'a Pair<A, B> |
| |
100 where |
| |
101 &'a A: $trait<&'b C>, |
| |
102 &'a B: $trait<&'b D>, |
| |
103 { |
| |
104 type Output = Pair<<&'a A as $trait<&'b C>>::Output, <&'a B as $trait<&'b D>>::Output>; |
| |
105 fn $fn(self, Pair(ref c, ref d): &'b Pair<C, D>) -> Self::Output { |
| |
106 let Pair(ref a, ref b) = self; |
| |
107 Pair(a.$fn(c), b.$fn(d)) |
| |
108 } |
| |
109 } |
| |
110 |
| |
111 impl<'b, A, B, C, D> $trait<&'b Pair<C, D>> for Pair<A, B> |
| |
112 where |
| |
113 A: $trait<&'b C>, |
| |
114 B: $trait<&'b D>, |
| |
115 { |
| |
116 type Output = Pair<<A as $trait<&'b C>>::Output, <B as $trait<&'b D>>::Output>; |
| |
117 fn $fn(self, Pair(ref c, ref d): &'b Pair<C, D>) -> Self::Output { |
| |
118 let Pair(a, b) = self; |
| |
119 Pair(a.$fn(c), b.$fn(d)) |
| 70 } |
120 } |
| 71 } |
121 } |
| 72 }; |
122 }; |
| 73 } |
123 } |
| 74 |
124 |
| 75 macro_rules! impl_assignop { |
125 impl_binary!(Add, add); |
| 76 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refr:ident) => { |
126 impl_binary!(Sub, sub); |
| 77 impl_assignop!(@doit: $a, $b, |
127 |
| 78 $trait, $fn; |
128 macro_rules! impl_scalar { |
| 79 maybe_lifetime!($refr, &'r Pair<Ai,Bi>), |
129 ($trait:ident, $fn:ident) => { |
| 80 (maybe_lifetime!($refr, &'r Ai), |
130 impl<A, B, F: Num> $trait<F> for Pair<A, B> |
| 81 maybe_lifetime!($refr, &'r Bi)); |
131 where |
| 82 $refr); |
132 A: $trait<F>, |
| |
133 B: $trait<F>, |
| |
134 { |
| |
135 type Output = Pair<A::Output, B::Output>; |
| |
136 fn $fn(self, t: F) -> Self::Output { |
| |
137 let Pair(a, b) = self; |
| |
138 Pair(a.$fn(t), b.$fn(t)) |
| |
139 } |
| |
140 } |
| |
141 |
| |
142 impl<'a, A, B, F: Num> $trait<F> for &'a Pair<A, B> |
| |
143 where |
| |
144 &'a A: $trait<F>, |
| |
145 &'a B: $trait<F>, |
| |
146 { |
| |
147 type Output = Pair<<&'a A as $trait<F>>::Output, <&'a B as $trait<F>>::Output>; |
| |
148 fn $fn(self, t: F) -> Self::Output { |
| |
149 let Pair(ref a, ref b) = self; |
| |
150 Pair(a.$fn(t), b.$fn(t)) |
| |
151 } |
| |
152 } |
| |
153 |
| |
154 // impl<'a, 'b, A, B> $trait<&'b $F> for &'a Pair<A, B> |
| |
155 // where |
| |
156 // &'a A: $trait<&'b $F>, |
| |
157 // &'a B: $trait<&'b $F>, |
| |
158 // { |
| |
159 // type Output = |
| |
160 // Pair<<&'a A as $trait<&'b $F>>::Output, <&'a B as $trait<&'b $F>>::Output>; |
| |
161 // fn $fn(self, t: &'b $F) -> Self::Output { |
| |
162 // let Pair(ref a, ref b) = self; |
| |
163 // Pair(a.$fn(t), b.$fn(t)) |
| |
164 // } |
| |
165 // } |
| |
166 |
| |
167 // impl<'b, A, B> $trait<&'b $F> for Pair<A, B> |
| |
168 // where |
| |
169 // A: $trait<&'b $F>, |
| |
170 // B: $trait<&'b $F>, |
| |
171 // { |
| |
172 // type Output = Pair<<A as $trait<&'b $F>>::Output, <B as $trait<&'b $F>>::Output>; |
| |
173 // fn $fn(self, t: &'b $F) -> Self::Output { |
| |
174 // let Pair(a, b) = self; |
| |
175 // Pair(a.$fn(t), b.$fn(t)) |
| |
176 // } |
| |
177 // } |
| 83 }; |
178 }; |
| 84 (@doit: $a : ty, $b : ty, |
179 } |
| 85 $trait:ident, $fn:ident; |
180 |
| 86 $in:ty, ($ain:ty, $bin:ty); |
181 impl_scalar!(Mul, mul); |
| 87 $refr:ident) => { |
182 impl_scalar!(Div, div); |
| 88 impl<'r, Ai, Bi> $trait<$in> |
183 |
| 89 for Pair<$a,$b> |
184 macro_rules! impl_scalar_lhs { |
| 90 where $a: $trait<$ain>, |
185 ($trait:ident, $fn:ident, $F:ty) => { |
| 91 $b: $trait<$bin> { |
186 impl<A, B> $trait<Pair<A, B>> for $F |
| 92 #[inline] |
187 where |
| 93 fn $fn(&mut self, y : $in) -> () { |
188 $F: $trait<A> + $trait<B>, |
| 94 self.0.$fn(maybe_ref!($refr, y.0)); |
189 { |
| 95 self.1.$fn(maybe_ref!($refr, y.1)); |
190 type Output = Pair<<$F as $trait<A>>::Output, <$F as $trait<B>>::Output>; |
| 96 } |
191 fn $fn(self, Pair(a, b): Pair<A, B>) -> Self::Output { |
| 97 } |
192 Pair(self.$fn(a), self.$fn(b)) |
| 98 } |
193 } |
| 99 } |
194 } |
| 100 |
195 |
| 101 macro_rules! impl_scalarop { |
196 // Compiler overflow: |
| 102 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident, $refl:ident) => { |
197 // |
| 103 impl_scalarop!(@doit: $field, |
198 // impl<'a, A, B> $trait<&'a Pair<A, B>> for $F |
| 104 $trait, $fn; |
199 // where |
| 105 maybe_lifetime!($refl, &'l Pair<$a,$b>), |
200 // $F: $trait<&'a A> + $trait<&'a B>, |
| 106 (maybe_lifetime!($refl, &'l $a), |
201 // { |
| 107 maybe_lifetime!($refl, &'l $b)); |
202 // type Output = Pair<<$F as $trait<&'a A>>::Output, <$F as $trait<&'a B>>::Output>; |
| 108 $refl); |
203 // fn $fn(self, Pair(a, b): &'a Pair<A, B>) -> Self::Output { |
| |
204 // Pair(self.$fn(a), self.$fn(b)) |
| |
205 // } |
| |
206 // } |
| 109 }; |
207 }; |
| 110 (@doit: $field : ty, |
208 } |
| 111 $trait:ident, $fn:ident; |
209 |
| 112 $self:ty, ($aself:ty, $bself:ty); |
210 impl_scalar_lhs!(Mul, mul, f32); |
| 113 $refl:ident) => { |
211 impl_scalar_lhs!(Mul, mul, f64); |
| 114 // Scalar as Rhs |
212 impl_scalar_lhs!(Div, div, f32); |
| 115 impl<'l> $trait<$field> |
213 impl_scalar_lhs!(Div, div, f64); |
| 116 for $self |
214 |
| 117 where $aself: $trait<$field>, |
215 macro_rules! impl_binary_mut { |
| 118 $bself: $trait<$field> { |
216 ($trait:ident, $fn:ident) => { |
| 119 type Output = Pair<<$aself as $trait<$field>>::Output, |
217 impl<'a, A, B, C, D> $trait<Pair<C, D>> for Pair<A, B> |
| 120 <$bself as $trait<$field>>::Output>; |
218 where |
| 121 #[inline] |
219 A: $trait<C>, |
| 122 fn $fn(self, a : $field) -> Self::Output { |
220 B: $trait<D>, |
| 123 Pair(maybe_ref!($refl, self.0).$fn(a), |
221 { |
| 124 maybe_ref!($refl, self.1).$fn(a)) |
222 fn $fn(&mut self, Pair(c, d): Pair<C, D>) { |
| 125 } |
223 let Pair(ref mut a, ref mut b) = self; |
| 126 } |
224 a.$fn(c); |
| 127 } |
225 b.$fn(d); |
| 128 } |
226 } |
| 129 |
227 } |
| 130 // Not used due to compiler overflow |
228 |
| 131 #[allow(unused_macros)] |
229 impl<'a, 'b, A, B, C, D> $trait<&'b Pair<C, D>> for Pair<A, B> |
| 132 macro_rules! impl_scalarlhs_op { |
230 where |
| 133 (($a : ty, $b : ty), $field : ty, $trait:ident, $fn:ident, $refr:ident) => { |
231 A: $trait<&'b C>, |
| 134 impl_scalarlhs_op!(@doit: $trait, $fn, |
232 B: $trait<&'b D>, |
| 135 maybe_lifetime!($refr, &'r Pair<$a,$b>), |
233 { |
| 136 (maybe_lifetime!($refr, &'r $a), |
234 fn $fn(&mut self, Pair(ref c, ref d): &'b Pair<C, D>) { |
| 137 maybe_lifetime!($refr, &'r $b)); |
235 let Pair(ref mut a, ref mut b) = self; |
| 138 $refr, $field); |
236 a.$fn(c); |
| |
237 b.$fn(d); |
| |
238 } |
| |
239 } |
| 139 }; |
240 }; |
| 140 (@doit: $trait:ident, $fn:ident, |
241 } |
| 141 $in:ty, ($ain:ty, $bin:ty); |
242 |
| 142 $refr:ident, $field:ty) => { |
243 impl_binary_mut!(AddAssign, add_assign); |
| 143 impl<'r> $trait<$in> |
244 impl_binary_mut!(SubAssign, sub_assign); |
| 144 for $field |
245 |
| 145 where $field : $trait<$ain> |
246 macro_rules! impl_scalar_mut { |
| 146 + $trait<$bin> { |
247 ($trait:ident, $fn:ident) => { |
| 147 type Output = Pair<<$field as $trait<$ain>>::Output, |
248 impl<'a, A, B, F: Num> $trait<F> for Pair<A, B> |
| 148 <$field as $trait<$bin>>::Output>; |
249 where |
| 149 #[inline] |
250 A: $trait<F>, |
| 150 fn $fn(self, x : $in) -> Self::Output { |
251 B: $trait<F>, |
| 151 Pair(self.$fn(maybe_ref!($refr, x.0)), |
252 { |
| 152 self.$fn(maybe_ref!($refr, x.1))) |
253 fn $fn(&mut self, t: F) { |
| |
254 let Pair(ref mut a, ref mut b) = self; |
| |
255 a.$fn(t); |
| |
256 b.$fn(t); |
| 153 } |
257 } |
| 154 } |
258 } |
| 155 }; |
259 }; |
| 156 } |
260 } |
| 157 |
261 |
| 158 macro_rules! impl_scalar_assignop { |
262 impl_scalar_mut!(MulAssign, mul_assign); |
| 159 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { |
263 impl_scalar_mut!(DivAssign, div_assign); |
| 160 impl<'r> $trait<$field> for Pair<$a, $b> |
264 |
| 161 where |
265 /// Trait for ownable-by-consumption objects |
| 162 $a: $trait<$field>, |
266 impl<A, B> Ownable for Pair<A, B> |
| 163 $b: $trait<$field>, |
267 where |
| 164 { |
268 A: Ownable, |
| 165 #[inline] |
269 B: Ownable, |
| 166 fn $fn(&mut self, a: $field) -> () { |
270 { |
| 167 self.0.$fn(a); |
271 type OwnedVariant = Pair<A::OwnedVariant, B::OwnedVariant>; |
| 168 self.1.$fn(a); |
272 |
| 169 } |
273 #[inline] |
| 170 } |
274 fn into_owned(self) -> Self::OwnedVariant { |
| 171 }; |
275 Pair(self.0.into_owned(), self.1.into_owned()) |
| 172 } |
276 } |
| 173 |
277 |
| 174 macro_rules! impl_unaryop { |
278 #[inline] |
| 175 (($a : ty, $b : ty), $trait:ident, $fn:ident, $refl:ident) => { |
279 fn clone_owned(&self) -> Self::OwnedVariant { |
| 176 impl_unaryop!(@doit: $trait, $fn; |
280 Pair(self.0.clone_owned(), self.1.clone_owned()) |
| 177 maybe_lifetime!($refl, &'l Pair<$a,$b>), |
281 } |
| 178 (maybe_lifetime!($refl, &'l $a), |
282 |
| 179 maybe_lifetime!($refl, &'l $b)); |
283 #[inline] |
| 180 $refl); |
284 fn cow_owned<'b>(self) -> MyCow<'b, Self::OwnedVariant> |
| 181 }; |
285 where |
| 182 (@doit: $trait:ident, $fn:ident; |
286 Self: 'b, |
| 183 $self:ty, ($aself:ty, $bself:ty); |
287 { |
| 184 $refl : ident) => { |
288 MyCow::Owned(self.into_owned()) |
| 185 impl<'l> $trait |
289 } |
| 186 for $self |
290 |
| 187 where $aself: $trait, |
291 #[inline] |
| 188 $bself: $trait { |
292 fn ref_cow_owned<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> |
| 189 type Output = Pair<<$aself as $trait>::Output, |
293 where |
| 190 <$bself as $trait>::Output>; |
294 Self: 'b, |
| 191 #[inline] |
295 { |
| 192 fn $fn(self) -> Self::Output { |
296 MyCow::Owned(self.clone_owned()) |
| 193 Pair(maybe_ref!($refl, self.0).$fn(), |
297 } |
| 194 maybe_ref!($refl, self.1).$fn()) |
298 } |
| 195 } |
299 |
| 196 } |
300 /// We only support 'closed' `Euclidean` `Pair`s, as more general ones cause |
| 197 } |
301 /// compiler overflows. |
| 198 } |
302 impl<A, B, F: Float> Euclidean<F> for Pair<A, B> |
| 199 |
|
| 200 #[macro_export] |
|
| 201 macro_rules! impl_pair_vectorspace_ops { |
|
| 202 (($a:ty, $b:ty), $field:ty) => { |
|
| 203 impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add); |
|
| 204 impl_pair_vectorspace_ops!(@binary, ($a, $b), Sub, sub); |
|
| 205 impl_pair_vectorspace_ops!(@assign, ($a, $b), AddAssign, add_assign); |
|
| 206 impl_pair_vectorspace_ops!(@assign, ($a, $b), SubAssign, sub_assign); |
|
| 207 impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Mul, mul); |
|
| 208 impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div); |
|
| 209 // Compiler overflow |
|
| 210 // $( |
|
| 211 // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul); |
|
| 212 // )* |
|
| 213 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign); |
|
| 214 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign); |
|
| 215 impl_pair_vectorspace_ops!(@unary, ($a, $b), Neg, neg); |
|
| 216 }; |
|
| 217 (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => { |
|
| 218 impl_binop!(($a, $b), $trait, $fn, ref, ref); |
|
| 219 impl_binop!(($a, $b), $trait, $fn, ref, noref); |
|
| 220 impl_binop!(($a, $b), $trait, $fn, noref, ref); |
|
| 221 impl_binop!(($a, $b), $trait, $fn, noref, noref); |
|
| 222 }; |
|
| 223 (@assign, ($a : ty, $b : ty), $trait : ident, $fn :ident) => { |
|
| 224 impl_assignop!(($a, $b), $trait, $fn, ref); |
|
| 225 impl_assignop!(($a, $b), $trait, $fn, noref); |
|
| 226 }; |
|
| 227 (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => { |
|
| 228 impl_scalarop!(($a, $b), $field, $trait, $fn, ref); |
|
| 229 impl_scalarop!(($a, $b), $field, $trait, $fn, noref); |
|
| 230 }; |
|
| 231 (@scalar_lhs, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { |
|
| 232 impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, ref); |
|
| 233 impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, noref); |
|
| 234 }; |
|
| 235 (@scalar_assign, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { |
|
| 236 impl_scalar_assignop!(($a, $b), $field, $trait, $fn); |
|
| 237 }; |
|
| 238 (@unary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => { |
|
| 239 impl_unaryop!(($a, $b), $trait, $fn, ref); |
|
| 240 impl_unaryop!(($a, $b), $trait, $fn, noref); |
|
| 241 }; |
|
| 242 } |
|
| 243 |
|
| 244 impl_pair_vectorspace_ops!((f32, f32), f32); |
|
| 245 impl_pair_vectorspace_ops!((f64, f64), f64); |
|
| 246 |
|
| 247 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; |
|
| 248 |
|
| 249 impl<A, B, F> Euclidean<F> for Pair<A, B> |
|
| 250 where |
303 where |
| 251 A: Euclidean<F>, |
304 A: Euclidean<F>, |
| 252 B: Euclidean<F>, |
305 B: Euclidean<F>, |
| 253 F: Float, |
306 // //Pair<A, B>: Euclidean<F>, |
| 254 PairOutput<F, A, B>: Euclidean<F>, |
307 // Self: Sized |
| 255 Self: Sized |
308 // + Mul<F, Output = Self::OwnedEuclidean> |
| 256 + Mul<F, Output = PairOutput<F, A, B>> |
309 // + MulAssign<F> |
| 257 + MulAssign<F> |
310 // + Div<F, Output = Self::OwnedEuclidean> |
| 258 + Div<F, Output = PairOutput<F, A, B>> |
311 // + DivAssign<F> |
| 259 + DivAssign<F> |
312 // + Add<Self, Output = Self::OwnedEuclidean> |
| 260 + Add<Self, Output = PairOutput<F, A, B>> |
313 // + Sub<Self, Output = Self::OwnedEuclidean> |
| 261 + Sub<Self, Output = PairOutput<F, A, B>> |
314 // + for<'b> Add<&'b Self, Output = Self::OwnedEuclidean> |
| 262 + for<'b> Add<&'b Self, Output = PairOutput<F, A, B>> |
315 // + for<'b> Sub<&'b Self, Output = Self::OwnedEuclidean> |
| 263 + for<'b> Sub<&'b Self, Output = PairOutput<F, A, B>> |
316 // + AddAssign<Self> |
| 264 + AddAssign<Self> |
317 // + for<'b> AddAssign<&'b Self> |
| 265 + for<'b> AddAssign<&'b Self> |
318 // + SubAssign<Self> |
| 266 + SubAssign<Self> |
319 // + for<'b> SubAssign<&'b Self> |
| 267 + for<'b> SubAssign<&'b Self> |
320 // + Neg<Output = Self::OwnedEuclidean>, |
| 268 + Neg<Output = PairOutput<F, A, B>>, |
321 { |
| 269 { |
322 type PrincipalE = Pair<A::PrincipalE, B::PrincipalE>; |
| 270 type Output = PairOutput<F, A, B>; |
|
| 271 |
323 |
| 272 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
324 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
| 273 let Pair(u, v) = other.decompose(); |
325 other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) |
| 274 self.0.dot(u) + self.1.dot(v) |
|
| 275 } |
326 } |
| 276 |
327 |
| 277 fn norm2_squared(&self) -> F { |
328 fn norm2_squared(&self) -> F { |
| 278 self.0.norm2_squared() + self.1.norm2_squared() |
329 self.0.norm2_squared() + self.1.norm2_squared() |
| 279 } |
330 } |
| 280 |
331 |
| 281 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { |
332 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { |
| 282 let Pair(u, v) = other.decompose(); |
333 other.eval_decompose(|Pair(u, v)| self.0.dist2_squared(u) + self.1.dist2_squared(v)) |
| 283 self.0.dist2_squared(u) + self.1.dist2_squared(v) |
334 } |
| 284 } |
335 } |
| 285 } |
336 |
| 286 |
337 impl<F, A, B> VectorSpace for Pair<A, B> |
| 287 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> |
338 where |
| |
339 A: VectorSpace<Field = F>, |
| |
340 B: VectorSpace<Field = F>, |
| |
341 F: Num, |
| |
342 { |
| |
343 type Field = F; |
| |
344 type PrincipalV = Pair<A::PrincipalV, B::PrincipalV>; |
| |
345 |
| |
346 /// Return a similar zero as `self`. |
| |
347 fn similar_origin(&self) -> Self::PrincipalV { |
| |
348 Pair(self.0.similar_origin(), self.1.similar_origin()) |
| |
349 } |
| |
350 |
| |
351 // #[inline] |
| |
352 // fn into_owned(self) -> Self::Owned { |
| |
353 // Pair(self.0.into_owned(), self.1.into_owned()) |
| |
354 // } |
| |
355 } |
| |
356 |
| |
357 impl<F, A, B, U, V> AXPY<Pair<U, V>> for Pair<A, B> |
| 288 where |
358 where |
| 289 U: Space, |
359 U: Space, |
| 290 V: Space, |
360 V: Space, |
| 291 A: AXPY<F, U>, |
361 A: AXPY<U, Field = F>, |
| 292 B: AXPY<F, V>, |
362 B: AXPY<V, Field = F>, |
| 293 F: Num, |
363 F: Num, |
| 294 Self: MulAssign<F>, |
364 // Self: MulAssign<F> + DivAssign<F>, |
| 295 Pair<A, B>: MulAssign<F>, |
365 // Pair<A, B>: MulAssign<F> + DivAssign<F>, |
| 296 Pair<A::Owned, B::Owned>: AXPY<F, Pair<U, V>>, |
366 { |
| 297 { |
|
| 298 type Owned = Pair<A::Owned, B::Owned>; |
|
| 299 |
|
| 300 fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { |
367 fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { |
| 301 let Pair(u, v) = x.decompose(); |
368 x.eval_decompose(|Pair(u, v)| { |
| 302 self.0.axpy(α, u, β); |
369 self.0.axpy(α, u, β); |
| 303 self.1.axpy(α, v, β); |
370 self.1.axpy(α, v, β); |
| |
371 }) |
| 304 } |
372 } |
| 305 |
373 |
| 306 fn copy_from<I: Instance<Pair<U, V>>>(&mut self, x: I) { |
374 fn copy_from<I: Instance<Pair<U, V>>>(&mut self, x: I) { |
| 307 let Pair(u, v) = x.decompose(); |
375 x.eval_decompose(|Pair(u, v)| { |
| 308 self.0.copy_from(u); |
376 self.0.copy_from(u); |
| 309 self.1.copy_from(v); |
377 self.1.copy_from(v); |
| |
378 }) |
| 310 } |
379 } |
| 311 |
380 |
| 312 fn scale_from<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I) { |
381 fn scale_from<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I) { |
| 313 let Pair(u, v) = x.decompose(); |
382 x.eval_decompose(|Pair(u, v)| { |
| 314 self.0.scale_from(α, u); |
383 self.0.scale_from(α, u); |
| 315 self.1.scale_from(α, v); |
384 self.1.scale_from(α, v); |
| 316 } |
385 }) |
| 317 |
|
| 318 /// Return a similar zero as `self`. |
|
| 319 fn similar_origin(&self) -> Self::Owned { |
|
| 320 Pair(self.0.similar_origin(), self.1.similar_origin()) |
|
| 321 } |
386 } |
| 322 |
387 |
| 323 /// Set self to zero. |
388 /// Set self to zero. |
| 324 fn set_zero(&mut self) { |
389 fn set_zero(&mut self) { |
| 325 self.0.set_zero(); |
390 self.0.set_zero(); |