src/direct_product.rs

branch
dev
changeset 114
b53806de0be0
parent 103
e98e1da2530d
child 115
f9aec20d0286
equal deleted inserted replaced
113:d97fcf22a61c 114:b53806de0be0
318 impl_pair_vectorspace_ops!((f32, f32), f32); 318 impl_pair_vectorspace_ops!((f32, f32), f32);
319 impl_pair_vectorspace_ops!((f64, f64), f64); 319 impl_pair_vectorspace_ops!((f64, f64), f64);
320 320
321 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; 321 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>;
322 322
323 impl<A, B, F> Euclidean<F> for Pair<A, B> 323 /// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output`
324 where 324 /// to avoid compiler overflows that the requirement
325 A: Euclidean<F>, 325 /// ```
326 B: Euclidean<F>, 326 /// Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output> : Euclidean<F>
327 F: Float, 327 /// ```
328 PairOutput<F, A, B>: Euclidean<F>, 328 /// would generate.
329 Self: Sized 329
330 + Mul<F, Output = PairOutput<F, A, B>> 330 macro_rules! impl_euclidean {
331 + MulAssign<F> 331 ($field:ty) => {
332 + Div<F, Output = PairOutput<F, A, B>> 332 impl<A, B> Euclidean<$field> for Pair<A, B>
333 + DivAssign<F> 333 where
334 + Add<Self, Output = PairOutput<F, A, B>> 334 A: Euclidean<$field>,
335 + Sub<Self, Output = PairOutput<F, A, B>> 335 B: Euclidean<$field>,
336 + for<'b> Add<&'b Self, Output = PairOutput<F, A, B>> 336 PairOutput<$field, A, B>: Euclidean<$field>,
337 + for<'b> Sub<&'b Self, Output = PairOutput<F, A, B>> 337 Self: Sized
338 + AddAssign<Self> 338 + Mul<$field, Output = PairOutput<$field, A, B>>
339 + for<'b> AddAssign<&'b Self> 339 + MulAssign<$field>
340 + SubAssign<Self> 340 + Div<$field, Output = PairOutput<$field, A, B>>
341 + for<'b> SubAssign<&'b Self> 341 + DivAssign<$field>
342 + Neg<Output = PairOutput<F, A, B>>, 342 + Add<Self, Output = PairOutput<$field, A, B>>
343 { 343 + Sub<Self, Output = PairOutput<$field, A, B>>
344 type Output = PairOutput<F, A, B>; 344 + for<'b> Add<&'b Self, Output = PairOutput<$field, A, B>>
345 345 + for<'b> Sub<&'b Self, Output = PairOutput<$field, A, B>>
346 fn dot<I: Instance<Self>>(&self, other: I) -> F { 346 + AddAssign<Self>
347 let Pair(u, v) = other.decompose(); 347 + for<'b> AddAssign<&'b Self>
348 self.0.dot(u) + self.1.dot(v) 348 + SubAssign<Self>
349 } 349 + for<'b> SubAssign<&'b Self>
350 350 + Neg<Output = PairOutput<$field, A, B>>,
351 fn norm2_squared(&self) -> F { 351 {
352 self.0.norm2_squared() + self.1.norm2_squared() 352 type Output = PairOutput<$field, A, B>;
353 } 353
354 354 fn dot<I: Instance<Self>>(&self, other: I) -> $field {
355 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { 355 let Pair(u, v) = other.decompose();
356 let Pair(u, v) = other.decompose(); 356 self.0.dot(u) + self.1.dot(v)
357 self.0.dist2_squared(u) + self.1.dist2_squared(v) 357 }
358 } 358
359 } 359 fn norm2_squared(&self) -> $field {
360 self.0.norm2_squared() + self.1.norm2_squared()
361 }
362
363 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> $field {
364 let Pair(u, v) = other.decompose();
365 self.0.dist2_squared(u) + self.1.dist2_squared(v)
366 }
367 }
368 };
369 }
370
371 impl_euclidean!(f32);
372 impl_euclidean!(f64);
360 373
361 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> 374 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B>
362 where 375 where
363 U: Space, 376 U: Space,
364 V: Space, 377 V: Space,

mercurial