src/loc.rs

branch
dev
changeset 81
d2acaaddd9af
parent 43
239aa32f0e7d
equal deleted inserted replaced
49:edb95d2b83cc 81:d2acaaddd9af
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, "[")?;
391 396
392 // Norms 397 // Norms
393 398
394 macro_rules! domination { 399 macro_rules! domination {
395 ($norm:ident, $dominates:ident) => { 400 ($norm:ident, $dominates:ident) => {
396 impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm { 401 impl<F : Float, const N : usize> Dominated<$dominates, Loc<F, N>> for $norm {
397 #[inline] 402 #[inline]
398 fn norm_factor(&self, _p : $dominates) -> F { 403 fn norm_factor(&self, _p : $dominates) -> F {
399 F::ONE 404 F::ONE
400 } 405 }
401 #[inline] 406 #[inline]
403 p_norm 408 p_norm
404 } 409 }
405 } 410 }
406 }; 411 };
407 ($norm:ident, $dominates:ident, $fn:path) => { 412 ($norm:ident, $dominates:ident, $fn:path) => {
408 impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm { 413 impl<F : Float, const N : usize> Dominated<$dominates, Loc<F, N>> for $norm {
409 #[inline] 414 #[inline]
410 fn norm_factor(&self, _p : $dominates) -> F { 415 fn norm_factor(&self, _p : $dominates) -> F {
411 $fn(F::cast_from(N)) 416 $fn(F::cast_from(N))
412 } 417 }
413 } 418 }
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 }

mercurial