| 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; |