| 1 /*! |
1 /*! |
| 2 Norms, projections, etc. |
2 Norms, projections, etc. |
| 3 */ |
3 */ |
| 4 |
4 |
| 5 use crate::euclidean::*; |
5 use crate::euclidean::*; |
| 6 use crate::linops::AXPY; |
6 use crate::instance::Ownable; |
| |
7 use crate::linops::VectorSpace; |
| 7 use crate::mapping::{Instance, Mapping, Space}; |
8 use crate::mapping::{Instance, Mapping, Space}; |
| 8 use crate::types::*; |
9 use crate::types::*; |
| 9 use serde::{Deserialize, Serialize}; |
10 use serde::{Deserialize, Serialize}; |
| 10 use std::marker::PhantomData; |
11 use std::marker::PhantomData; |
| 11 |
12 |
| 121 /// # use alg_tools::loc::Loc; |
122 /// # use alg_tools::loc::Loc; |
| 122 /// let x = Loc([1.0, 2.0, 3.0]); |
123 /// let x = Loc([1.0, 2.0, 3.0]); |
| 123 /// |
124 /// |
| 124 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); |
125 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); |
| 125 /// ``` |
126 /// ``` |
| 126 pub trait Projection<F: Num, Exponent: NormExponent>: Norm<Exponent, F> + Sized |
127 pub trait Projection<F: Num, Exponent: NormExponent>: Ownable + Norm<Exponent, F> { |
| 127 where |
|
| 128 F: Float, |
|
| 129 { |
|
| 130 /// Projection of `self` to the `q`-norm-ball of radius ρ. |
128 /// Projection of `self` to the `q`-norm-ball of radius ρ. |
| 131 fn proj_ball(mut self, ρ: F, q: Exponent) -> Self { |
129 fn proj_ball(self, ρ: F, q: Exponent) -> Self::OwnedVariant; |
| 132 self.proj_ball_mut(ρ, q); |
130 } |
| 133 self |
131 |
| 134 } |
132 pub trait ProjectionMut<F: Num, Exponent: NormExponent>: Projection<F, Exponent> { |
| 135 |
|
| 136 /// In-place projection of `self` to the `q`-norm-ball of radius ρ. |
133 /// In-place projection of `self` to the `q`-norm-ball of radius ρ. |
| 137 fn proj_ball_mut(&mut self, ρ: F, q: Exponent); |
134 fn proj_ball_mut(&mut self, ρ: F, q: Exponent); |
| 138 } |
135 } |
| 139 |
136 |
| 140 /*impl<F : Float, E : Euclidean<F>> Norm<L2, F> for E { |
137 /*impl<F : Float, E : Euclidean<F>> Norm<L2, F> for E { |
| 144 fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) } |
141 fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) } |
| 145 }*/ |
142 }*/ |
| 146 |
143 |
| 147 impl<F: Float, E: Euclidean<F> + Norm<L2, F>> Projection<F, L2> for E { |
144 impl<F: Float, E: Euclidean<F> + Norm<L2, F>> Projection<F, L2> for E { |
| 148 #[inline] |
145 #[inline] |
| 149 fn proj_ball(self, ρ: F, _p: L2) -> Self { |
146 fn proj_ball(self, ρ: F, _p: L2) -> Self::OwnedVariant { |
| 150 self.proj_ball2(ρ) |
147 self.proj_ball2(ρ) |
| 151 } |
148 } |
| 152 |
149 } |
| |
150 |
| |
151 impl<F: Float, E: EuclideanMut<F> + Norm<L2, F>> ProjectionMut<F, L2> for E { |
| 153 #[inline] |
152 #[inline] |
| 154 fn proj_ball_mut(&mut self, ρ: F, _p: L2) { |
153 fn proj_ball_mut(&mut self, ρ: F, _p: L2) { |
| 155 self.proj_ball2_mut(ρ) |
154 self.proj_ball2_mut(ρ) |
| 156 } |
155 } |
| 157 } |
156 } |
| 227 fn is_zero(&self) -> bool { |
226 fn is_zero(&self) -> bool { |
| 228 self.norm_() == F::ZERO |
227 self.norm_() == F::ZERO |
| 229 } |
228 } |
| 230 } |
229 } |
| 231 |
230 |
| 232 pub trait HasDual<F: Num = f64>: Normed<F> + AXPY<Field = F> { |
231 pub trait HasDual<F: Num = f64>: Normed<F> + VectorSpace<Field = F> { |
| 233 type DualSpace: Normed<F> + AXPY<Field = F>; |
232 type DualSpace: Normed<F> + VectorSpace<Field = F>; |
| 234 |
233 |
| 235 fn dual_origin(&self) -> <Self::DualSpace as AXPY>::Owned; |
234 fn dual_origin(&self) -> <Self::DualSpace as VectorSpace>::Owned; |
| 236 } |
235 } |
| 237 |
236 |
| 238 /// Automatically implemented trait for reflexive spaces |
237 /// Automatically implemented trait for reflexive spaces |
| 239 pub trait Reflexive<F: Num = f64>: HasDual<F> |
238 pub trait Reflexive<F: Num = f64>: HasDual<F> |
| 240 where |
239 where |