src/loc.rs

branch
dev
changeset 64
4f6ca107ccb1
parent 63
f7b87d84864d
child 80
f802ddbabcfc
child 82
981069ef919b
child 86
d5b0e496b72f
equal deleted inserted replaced
63:f7b87d84864d 64:4f6ca107ccb1
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

mercurial