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 std::ops::{Mul, MulAssign, Div, DivAssign, Add, Sub, AddAssign, SubAssign, Neg}; |
6 use crate::types::*; |
6 use crate::types::*; |
7 use crate::mapping::Space; |
7 use crate::instance::Instance; |
8 |
8 use crate::norms::{HasDual, Reflexive}; |
9 /// Space (type) with a defined dot product. |
|
10 /// |
|
11 /// `U` is the space of the multiplier, and `F` the space of scalars. |
|
12 /// Since `U` ≠ `Self`, this trait can also implement dual products. |
|
13 pub trait Dot<U, F> { |
|
14 fn dot(&self, other : &U) -> F; |
|
15 } |
|
16 |
9 |
17 /// Space (type) with Euclidean and vector space structure |
10 /// Space (type) with Euclidean and vector space structure |
18 /// |
11 /// |
19 /// The type should implement vector space operations (addition, subtraction, scalar |
12 /// The type should implement vector space operations (addition, subtraction, scalar |
20 /// multiplication and scalar division) along with their assignment versions, as well |
13 /// multiplication and scalar division) along with their assignment versions, as well |
21 /// as the [`Dot`] product with respect to `Self`. |
14 /// as an inner product. |
22 pub trait Euclidean<F : Float> : Space + Dot<Self,F> |
15 pub trait Euclidean<F : Float> : HasDual<F, DualSpace=Self> + Reflexive<F> |
23 + Mul<F, Output=<Self as Euclidean<F>>::Output> + MulAssign<F> |
16 + Mul<F, Output=<Self as Euclidean<F>>::Output> + MulAssign<F> |
24 + Div<F, Output=<Self as Euclidean<F>>::Output> + DivAssign<F> |
17 + Div<F, Output=<Self as Euclidean<F>>::Output> + DivAssign<F> |
25 + Add<Self, Output=<Self as Euclidean<F>>::Output> |
18 + Add<Self, Output=<Self as Euclidean<F>>::Output> |
26 + Sub<Self, Output=<Self as Euclidean<F>>::Output> |
19 + Sub<Self, Output=<Self as Euclidean<F>>::Output> |
27 + for<'b> Add<&'b Self, Output=<Self as Euclidean<F>>::Output> |
20 + for<'b> Add<&'b Self, Output=<Self as Euclidean<F>>::Output> |
28 + for<'b> Sub<&'b Self, Output=<Self as Euclidean<F>>::Output> |
21 + for<'b> Sub<&'b Self, Output=<Self as Euclidean<F>>::Output> |
29 + AddAssign<Self> + for<'b> AddAssign<&'b Self> |
22 + AddAssign<Self> + for<'b> AddAssign<&'b Self> |
30 + SubAssign<Self> + for<'b> SubAssign<&'b Self> |
23 + SubAssign<Self> + for<'b> SubAssign<&'b Self> |
31 + Neg<Output=<Self as Euclidean<F>>::Output> { |
24 + Neg<Output=<Self as Euclidean<F>>::Output> |
|
25 { |
32 type Output : Euclidean<F>; |
26 type Output : Euclidean<F>; |
33 |
27 |
|
28 // Inner product |
|
29 fn dot<I : Instance<Self>>(&self, other : I) -> F; |
|
30 |
34 /// 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$. |
35 #[inline] |
32 /// |
36 fn norm2_squared(&self) -> F { |
33 /// This is not automatically implemented to avoid imposing |
37 self.dot(self) |
34 /// `for <'a> &'a Self : Instance<Self>` trait bound bloat. |
38 } |
35 fn norm2_squared(&self) -> F; |
39 |
36 |
40 /// 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$, |
41 /// where `self` is $x$. |
38 /// where `self` is $x$. |
42 #[inline] |
39 #[inline] |
43 fn norm2_squared_div2(&self) -> F { |
40 fn norm2_squared_div2(&self) -> F { |