| 4 */ | 4 */ | 
| 5 | 5 | 
| 6 use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut}; | 6 use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut}; | 
| 7 use std::slice::{Iter,IterMut}; | 7 use std::slice::{Iter,IterMut}; | 
| 8 use std::fmt::{Display, Formatter}; | 8 use std::fmt::{Display, Formatter}; | 
|  | 9 use std::borrow::Borrow; | 
| 9 use crate::types::{Float,Num,SignedNum}; | 10 use crate::types::{Float,Num,SignedNum}; | 
| 10 use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut}; | 11 use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut}; | 
| 11 use crate::euclidean::*; | 12 use crate::euclidean::*; | 
| 12 use crate::norms::*; | 13 use crate::norms::*; | 
| 13 use crate::linops::AXPY; | 14 use crate::linops::AXPY; | 
| 20 #[derive(Copy,Clone,Debug,PartialEq,Eq)] | 21 #[derive(Copy,Clone,Debug,PartialEq,Eq)] | 
| 21 pub struct Loc<F, const N : usize>( | 22 pub struct Loc<F, const N : usize>( | 
| 22     /// An array of the elements of the vector | 23     /// An array of the elements of the vector | 
| 23     pub [F; N] | 24     pub [F; N] | 
| 24 ); | 25 ); | 
|  | 26 | 
|  | 27 impl<F : Num, const N : usize> HasScalarField for Loc<F, N> { | 
|  | 28     type Field = F; | 
|  | 29 } | 
| 25 | 30 | 
| 26 impl<F : Display, const N : usize> Display for Loc<F, N>{ | 31 impl<F : Display, const N : usize> Display for Loc<F, N>{ | 
| 27     // Required method | 32     // Required method | 
| 28     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | 33     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | 
| 29          write!(f, "[")?; | 34          write!(f, "[")?; | 
| 424 | 429 | 
| 425 domination!(Linfinity, L1); | 430 domination!(Linfinity, L1); | 
| 426 domination!(Linfinity, L2); | 431 domination!(Linfinity, L2); | 
| 427 domination!(L2, L1); | 432 domination!(L2, L1); | 
| 428 | 433 | 
| 429 impl<F : Num,const N : usize> Dot<Loc<F, N>,F> for Loc<F, N> { | 434 impl<F : Num, T : Borrow<Loc<F, N>>, const N : usize> Dot<T> for Loc<F, N> { | 
| 430     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 435     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 
| 431     /// Use [`nalgebra`] for larger vectors. | 436     /// Use [`nalgebra`] for larger vectors. | 
| 432     #[inline] | 437     #[inline] | 
| 433     fn dot(&self, other : &Loc<F, N>) -> F { | 438     fn dot(&self, other : T) -> F { | 
| 434         self.0.iter() | 439         self.0.iter() | 
| 435               .zip(other.0.iter()) | 440               .zip(other.borrow().0.iter()) | 
| 436               .fold(F::ZERO, |m, (&v, &w)| m + v * w) | 441               .fold(F::ZERO, |m, (&v, &w)| m + v * w) | 
| 437     } | 442     } | 
| 438 } | 443 } | 
| 439 | 444 | 
| 440 impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> { | 445 impl<F : Float,const N : usize> Euclidean for Loc<F, N> { | 
| 441     type Output = Self; | 446     type Output = Self; | 
| 442 | 447 | 
| 443     #[inline] | 448     #[inline] | 
| 444     fn similar_origin(&self) -> Self { | 449     fn similar_origin(&self) -> Self { | 
| 445         Self::ORIGIN | 450         Self::ORIGIN | 
| 481 | 486 | 
| 482 impl<F : Num, const N : usize> Loc<F, N> { | 487 impl<F : Num, const N : usize> Loc<F, N> { | 
| 483     pub const ORIGIN : Self = Loc([F::ZERO; N]); | 488     pub const ORIGIN : Self = Loc([F::ZERO; N]); | 
| 484 } | 489 } | 
| 485 | 490 | 
| 486 impl<F : Float,const N : usize> StaticEuclidean<F> for Loc<F, N> { | 491 impl<F : Float,const N : usize> StaticEuclidean for Loc<F, N> { | 
| 487     #[inline] | 492     #[inline] | 
| 488     fn origin() -> Self { | 493     fn origin() -> Self { | 
| 489         Self::ORIGIN | 494         Self::ORIGIN | 
| 490     } | 495     } | 
| 491 } | 496 } | 
| 492 | 497 | 
| 493 impl<F : Float, const N : usize> Norm<F, L2> for Loc<F, N> { | 498 impl<F : Float, const N : usize> Norm<L2> for Loc<F, N> { | 
| 494     #[inline] | 499     #[inline] | 
| 495     fn norm(&self, _ : L2) -> F { self.norm2() } | 500     fn norm(&self, _ : L2) -> F { self.norm2() } | 
| 496 } | 501 } | 
| 497 | 502 | 
| 498 impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> { | 503 impl<F : Float, const N : usize> Dist<L2> for Loc<F, N> { | 
| 499     #[inline] | 504     #[inline] | 
| 500     fn dist(&self, other : &Self, _ : L2) -> F { self.dist2(other) } | 505     fn dist(&self, other : &Self, _ : L2) -> F { self.dist2(other) } | 
| 501 } | 506 } | 
| 502 | 507 | 
| 503 impl<F : Float, const N : usize> Norm<F, L1> for Loc<F, N> { | 508 impl<F : Float, const N : usize> Norm<L1> for Loc<F, N> { | 
| 504     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 509     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 
| 505     /// Use [`nalgebra`] for larger vectors. | 510     /// Use [`nalgebra`] for larger vectors. | 
| 506     #[inline] | 511     #[inline] | 
| 507     fn norm(&self, _ : L1) -> F { | 512     fn norm(&self, _ : L1) -> F { | 
| 508         self.iter().fold(F::ZERO, |m, v| m + v.abs()) | 513         self.iter().fold(F::ZERO, |m, v| m + v.abs()) | 
| 509     } | 514     } | 
| 510 } | 515 } | 
| 511 | 516 | 
| 512 impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> { | 517 impl<F : Float, const N : usize> Dist<L1> for Loc<F, N> { | 
| 513     #[inline] | 518     #[inline] | 
| 514     fn dist(&self, other : &Self, _ : L1) -> F { | 519     fn dist(&self, other : &Self, _ : L1) -> F { | 
| 515         self.iter() | 520         self.iter() | 
| 516             .zip(other.iter()) | 521             .zip(other.iter()) | 
| 517             .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) | 522             .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) | 
| 518     } | 523     } | 
| 519 } | 524 } | 
| 520 | 525 | 
| 521 impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> { | 526 impl<F : Float, const N : usize> Projection<Linfinity> for Loc<F, N> { | 
| 522     #[inline] | 527     #[inline] | 
| 523     fn proj_ball_mut(&mut self, ρ : F, _ : Linfinity) { | 528     fn proj_ball_mut(&mut self, ρ : F, _ : Linfinity) { | 
| 524         self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) | 529         self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) | 
| 525     } | 530     } | 
| 526 } | 531 } | 
| 527 | 532 | 
| 528 impl<F : Float, const N : usize> Norm<F, Linfinity> for Loc<F, N> { | 533 impl<F : Float, const N : usize> Norm<Linfinity> for Loc<F, N> { | 
| 529     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 534     /// This implementation is not stabilised as it's meant to be used for very small vectors. | 
| 530     /// Use [`nalgebra`] for larger vectors. | 535     /// Use [`nalgebra`] for larger vectors. | 
| 531     #[inline] | 536     #[inline] | 
| 532     fn norm(&self, _ : Linfinity) -> F { | 537     fn norm(&self, _ : Linfinity) -> F { | 
| 533         self.iter().fold(F::ZERO, |m, v| m.max(v.abs())) | 538         self.iter().fold(F::ZERO, |m, v| m.max(v.abs())) | 
| 534     } | 539     } | 
| 535 } | 540 } | 
| 536 | 541 | 
| 537 impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> { | 542 impl<F : Float, const N : usize> Dist<Linfinity> for Loc<F, N> { | 
| 538     #[inline] | 543     #[inline] | 
| 539     fn dist(&self, other : &Self, _ : Linfinity) -> F { | 544     fn dist(&self, other : &Self, _ : Linfinity) -> F { | 
| 540         self.iter() | 545         self.iter() | 
| 541             .zip(other.iter()) | 546             .zip(other.iter()) | 
| 542             .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) | 547             .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) | 
| 570     fn fl_iter(self) -> Self::Iter { | 575     fn fl_iter(self) -> Self::Iter { | 
| 571         self.iter() | 576         self.iter() | 
| 572     } | 577     } | 
| 573 } | 578 } | 
| 574 | 579 | 
| 575 impl<F : Num, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> { | 580 impl<'a, T : Borrow<Loc<F, N>>, F : Num, const N : usize> AXPY<F, T> for Loc<F, N> { | 
| 576 | 581     #[inline] | 
| 577     #[inline] | 582     fn axpy(&mut self, α : F, x : T, β : F) { | 
| 578     fn axpy(&mut self, α : F, x : &Loc<F, N>, β : F) { |  | 
| 579         if β == F::ZERO { | 583         if β == F::ZERO { | 
| 580             map2_mut(self, x, |yi, xi| { *yi = α * (*xi) }) | 584             map2_mut(self, x.borrow(), |yi, xi| { *yi = α * (*xi) }) | 
| 581         } else { | 585         } else { | 
| 582             map2_mut(self, x, |yi, xi| { *yi = β * (*yi) + α * (*xi) }) | 586             map2_mut(self, x.borrow(), |yi, xi| { *yi = β * (*yi) + α * (*xi) }) | 
| 583         } | 587         } | 
| 584     } | 588     } | 
| 585 | 589 | 
| 586     #[inline] | 590     #[inline] | 
| 587     fn copy_from(&mut self, x : &Loc<F, N>) { | 591     fn copy_from(&mut self, x : T) { | 
| 588         map2_mut(self, x, |yi, xi| *yi = *xi ) | 592         map2_mut(self, x.borrow(), |yi, xi| *yi = *xi ) | 
| 589     } | 593     } | 
| 590 } | 594 } |