src/euclidean.rs

changeset 90
b3c35d16affe
parent 64
4f6ca107ccb1
equal deleted inserted replaced
25:d14c877e14b7 90:b3c35d16affe
1 /*! 1 /*!
2 Euclidean spaces. 2 Euclidean spaces.
3 */ 3 */
4 4
5 use std::ops::{Mul, MulAssign, Div, DivAssign, Add, Sub, AddAssign, SubAssign, Neg};
5 use crate::types::*; 6 use crate::types::*;
6 use std::ops::{Mul, MulAssign, Div, DivAssign, Add, Sub, AddAssign, SubAssign, Neg}; 7 use crate::instance::Instance;
7 8 use crate::norms::{HasDual, Reflexive};
8 /// Space (type) with a defined dot product.
9 ///
10 /// `U` is the space of the multiplier, and `F` the space of scalars.
11 /// Since `U` ≠ `Self`, this trait can also implement dual products.
12 pub trait Dot<U, F> {
13 fn dot(&self, other : &U) -> F;
14 }
15 9
16 /// Space (type) with Euclidean and vector space structure 10 /// Space (type) with Euclidean and vector space structure
17 /// 11 ///
18 /// The type should implement vector space operations (addition, subtraction, scalar 12 /// The type should implement vector space operations (addition, subtraction, scalar
19 /// multiplication and scalar division) along with their assignment versions, as well 13 /// multiplication and scalar division) along with their assignment versions, as well
20 /// as the [`Dot`] product with respect to `Self`. 14 /// as an inner product.
21 pub trait Euclidean<F : Float> : Sized + Dot<Self,F> 15 pub trait Euclidean<F : Float> : HasDual<F, DualSpace=Self> + Reflexive<F>
22 + Mul<F, Output=<Self as Euclidean<F>>::Output> + MulAssign<F> 16 + Mul<F, Output=<Self as Euclidean<F>>::Output> + MulAssign<F>
23 + Div<F, Output=<Self as Euclidean<F>>::Output> + DivAssign<F> 17 + Div<F, Output=<Self as Euclidean<F>>::Output> + DivAssign<F>
24 + Add<Self, Output=<Self as Euclidean<F>>::Output> 18 + Add<Self, Output=<Self as Euclidean<F>>::Output>
25 + Sub<Self, Output=<Self as Euclidean<F>>::Output> 19 + Sub<Self, Output=<Self as Euclidean<F>>::Output>
26 + for<'b> Add<&'b Self, Output=<Self as Euclidean<F>>::Output> 20 + for<'b> Add<&'b Self, Output=<Self as Euclidean<F>>::Output>
27 + for<'b> Sub<&'b Self, Output=<Self as Euclidean<F>>::Output> 21 + for<'b> Sub<&'b Self, Output=<Self as Euclidean<F>>::Output>
28 + AddAssign<Self> + for<'b> AddAssign<&'b Self> 22 + AddAssign<Self> + for<'b> AddAssign<&'b Self>
29 + SubAssign<Self> + for<'b> SubAssign<&'b Self> 23 + SubAssign<Self> + for<'b> SubAssign<&'b Self>
30 + Neg<Output=<Self as Euclidean<F>>::Output> { 24 + Neg<Output=<Self as Euclidean<F>>::Output>
25 {
31 type Output : Euclidean<F>; 26 type Output : Euclidean<F>;
32 27
33 /// Returns origin of same dimensions as `self`. 28 // Inner product
34 fn similar_origin(&self) -> <Self as Euclidean<F>>::Output; 29 fn dot<I : Instance<Self>>(&self, other : I) -> F;
35 30
36 /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. 31 /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$.
37 #[inline] 32 ///
38 fn norm2_squared(&self) -> F { 33 /// This is not automatically implemented to avoid imposing
39 self.dot(self) 34 /// `for <'a> &'a Self : Instance<Self>` trait bound bloat.
40 } 35 fn norm2_squared(&self) -> F;
41 36
42 /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$, 37 /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$,
43 /// where `self` is $x$. 38 /// where `self` is $x$.
44 #[inline] 39 #[inline]
45 fn norm2_squared_div2(&self) -> F { 40 fn norm2_squared_div2(&self) -> F {
51 fn norm2(&self) -> F { 46 fn norm2(&self) -> F {
52 self.norm2_squared().sqrt() 47 self.norm2_squared().sqrt()
53 } 48 }
54 49
55 /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$. 50 /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$.
56 fn dist2_squared(&self, y : &Self) -> F; 51 fn dist2_squared<I : Instance<Self>>(&self, y : I) -> F;
57 52
58 /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$. 53 /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$.
59 #[inline] 54 #[inline]
60 fn dist2(&self, y : &Self) -> F { 55 fn dist2<I : Instance<Self>>(&self, y : I) -> F {
61 self.dist2_squared(y).sqrt() 56 self.dist2_squared(y).sqrt()
62 } 57 }
63 58
64 /// Projection to the 2-ball. 59 /// Projection to the 2-ball.
65 #[inline] 60 #[inline]

mercurial