src/loc.rs

branch
dev
changeset 171
fa8df5a14486
parent 166
20fa28637737
equal deleted inserted replaced
170:221728aeeb7e 171:fa8df5a14486
440 440
441 /// This implementation is not stabilised as it's meant to be used for very small vectors. 441 /// This implementation is not stabilised as it's meant to be used for very small vectors.
442 /// Use [`nalgebra`] for larger vectors. 442 /// Use [`nalgebra`] for larger vectors.
443 #[inline] 443 #[inline]
444 fn dot<I: Instance<Self>>(&self, other: I) -> F { 444 fn dot<I: Instance<Self>>(&self, other: I) -> F {
445 other.eval_ref_decompose(|r| { 445 other.eval_ref(|r| {
446 self.0 446 self.0
447 .iter() 447 .iter()
448 .zip(r.0.iter()) 448 .zip(r.0.iter())
449 .fold(F::ZERO, |m, (&v, &w)| m + v * w) 449 .fold(F::ZERO, |m, (&v, &w)| m + v * w)
450 }) 450 })
456 fn norm2_squared(&self) -> F { 456 fn norm2_squared(&self) -> F {
457 self.iter().fold(F::ZERO, |m, &v| m + v * v) 457 self.iter().fold(F::ZERO, |m, &v| m + v * v)
458 } 458 }
459 459
460 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { 460 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
461 other.eval_ref_decompose(|r| { 461 other.eval_ref(|r| {
462 self.iter().zip(r.iter()).fold(F::ZERO, |m, (&v, &w)| { 462 self.iter().zip(r.iter()).fold(F::ZERO, |m, (&v, &w)| {
463 let d = v - w; 463 let d = v - w;
464 m + d * d 464 m + d * d
465 }) 465 })
466 }) 466 })
478 478
479 #[inline] 479 #[inline]
480 fn dist2<I: Instance<Self>>(&self, other: I) -> F { 480 fn dist2<I: Instance<Self>>(&self, other: I) -> F {
481 // Optimisation for N==1 that avoids squaring and square rooting. 481 // Optimisation for N==1 that avoids squaring and square rooting.
482 if N == 1 { 482 if N == 1 {
483 other.eval_ref_decompose(|r| { 483 other.eval_ref(|r| unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs())
484 unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs()
485 })
486 } else { 484 } else {
487 self.dist2_squared(other).sqrt() 485 self.dist2_squared(other).sqrt()
488 } 486 }
489 } 487 }
490 } 488 }
641 } 639 }
642 640
643 impl<F: Float, const N: usize> Dist<L1, F> for Loc<N, F> { 641 impl<F: Float, const N: usize> Dist<L1, F> for Loc<N, F> {
644 #[inline] 642 #[inline]
645 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F { 643 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F {
646 other.eval_ref_decompose(|r| { 644 other.eval_ref(|r| {
647 self.iter() 645 self.iter()
648 .zip(r.iter()) 646 .zip(r.iter())
649 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs()) 647 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs())
650 }) 648 })
651 } 649 }
677 } 675 }
678 676
679 impl<F: Float, const N: usize> Dist<Linfinity, F> for Loc<N, F> { 677 impl<F: Float, const N: usize> Dist<Linfinity, F> for Loc<N, F> {
680 #[inline] 678 #[inline]
681 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F { 679 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F {
682 other.eval_ref_decompose(|r| { 680 other.eval_ref(|r| {
683 self.iter() 681 self.iter()
684 .zip(r.iter()) 682 .zip(r.iter())
685 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs())) 683 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs()))
686 }) 684 })
687 } 685 }
759 } 757 }
760 758
761 impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> { 759 impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> {
762 #[inline] 760 #[inline]
763 fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) { 761 fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) {
764 x.eval(|x̃| { 762 x.eval_ref(|x̃| {
765 if β == F::ZERO { 763 if β == F::ZERO {
766 map2_mut(self, x̃, |yi, xi| *yi = α * (*xi)) 764 map2_mut(self, x̃, |yi, xi| *yi = α * (*xi))
767 } else { 765 } else {
768 map2_mut(self, x̃, |yi, xi| *yi = β * (*yi) + α * (*xi)) 766 map2_mut(self, x̃, |yi, xi| *yi = β * (*yi) + α * (*xi))
769 } 767 }
770 }) 768 })
771 } 769 }
772 770
773 #[inline] 771 #[inline]
774 fn copy_from<I: Instance<Loc<N, F>>>(&mut self, x: I) { 772 fn copy_from<I: Instance<Loc<N, F>>>(&mut self, x: I) {
775 x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi)) 773 x.eval_ref(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi))
776 } 774 }
777 775
778 #[inline] 776 #[inline]
779 fn set_zero(&mut self) { 777 fn set_zero(&mut self) {
780 *self = Self::ORIGIN; 778 *self = Self::ORIGIN;

mercurial