src/loc.rs

branch
dev
changeset 133
2b13f8a0c8ba
parent 132
89371dc4d637
child 138
593912dc3293
equal deleted inserted replaced
132:89371dc4d637 133:2b13f8a0c8ba
435 impl<F: Float, const N: usize> Euclidean<F> for Loc<N, F> { 435 impl<F: Float, const N: usize> Euclidean<F> for Loc<N, F> {
436 /// This implementation is not stabilised as it's meant to be used for very small vectors. 436 /// This implementation is not stabilised as it's meant to be used for very small vectors.
437 /// Use [`nalgebra`] for larger vectors. 437 /// Use [`nalgebra`] for larger vectors.
438 #[inline] 438 #[inline]
439 fn dot<I: Instance<Self>>(&self, other: I) -> F { 439 fn dot<I: Instance<Self>>(&self, other: I) -> F {
440 self.0 440 other.eval_ref_decompose(|r| {
441 .iter() 441 self.0
442 .zip(other.ref_instance().0.iter()) 442 .iter()
443 .fold(F::ZERO, |m, (&v, &w)| m + v * w) 443 .zip(r.0.iter())
444 .fold(F::ZERO, |m, (&v, &w)| m + v * w)
445 })
444 } 446 }
445 447
446 /// This implementation is not stabilised as it's meant to be used for very small vectors. 448 /// This implementation is not stabilised as it's meant to be used for very small vectors.
447 /// Use [`nalgebra`] for larger vectors. 449 /// Use [`nalgebra`] for larger vectors.
448 #[inline] 450 #[inline]
449 fn norm2_squared(&self) -> F { 451 fn norm2_squared(&self) -> F {
450 self.iter().fold(F::ZERO, |m, &v| m + v * v) 452 self.iter().fold(F::ZERO, |m, &v| m + v * v)
451 } 453 }
452 454
453 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { 455 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
454 self.iter() 456 other.eval_ref_decompose(|r| {
455 .zip(other.ref_instance().iter()) 457 self.iter().zip(r.iter()).fold(F::ZERO, |m, (&v, &w)| {
456 .fold(F::ZERO, |m, (&v, &w)| {
457 let d = v - w; 458 let d = v - w;
458 m + d * d 459 m + d * d
459 }) 460 })
461 })
460 } 462 }
461 463
462 #[inline] 464 #[inline]
463 fn norm2(&self) -> F { 465 fn norm2(&self) -> F {
464 // Optimisation for N==1 that avoids squaring and square rooting. 466 // Optimisation for N==1 that avoids squaring and square rooting.
470 } 472 }
471 473
472 #[inline] 474 #[inline]
473 fn dist2<I: Instance<Self>>(&self, other: I) -> F { 475 fn dist2<I: Instance<Self>>(&self, other: I) -> F {
474 // Optimisation for N==1 that avoids squaring and square rooting. 476 // Optimisation for N==1 that avoids squaring and square rooting.
475 let otherr = other.ref_instance();
476 if N == 1 { 477 if N == 1 {
477 unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs() 478 other.eval_ref_decompose(|r| {
479 unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs()
480 })
478 } else { 481 } else {
479 self.dist2_squared(other).sqrt() 482 self.dist2_squared(other).sqrt()
480 } 483 }
481 } 484 }
482 } 485 }
629 } 632 }
630 633
631 impl<F: Float, const N: usize> Dist<F, L1> for Loc<N, F> { 634 impl<F: Float, const N: usize> Dist<F, L1> for Loc<N, F> {
632 #[inline] 635 #[inline]
633 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F { 636 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F {
634 self.iter() 637 other.eval_ref_decompose(|r| {
635 .zip(other.ref_instance().iter()) 638 self.iter()
636 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs()) 639 .zip(r.iter())
640 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs())
641 })
637 } 642 }
638 } 643 }
639 644
640 impl<F: Float, const N: usize> Projection<F, Linfinity> for Loc<N, F> { 645 impl<F: Float, const N: usize> Projection<F, Linfinity> for Loc<N, F> {
641 #[inline] 646 #[inline]
655 } 660 }
656 661
657 impl<F: Float, const N: usize> Dist<F, Linfinity> for Loc<N, F> { 662 impl<F: Float, const N: usize> Dist<F, Linfinity> for Loc<N, F> {
658 #[inline] 663 #[inline]
659 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F { 664 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F {
660 self.iter() 665 other.eval_ref_decompose(|r| {
661 .zip(other.ref_instance().iter()) 666 self.iter()
662 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs())) 667 .zip(r.iter())
668 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs()))
669 })
663 } 670 }
664 } 671 }
665 672
666 // Misc. 673 // Misc.
667 674
700 707
701 impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Loc<N, F> { 708 impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Loc<N, F> {
702 type Codomain = F; 709 type Codomain = F;
703 710
704 fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain { 711 fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain {
705 x.eval(|x̃| self.dot(x̃)) 712 x.eval_decompose(|x̃| self.dot(x̃))
706 } 713 }
707 } 714 }
708 715
709 impl<F: Float, const N: usize> Linear<Loc<N, F>> for Loc<N, F> {} 716 impl<F: Float, const N: usize> Linear<Loc<N, F>> for Loc<N, F> {}
710 717

mercurial