src/euclidean.rs

branch
dev
changeset 150
c4e394a9c84c
parent 146
3f9a03f95457
child 151
402d717bb5c0
equal deleted inserted replaced
149:2f1798c65fd6 150:c4e394a9c84c
1 /*! 1 /*!
2 Euclidean spaces. 2 Euclidean spaces.
3 */ 3 */
4 4
5 use crate::instance::Instance; 5 use crate::instance::Instance;
6 use crate::linops::AXPY; 6 use crate::linops::{VectorSpace, AXPY};
7 use crate::norms::{HasDual, Reflexive}; 7 use crate::norms::{HasDual, Reflexive};
8 use crate::types::*; 8 use crate::types::*;
9 use std::ops::{Add, AddAssign, Sub, SubAssign}; 9 use std::ops::{Add, AddAssign, Sub, SubAssign};
10 10
11 pub mod wrap; 11 pub mod wrap;
12 12
13 // TODO: Euclidean & EuclideanMut
14 //
13 /// Space (type) with Euclidean and vector space structure 15 /// Space (type) with Euclidean and vector space structure
14 /// 16 ///
15 /// The type should implement vector space operations (addition, subtraction, scalar 17 /// The type should implement vector space operations (addition, subtraction, scalar
16 /// multiplication and scalar division) along with their assignment versions, as well 18 /// multiplication and scalar division) along with their assignment versions, as well
17 /// as an inner product. 19 /// as an inner product.
18 // TODO: remove F parameter, use AXPY::Field 20 // TODO: remove F parameter, use AXPY::Field
19 pub trait Euclidean<F: Float = f64>: 21 pub trait Euclidean<F: Float = f64>:
20 HasDual<F, DualSpace = Self> 22 HasDual<F, DualSpace = Self>
21 + AXPY<Field = F> 23 + VectorSpace<Field = F>
22 + Reflexive<F> 24 + Reflexive<F>
23 // TODO: move the following to AXPY 25 // TODO: move the following to AXPY
24 + for<'b> Add<&'b Self, Output = <Self as AXPY>::Owned> 26 + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned>
25 + for<'b> Sub<&'b Self, Output = <Self as AXPY>::Owned> 27 + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned>
26 + for<'b> AddAssign<&'b Self> 28 + for<'b> AddAssign<&'b Self>
27 + for<'b> SubAssign<&'b Self> 29 + for<'b> SubAssign<&'b Self>
28 { 30 {
29 // Inner product 31 // Inner product
30 fn dot<I: Instance<Self>>(&self, other: I) -> F; 32 fn dot<I: Instance<Self>>(&self, other: I) -> F;
57 self.dist2_squared(y).sqrt() 59 self.dist2_squared(y).sqrt()
58 } 60 }
59 61
60 /// Projection to the 2-ball. 62 /// Projection to the 2-ball.
61 #[inline] 63 #[inline]
62 fn proj_ball2(mut self, ρ: F) -> Self { 64 fn proj_ball2(self, ρ: F) -> Self::Owned {
63 self.proj_ball2_mut(ρ); 65 let r = self.norm2();
64 self 66 if r > ρ {
67 self * (ρ / r)
68 } else {
69 self.into_owned()
70 }
65 } 71 }
72 }
66 73
74 // TODO: remove F parameter, use AXPY::Field
75 pub trait EuclideanMut<F: Float = f64>:
76 Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self>
77 {
67 /// In-place projection to the 2-ball. 78 /// In-place projection to the 2-ball.
68 #[inline] 79 #[inline]
69 fn proj_ball2_mut(&mut self, ρ: F) { 80 fn proj_ball2_mut(&mut self, ρ: F) {
70 let r = self.norm2(); 81 let r = self.norm2();
71 if r > ρ { 82 if r > ρ {
72 *self *= ρ / r 83 *self *= ρ / r
73 } 84 }
74 } 85 }
75 } 86 }
76 87
88 impl<X, F: Float> EuclideanMut<F> for X where
89 X: Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self>
90 {
91 }
92
77 /// Trait for [`Euclidean`] spaces with dimensions known at compile time. 93 /// Trait for [`Euclidean`] spaces with dimensions known at compile time.
78 pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> { 94 pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> {
79 /// Returns the origin 95 /// Returns the origin
80 fn origin() -> <Self as AXPY>::Owned; 96 fn origin() -> <Self as VectorSpace>::Owned;
81 } 97 }

mercurial