| 462 let diff = a - b; |
462 let diff = a - b; |
| 463 acc + diff.simd_modulus_squared() |
463 acc + diff.simd_modulus_squared() |
| 464 }) |
464 }) |
| 465 } |
465 } |
| 466 |
466 |
| 467 // TODO: should allow different input storages in `Euclidean`. |
467 impl<E, M, N, S> Euclidean<E> for Matrix<E, M, N, S> |
| 468 |
468 where |
| 469 impl<E, M, S> Euclidean<E> for Vector<E, M, S> |
469 M: Dim, |
| 470 where |
470 N: Dim, |
| 471 M: Dim, |
471 S: Storage<E, M, N>, |
| |
472 E: Float + Scalar + Zero + One + RealField, |
| |
473 DefaultAllocator: Allocator<M, N>, |
| |
474 ShapeConstraint: StridesOk<E, M, N, S>, |
| |
475 { |
| |
476 type PrincipalE = OMatrix<E, M, N>; |
| |
477 |
| |
478 #[inline] |
| |
479 fn dot<I: Instance<Self>>(&self, other: I) -> E { |
| |
480 other.eval_ref(|ref r| Matrix::<E, M, N, S>::dot(self, r)) |
| |
481 } |
| |
482 |
| |
483 #[inline] |
| |
484 fn norm2_squared(&self) -> E { |
| |
485 Matrix::<E, M, N, S>::norm_squared(self) |
| |
486 } |
| |
487 |
| |
488 #[inline] |
| |
489 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E { |
| |
490 other.eval_ref(|ref r| metric_distance_squared(self, r)) |
| |
491 } |
| |
492 } |
| |
493 |
| |
494 impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> |
| |
495 where |
| |
496 M: DimName, |
| 472 S: Storage<E, M>, |
497 S: Storage<E, M>, |
| 473 E: Float + Scalar + Zero + One + RealField, |
498 E: Float + Scalar + Zero + One + RealField, |
| 474 DefaultAllocator: Allocator<M>, |
499 DefaultAllocator: Allocator<M>, |
| 475 ShapeConstraint: StridesOk<E, M, U1, S>, |
500 ShapeConstraint: StridesOk<E, M, U1, S>, |
| 476 { |
501 { |
| 477 type PrincipalE = OVector<E, M>; |
502 #[inline] |
| 478 |
503 fn origin() -> OVector<E, M> { |
| 479 #[inline] |
504 OVector::zeros() |
| 480 fn dot<I: Instance<Self>>(&self, other: I) -> E { |
505 } |
| 481 other.eval_ref(|ref r| Vector::<E, M, S>::dot(self, r)) |
506 } |
| 482 } |
507 |
| 483 |
508 /// The default norm for `Vector` is [`L2`]. |
| 484 #[inline] |
509 impl<E, M, N, S> Normed<E> for Matrix<E, M, N, S> |
| 485 fn norm2_squared(&self) -> E { |
510 where |
| 486 Vector::<E, M, S>::norm_squared(self) |
511 M: Dim, |
| 487 } |
512 N: Dim, |
| 488 |
513 S: Storage<E, M, N>, |
| 489 #[inline] |
514 E: Float + Scalar + Zero + One + RealField, |
| 490 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E { |
515 DefaultAllocator: Allocator<M, N>, |
| 491 other.eval_ref(|ref r| metric_distance_squared(self, r)) |
516 ShapeConstraint: StridesOk<E, M, N, S>, |
| 492 } |
517 { |
| 493 } |
518 type NormExp = L2; |
| 494 |
519 |
| 495 impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> |
520 #[inline] |
| 496 where |
521 fn norm_exponent(&self) -> Self::NormExp { |
| 497 M: DimName, |
522 L2 |
| |
523 } |
| |
524 |
| |
525 #[inline] |
| |
526 fn is_zero(&self) -> bool { |
| |
527 Matrix::<E, M, N, S>::norm_squared(self) == E::ZERO |
| |
528 } |
| |
529 } |
| |
530 |
| |
531 impl<E, M, N, S> HasDual<E> for Matrix<E, M, N, S> |
| |
532 where |
| |
533 M: Dim, |
| |
534 N: Dim, |
| |
535 S: Storage<E, M, N>, |
| |
536 E: Float + Scalar + Zero + One + RealField, |
| |
537 DefaultAllocator: Allocator<M, N>, |
| |
538 ShapeConstraint: StridesOk<E, M, N, S>, |
| |
539 { |
| |
540 type DualSpace = OMatrix<E, M, N>; |
| |
541 |
| |
542 fn dual_origin(&self) -> OMatrix<E, M, N> { |
| |
543 let (m, n) = self.shape_generic(); |
| |
544 OMatrix::zeros_generic(m, n) |
| |
545 } |
| |
546 } |
| |
547 |
| |
548 impl<E, M, S> Norm<L1, E> for Vector<E, M, S> |
| |
549 where |
| |
550 M: Dim, |
| 498 S: Storage<E, M>, |
551 S: Storage<E, M>, |
| 499 E: Float + Scalar + Zero + One + RealField, |
552 E: Float + Scalar + Zero + One + RealField, |
| 500 DefaultAllocator: Allocator<M>, |
553 DefaultAllocator: Allocator<M>, |
| 501 ShapeConstraint: StridesOk<E, M, U1, S>, |
554 ShapeConstraint: StridesOk<E, M, U1, S>, |
| 502 { |
555 { |
| 503 #[inline] |
556 #[inline] |
| 504 fn origin() -> OVector<E, M> { |
557 fn norm(&self, _: L1) -> E { |
| 505 OVector::zeros() |
558 nalgebra::Norm::norm(&LpNorm(1), self) |
| 506 } |
559 } |
| 507 } |
560 } |
| 508 |
561 |
| 509 /// The default norm for `Vector` is [`L2`]. |
562 impl<E, M, S> Dist<L1, E> for Vector<E, M, S> |
| 510 impl<E, M, S> Normed<E> for Vector<E, M, S> |
|
| 511 where |
563 where |
| 512 M: Dim, |
564 M: Dim, |
| 513 S: Storage<E, M>, |
565 S: Storage<E, M>, |
| 514 E: Float + Scalar + Zero + One + RealField, |
566 E: Float + Scalar + Zero + One + RealField, |
| 515 DefaultAllocator: Allocator<M>, |
567 DefaultAllocator: Allocator<M>, |
| 516 ShapeConstraint: StridesOk<E, M, U1, S>, |
568 ShapeConstraint: StridesOk<E, M, U1, S>, |
| 517 { |
569 { |
| 518 type NormExp = L2; |
|
| 519 |
|
| 520 #[inline] |
|
| 521 fn norm_exponent(&self) -> Self::NormExp { |
|
| 522 L2 |
|
| 523 } |
|
| 524 |
|
| 525 #[inline] |
|
| 526 fn is_zero(&self) -> bool { |
|
| 527 Vector::<E, M, S>::norm_squared(self) == E::ZERO |
|
| 528 } |
|
| 529 } |
|
| 530 |
|
| 531 impl<E, M, S> HasDual<E> for Vector<E, M, S> |
|
| 532 where |
|
| 533 M: Dim, |
|
| 534 S: Storage<E, M>, |
|
| 535 E: Float + Scalar + Zero + One + RealField, |
|
| 536 DefaultAllocator: Allocator<M>, |
|
| 537 ShapeConstraint: StridesOk<E, M, U1, S>, |
|
| 538 { |
|
| 539 type DualSpace = OVector<E, M>; |
|
| 540 |
|
| 541 fn dual_origin(&self) -> OVector<E, M> { |
|
| 542 OVector::zeros_generic(M::from_usize(self.len()), Const) |
|
| 543 } |
|
| 544 } |
|
| 545 |
|
| 546 impl<E, M, S> Norm<L1, E> for Vector<E, M, S> |
|
| 547 where |
|
| 548 M: Dim, |
|
| 549 S: Storage<E, M>, |
|
| 550 E: Float + Scalar + Zero + One + RealField, |
|
| 551 DefaultAllocator: Allocator<M>, |
|
| 552 ShapeConstraint: StridesOk<E, M, U1, S>, |
|
| 553 { |
|
| 554 #[inline] |
|
| 555 fn norm(&self, _: L1) -> E { |
|
| 556 nalgebra::Norm::norm(&LpNorm(1), self) |
|
| 557 } |
|
| 558 } |
|
| 559 |
|
| 560 impl<E, M, S> Dist<L1, E> for Vector<E, M, S> |
|
| 561 where |
|
| 562 M: Dim, |
|
| 563 S: Storage<E, M> + Clone, |
|
| 564 E: Float + Scalar + Zero + One + RealField, |
|
| 565 DefaultAllocator: Allocator<M>, |
|
| 566 ShapeConstraint: StridesOk<E, M, U1, S>, |
|
| 567 { |
|
| 568 #[inline] |
570 #[inline] |
| 569 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E { |
571 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E { |
| 570 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r)) |
572 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r)) |
| 571 } |
573 } |
| 572 } |
574 } |
| 573 |
575 |
| 574 impl<E, M, S> Norm<L2, E> for Vector<E, M, S> |
576 impl<E, M, N, S> Norm<L2, E> for Matrix<E, M, N, S> |
| 575 where |
577 where |
| 576 M: Dim, |
578 M: Dim, |
| 577 S: Storage<E, M>, |
579 N: Dim, |
| 578 E: Float + Scalar + Zero + One + RealField, |
580 S: Storage<E, M, N>, |
| 579 DefaultAllocator: Allocator<M>, |
581 E: Float + Scalar + Zero + One + RealField, |
| 580 ShapeConstraint: StridesOk<E, M, U1, S>, |
582 DefaultAllocator: Allocator<M, N>, |
| |
583 ShapeConstraint: StridesOk<E, M, N, S>, |
| 581 { |
584 { |
| 582 #[inline] |
585 #[inline] |
| 583 fn norm(&self, _: L2) -> E { |
586 fn norm(&self, _: L2) -> E { |
| 584 nalgebra::Norm::norm(&LpNorm(2), self) |
587 nalgebra::Norm::norm(&LpNorm(2), self) |
| 585 } |
588 } |
| 586 } |
589 } |
| 587 |
590 |
| 588 impl<E, M, S> Dist<L2, E> for Vector<E, M, S> |
591 impl<E, M, N, S> Dist<L2, E> for Matrix<E, M, N, S> |
| 589 where |
592 where |
| 590 M: Dim, |
593 M: Dim, |
| 591 S: Storage<E, M> + Clone, |
594 N: Dim, |
| 592 E: Float + Scalar + Zero + One + RealField, |
595 S: Storage<E, M, N>, |
| 593 DefaultAllocator: Allocator<M>, |
596 E: Float + Scalar + Zero + One + RealField, |
| 594 ShapeConstraint: StridesOk<E, M, U1, S>, |
597 DefaultAllocator: Allocator<M, N>, |
| |
598 ShapeConstraint: StridesOk<E, M, N, S>, |
| 595 { |
599 { |
| 596 #[inline] |
600 #[inline] |
| 597 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E { |
601 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E { |
| 598 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r)) |
602 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r)) |
| 599 } |
603 } |
| 600 } |
604 } |
| 601 |
605 |
| 602 impl<E, M, S> Norm<Linfinity, E> for Vector<E, M, S> |
606 impl<E, M, N, S> Norm<Linfinity, E> for Matrix<E, M, N, S> |
| 603 where |
607 where |
| 604 M: Dim, |
608 M: Dim, |
| 605 S: Storage<E, M>, |
609 N: Dim, |
| 606 E: Float + Scalar + Zero + One + RealField, |
610 S: Storage<E, M, N>, |
| 607 DefaultAllocator: Allocator<M>, |
611 E: Float + Scalar + Zero + One + RealField, |
| 608 ShapeConstraint: StridesOk<E, M, U1, S>, |
612 DefaultAllocator: Allocator<M, N>, |
| |
613 ShapeConstraint: StridesOk<E, M, N, S>, |
| 609 { |
614 { |
| 610 #[inline] |
615 #[inline] |
| 611 fn norm(&self, _: Linfinity) -> E { |
616 fn norm(&self, _: Linfinity) -> E { |
| 612 nalgebra::Norm::norm(&UniformNorm, self) |
617 nalgebra::Norm::norm(&UniformNorm, self) |
| 613 } |
618 } |
| 614 } |
619 } |
| 615 |
620 |
| 616 impl<E, M, S> Dist<Linfinity, E> for Vector<E, M, S> |
621 impl<E, M, N, S> Dist<Linfinity, E> for Matrix<E, M, N, S> |
| 617 where |
622 where |
| 618 M: Dim, |
623 M: Dim, |
| 619 S: Storage<E, M> + Clone, |
624 N: Dim, |
| 620 E: Float + Scalar + Zero + One + RealField, |
625 S: Storage<E, M, N>, |
| 621 DefaultAllocator: Allocator<M>, |
626 E: Float + Scalar + Zero + One + RealField, |
| 622 ShapeConstraint: StridesOk<E, M, U1, S>, |
627 DefaultAllocator: Allocator<M, N>, |
| |
628 ShapeConstraint: StridesOk<E, M, N, S>, |
| 623 { |
629 { |
| 624 #[inline] |
630 #[inline] |
| 625 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E { |
631 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E { |
| 626 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r)) |
632 other.eval_ref(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r)) |
| 627 } |
633 } |