| 446 #[inline] |
446 #[inline] |
| 447 fn norm2_squared(&self) -> F { |
447 fn norm2_squared(&self) -> F { |
| 448 self.iter().fold(F::ZERO, |m, &v| m + v * v) |
448 self.iter().fold(F::ZERO, |m, &v| m + v * v) |
| 449 } |
449 } |
| 450 |
450 |
| 451 fn dist2_squared(&self, other : &Self) -> F { |
451 fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F { |
| 452 self.iter() |
452 self.iter() |
| 453 .zip(other.iter()) |
453 .zip(other.ref_instance().iter()) |
| 454 .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d }) |
454 .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d }) |
| 455 } |
455 } |
| 456 |
456 |
| 457 #[inline] |
457 #[inline] |
| 458 fn norm2(&self) -> F { |
458 fn norm2(&self) -> F { |
| 463 self.norm2_squared().sqrt() |
463 self.norm2_squared().sqrt() |
| 464 } |
464 } |
| 465 } |
465 } |
| 466 |
466 |
| 467 #[inline] |
467 #[inline] |
| 468 fn dist2(&self, other : &Self) -> F { |
468 fn dist2<I : Instance<Self>>(&self, other : I) -> F { |
| 469 // Optimisation for N==1 that avoids squaring and square rooting. |
469 // Optimisation for N==1 that avoids squaring and square rooting. |
| |
470 let otherr = other.ref_instance(); |
| 470 if N==1 { |
471 if N==1 { |
| 471 unsafe { *self.0.get_unchecked(0) - *other.0.get_unchecked(0) }.abs() |
472 unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs() |
| 472 } else { |
473 } else { |
| 473 self.dist2_squared(other).sqrt() |
474 self.dist2_squared(other).sqrt() |
| 474 } |
475 } |
| 475 } |
476 } |
| 476 } |
477 } |
| 601 fn norm(&self, _ : L2) -> F { self.norm2() } |
602 fn norm(&self, _ : L2) -> F { self.norm2() } |
| 602 } |
603 } |
| 603 |
604 |
| 604 impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> { |
605 impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> { |
| 605 #[inline] |
606 #[inline] |
| 606 fn dist(&self, other : &Self, _ : L2) -> F { self.dist2(other) } |
607 fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> F { self.dist2(other) } |
| 607 } |
608 } |
| 608 |
609 |
| 609 /* Implemented automatically as Euclidean. |
610 /* Implemented automatically as Euclidean. |
| 610 impl<F : Float, const N : usize> Projection<F, L2> for Loc<F, N> { |
611 impl<F : Float, const N : usize> Projection<F, L2> for Loc<F, N> { |
| 611 #[inline] |
612 #[inline] |
| 626 } |
627 } |
| 627 } |
628 } |
| 628 |
629 |
| 629 impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> { |
630 impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> { |
| 630 #[inline] |
631 #[inline] |
| 631 fn dist(&self, other : &Self, _ : L1) -> F { |
632 fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> F { |
| 632 self.iter() |
633 self.iter() |
| 633 .zip(other.iter()) |
634 .zip(other.ref_instance().iter()) |
| 634 .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) |
635 .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) |
| 635 } |
636 } |
| 636 } |
637 } |
| 637 |
638 |
| 638 impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> { |
639 impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> { |
| 651 } |
652 } |
| 652 } |
653 } |
| 653 |
654 |
| 654 impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> { |
655 impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> { |
| 655 #[inline] |
656 #[inline] |
| 656 fn dist(&self, other : &Self, _ : Linfinity) -> F { |
657 fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> F { |
| 657 self.iter() |
658 self.iter() |
| 658 .zip(other.iter()) |
659 .zip(other.ref_instance().iter()) |
| 659 .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) |
660 .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) |
| 660 } |
661 } |
| 661 } |
662 } |
| 662 |
663 |
| 663 |
664 |