src/direct_product.rs

branch
dev
changeset 118
0fabd0b5914c
parent 117
9b782aa6b452
child 119
cc0c6a8d0933
equal deleted inserted replaced
117:9b782aa6b452 118:0fabd0b5914c
222 } 222 }
223 } 223 }
224 }; 224 };
225 } 225 }
226 226
227 impl_binary!(Add, add);
228 impl_binary!(Sub, sub);
229
227 macro_rules! impl_binary_mut { 230 macro_rules! impl_binary_mut {
228 ($trait:ident, $fn:ident) => { 231 ($trait:ident, $fn:ident) => {
229 impl<'a, A, B, C, D> $trait<Pair<C, D>> for Pair<A, B> 232 impl<'a, A, B, C, D> $trait<Pair<C, D>> for Pair<A, B>
230 where 233 where
231 A: $trait<C>, 234 A: $trait<C>,
250 } 253 }
251 } 254 }
252 }; 255 };
253 } 256 }
254 257
255 impl_binary!(Add, add);
256 impl_binary!(Sub, sub);
257 impl_binary_mut!(AddAssign, add_assign); 258 impl_binary_mut!(AddAssign, add_assign);
258 impl_binary_mut!(SubAssign, sub_assign); 259 impl_binary_mut!(SubAssign, sub_assign);
260
261 macro_rules! impl_scalar_mut {
262 ($trait:ident, $fn:ident) => {
263 impl<'a, A, B, F> $trait<F> for Pair<A, B>
264 where
265 A: $trait<F>,
266 B: $trait<F>,
267 {
268 fn $fn(&mut self, t: F) {
269 let Pair(ref mut a, ref mut b) = self;
270 a.$fn(t);
271 b.$fn(t);
272 }
273 }
274 };
275 }
276
277 impl_scalar_mut!(MulAssign, mul_assign);
278 impl_scalar_mut!(DivAssign, div_assign);
259 279
260 #[macro_export] 280 #[macro_export]
261 macro_rules! impl_pair_vectorspace_ops { 281 macro_rules! impl_pair_vectorspace_ops {
262 (($a:ty, $b:ty), $field:ty) => { 282 (($a:ty, $b:ty), $field:ty) => {
263 //impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add); 283 //impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add);
268 // impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div); 288 // impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div);
269 // Compiler overflow 289 // Compiler overflow
270 // $( 290 // $(
271 // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul); 291 // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul);
272 // )* 292 // )*
273 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign);
274 impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign);
275 };
276 (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
277 impl_binop!(($a, $b), $trait, $fn, ref, ref);
278 impl_binop!(($a, $b), $trait, $fn, ref, noref);
279 impl_binop!(($a, $b), $trait, $fn, noref, ref);
280 impl_binop!(($a, $b), $trait, $fn, noref, noref);
281 }; 293 };
282 (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => { 294 (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => {
283 impl_scalarop!(($a, $b), $field, $trait, $fn, ref); 295 impl_scalarop!(($a, $b), $field, $trait, $fn, ref);
284 impl_scalarop!(($a, $b), $field, $trait, $fn, noref); 296 impl_scalarop!(($a, $b), $field, $trait, $fn, noref);
285 }; 297 };
303 impl_pair_vectorspace_ops_gen!(@scalar, $field, Mul, mul); 315 impl_pair_vectorspace_ops_gen!(@scalar, $field, Mul, mul);
304 impl_pair_vectorspace_ops_gen!(@scalar, $field, Div, div); 316 impl_pair_vectorspace_ops_gen!(@scalar, $field, Div, div);
305 // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, MulAssign, mul_assign); 317 // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, MulAssign, mul_assign);
306 // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, DivAssign, div_assign); 318 // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, DivAssign, div_assign);
307 }; 319 };
308 // (@binary, $trait : ident, $fn : ident) => {
309 // impl_binop_gen!(($a, $b), $trait, $fn, ref, ref);
310 // impl_binop_gen!(($a, $b), $trait, $fn, ref, noref);
311 // impl_binop_gen!(($a, $b), $trait, $fn, noref, ref);
312 // impl_binop_gen!(($a, $b), $trait, $fn, noref, noref);
313 // };
314 // (@assign, $trait : ident, $fn :ident) => {
315 // impl_assignop_gen!(($a, $b), $trait, $fn, ref);
316 // impl_assignop_gen!(($a, $b), $trait, $fn, noref);
317 // };
318 (@scalar, $field : ty, $trait : ident, $fn :ident) => { 320 (@scalar, $field : ty, $trait : ident, $fn :ident) => {
319 impl_scalarop_gen!($field, $trait, $fn, ref); 321 impl_scalarop_gen!($field, $trait, $fn, ref);
320 impl_scalarop_gen!($field, $trait, $fn, noref); 322 impl_scalarop_gen!($field, $trait, $fn, noref);
321 }; 323 };
322 // (@scalar_lhs, $field : ty, $trait : ident, $fn : ident) => { 324 // (@scalar_lhs, $field : ty, $trait : ident, $fn : ident) => {
329 } 331 }
330 332
331 impl_pair_vectorspace_ops_gen!(f32); 333 impl_pair_vectorspace_ops_gen!(f32);
332 impl_pair_vectorspace_ops_gen!(f64); 334 impl_pair_vectorspace_ops_gen!(f64);
333 335
334 impl_pair_vectorspace_ops!((f32, f32), f32); 336 //impl_pair_vectorspace_ops!((f32, f32), f32);
335 impl_pair_vectorspace_ops!((f64, f64), f64); 337 //impl_pair_vectorspace_ops!((f64, f64), f64);
336
337 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>;
338 338
339 /// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output` 339 /// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output`
340 /// to avoid compiler overflows that the requirement 340
341 /// ``` 341 impl<A, B, F: Float> Euclidean<F> for Pair<A, B>
342 /// Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output> : Euclidean<F> 342 where
343 /// ``` 343 A: Euclidean<F>,
344 /// would generate. 344 B: Euclidean<F>,
345 345 //Pair<A, B>: Euclidean<F>,
346 macro_rules! impl_euclidean { 346 Self: Sized
347 ($field:ty) => { 347 + Mul<F, Output = Pair<A, B>>
348 impl<A, B> Euclidean<$field> for Pair<A, B> 348 + MulAssign<F>
349 where 349 + Div<F, Output = Pair<A, B>>
350 A: Euclidean<$field>, 350 + DivAssign<F>
351 B: Euclidean<$field>, 351 + Add<Self, Output = Pair<A, B>>
352 PairOutput<$field, A, B>: Euclidean<$field>, 352 + Sub<Self, Output = Pair<A, B>>
353 Self: Sized 353 + for<'b> Add<&'b Self, Output = Pair<A, B>>
354 + Mul<$field, Output = PairOutput<$field, A, B>> 354 + for<'b> Sub<&'b Self, Output = Pair<A, B>>
355 + MulAssign<$field> 355 + AddAssign<Self>
356 + Div<$field, Output = PairOutput<$field, A, B>> 356 + for<'b> AddAssign<&'b Self>
357 + DivAssign<$field> 357 + SubAssign<Self>
358 + Add<Self, Output = PairOutput<$field, A, B>> 358 + for<'b> SubAssign<&'b Self>
359 + Sub<Self, Output = PairOutput<$field, A, B>> 359 + Neg<Output = Pair<A, B>>,
360 + for<'b> Add<&'b Self, Output = PairOutput<$field, A, B>> 360 {
361 + for<'b> Sub<&'b Self, Output = PairOutput<$field, A, B>> 361 type Output = Pair<A, B>;
362 + AddAssign<Self> 362
363 + for<'b> AddAssign<&'b Self> 363 fn dot<I: Instance<Self>>(&self, other: I) -> F {
364 + SubAssign<Self> 364 let Pair(u, v) = other.decompose();
365 + for<'b> SubAssign<&'b Self>, //+ Neg<Output = PairOutput<$field, A, B>>, 365 self.0.dot(u) + self.1.dot(v)
366 { 366 }
367 type Output = PairOutput<$field, A, B>; 367
368 368 fn norm2_squared(&self) -> F {
369 fn dot<I: Instance<Self>>(&self, other: I) -> $field { 369 self.0.norm2_squared() + self.1.norm2_squared()
370 let Pair(u, v) = other.decompose(); 370 }
371 self.0.dot(u) + self.1.dot(v) 371
372 } 372 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
373 373 let Pair(u, v) = other.decompose();
374 fn norm2_squared(&self) -> $field { 374 self.0.dist2_squared(u) + self.1.dist2_squared(v)
375 self.0.norm2_squared() + self.1.norm2_squared() 375 }
376 } 376 }
377
378 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> $field {
379 let Pair(u, v) = other.decompose();
380 self.0.dist2_squared(u) + self.1.dist2_squared(v)
381 }
382 }
383 };
384 }
385
386 impl_euclidean!(f32);
387 impl_euclidean!(f64);
388 377
389 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> 378 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B>
390 where 379 where
391 U: Space, 380 U: Space,
392 V: Space, 381 V: Space,

mercurial