| 309 // + for<'b> AddAssign<&'b Self> |
309 // + for<'b> AddAssign<&'b Self> |
| 310 // + SubAssign<Self> |
310 // + SubAssign<Self> |
| 311 // + for<'b> SubAssign<&'b Self> |
311 // + for<'b> SubAssign<&'b Self> |
| 312 // + Neg<Output = Self::OwnedEuclidean>, |
312 // + Neg<Output = Self::OwnedEuclidean>, |
| 313 { |
313 { |
| 314 type OwnedEuclidean = Pair<A::OwnedEuclidean, B::OwnedEuclidean>; |
314 type PrincipalE = Pair<A::PrincipalE, B::PrincipalE>; |
| 315 |
315 |
| 316 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
316 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
| 317 other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) |
317 other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) |
| 318 } |
318 } |
| 319 |
319 |
| 331 A: VectorSpace<Field = F>, |
331 A: VectorSpace<Field = F>, |
| 332 B: VectorSpace<Field = F>, |
332 B: VectorSpace<Field = F>, |
| 333 F: Num, |
333 F: Num, |
| 334 { |
334 { |
| 335 type Field = F; |
335 type Field = F; |
| 336 type Owned = Pair<A::Owned, B::Owned>; |
336 type PrincipalV = Pair<A::PrincipalV, B::PrincipalV>; |
| 337 |
337 |
| 338 /// Return a similar zero as `self`. |
338 /// Return a similar zero as `self`. |
| 339 fn similar_origin(&self) -> Self::Owned { |
339 fn similar_origin(&self) -> Self::PrincipalV { |
| 340 Pair(self.0.similar_origin(), self.1.similar_origin()) |
340 Pair(self.0.similar_origin(), self.1.similar_origin()) |
| 341 } |
341 } |
| 342 |
342 |
| 343 // #[inline] |
343 // #[inline] |
| 344 // fn into_owned(self) -> Self::Owned { |
344 // fn into_owned(self) -> Self::Owned { |
| 387 /// [`Decomposition`] for working with [`Pair`]s. |
387 /// [`Decomposition`] for working with [`Pair`]s. |
| 388 #[derive(Copy, Clone, Debug)] |
388 #[derive(Copy, Clone, Debug)] |
| 389 pub struct PairDecomposition<D, Q>(D, Q); |
389 pub struct PairDecomposition<D, Q>(D, Q); |
| 390 |
390 |
| 391 impl<A: Space, B: Space> Space for Pair<A, B> { |
391 impl<A: Space, B: Space> Space for Pair<A, B> { |
| 392 type OwnedSpace = Pair<A::OwnedSpace, B::OwnedSpace>; |
392 type Principal = Pair<A::Principal, B::Principal>; |
| 393 type Decomp = PairDecomposition<A::Decomp, B::Decomp>; |
393 type Decomp = PairDecomposition<A::Decomp, B::Decomp>; |
| 394 } |
394 } |
| 395 |
395 |
| 396 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q> |
396 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q> |
| 397 where |
397 where |
| 447 self.0 |
447 self.0 |
| 448 .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) |
448 .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) |
| 449 } |
449 } |
| 450 |
450 |
| 451 #[inline] |
451 #[inline] |
| 452 fn cow<'b>(self) -> MyCow<'b, Pair<A::OwnedSpace, B::OwnedSpace>> |
452 fn cow<'b>(self) -> MyCow<'b, Pair<A::Principal, B::Principal>> |
| 453 where |
453 where |
| 454 Self: 'b, |
454 Self: 'b, |
| 455 { |
455 { |
| 456 MyCow::Owned(Pair(self.0.own(), self.1.own())) |
456 MyCow::Owned(Pair(self.0.own(), self.1.own())) |
| 457 } |
457 } |
| 458 |
458 |
| 459 #[inline] |
459 #[inline] |
| 460 fn own(self) -> Pair<A::OwnedSpace, B::OwnedSpace> { |
460 fn own(self) -> Pair<A::Principal, B::Principal> { |
| 461 Pair(self.0.own(), self.1.own()) |
461 Pair(self.0.own(), self.1.own()) |
| 462 } |
462 } |
| 463 } |
463 } |
| 464 |
464 |
| 465 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V> |
465 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V> |
| 498 self.0 |
498 self.0 |
| 499 .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) |
499 .eval_ref_decompose(|a| self.1.eval_ref_decompose(|b| f(Pair(a, b)))) |
| 500 } |
500 } |
| 501 |
501 |
| 502 #[inline] |
502 #[inline] |
| 503 fn cow<'b>(self) -> MyCow<'b, Pair<A::OwnedSpace, B::OwnedSpace>> |
503 fn cow<'b>(self) -> MyCow<'b, Pair<A::Principal, B::Principal>> |
| 504 where |
504 where |
| 505 Self: 'b, |
505 Self: 'b, |
| 506 { |
506 { |
| 507 MyCow::Owned(self.own()) |
507 MyCow::Owned(self.own()) |
| 508 } |
508 } |
| 509 |
509 |
| 510 #[inline] |
510 #[inline] |
| 511 fn own(self) -> Pair<A::OwnedSpace, B::OwnedSpace> { |
511 fn own(self) -> Pair<A::Principal, B::Principal> { |
| 512 let Pair(ref u, ref v) = self; |
512 let Pair(ref u, ref v) = self; |
| 513 Pair(u.own(), v.own()) |
513 Pair(u.own(), v.own()) |
| 514 } |
514 } |
| 515 } |
515 } |
| 516 |
516 |
| 599 A: HasDual<F>, |
599 A: HasDual<F>, |
| 600 B: HasDual<F>, |
600 B: HasDual<F>, |
| 601 { |
601 { |
| 602 type DualSpace = Pair<A::DualSpace, B::DualSpace>; |
602 type DualSpace = Pair<A::DualSpace, B::DualSpace>; |
| 603 |
603 |
| 604 fn dual_origin(&self) -> <Self::DualSpace as VectorSpace>::Owned { |
604 fn dual_origin(&self) -> <Self::DualSpace as VectorSpace>::PrincipalV { |
| 605 Pair(self.0.dual_origin(), self.1.dual_origin()) |
605 Pair(self.0.dual_origin(), self.1.dual_origin()) |
| 606 } |
606 } |
| 607 } |
607 } |
| 608 |
608 |
| 609 #[cfg(feature = "pyo3")] |
609 #[cfg(feature = "pyo3")] |