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 |