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