117 /// # use alg_tools::loc::Loc; |
117 /// # use alg_tools::loc::Loc; |
118 /// let x = Loc([1.0, 2.0, 3.0]); |
118 /// let x = Loc([1.0, 2.0, 3.0]); |
119 /// |
119 /// |
120 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); |
120 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); |
121 /// ``` |
121 /// ``` |
122 pub trait Projection<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Euclidean<F> |
122 pub trait Projection<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Sized |
123 where F : Float { |
123 where F : Float { |
124 /// Projection of `self` to the `q`-norm-ball of radius ρ. |
124 /// Projection of `self` to the `q`-norm-ball of radius ρ. |
125 fn proj_ball(mut self, ρ : F, q : Exponent) -> Self { |
125 fn proj_ball(mut self, ρ : F, q : Exponent) -> Self { |
126 self.proj_ball_mut(ρ, q); |
126 self.proj_ball_mut(ρ, q); |
127 self |
127 self |
128 } |
128 } |
129 |
129 |
130 /// In-place projection of `self` to the `q`-norm-ball of radius ρ. |
130 /// In-place projection of `self` to the `q`-norm-ball of radius ρ. |
131 fn proj_ball_mut(&mut self, ρ : F, _q : Exponent); |
131 fn proj_ball_mut(&mut self, ρ : F, q : Exponent); |
132 } |
132 } |
133 |
133 |
134 /*impl<F : Float, E : Euclidean<F>> Norm<F, L2> for E { |
134 /*impl<F : Float, E : Euclidean<F>> Norm<F, L2> for E { |
135 #[inline] |
135 #[inline] |
136 fn norm(&self, _p : L2) -> F { self.norm2() } |
136 fn norm(&self, _p : L2) -> F { self.norm2() } |
200 fn apply<I : Instance<Domain>>(&self, x : I) -> F { |
200 fn apply<I : Instance<Domain>>(&self, x : I) -> F { |
201 x.eval(|r| r.norm(self.exponent)) |
201 x.eval(|r| r.norm(self.exponent)) |
202 } |
202 } |
203 } |
203 } |
204 |
204 |
|
205 pub trait Normed<F : Num = f64> : Space + Norm<F, Self::NormExp> { |
|
206 type NormExp : NormExponent; |
|
207 |
|
208 fn norm_exponent(&self) -> Self::NormExp; |
|
209 |
|
210 #[inline] |
|
211 fn norm_(&self) -> F { |
|
212 self.norm(self.norm_exponent()) |
|
213 } |
|
214 |
|
215 // fn similar_origin(&self) -> Self; |
|
216 |
|
217 fn is_zero(&self) -> bool; |
|
218 } |
|
219 |
|
220 pub trait HasDual<F : Num = f64> : Normed<F> { |
|
221 type DualSpace : Normed<F>; |
|
222 } |
|
223 |
|
224 pub trait Reflexive<F : Num = f64> : HasDual<F> |
|
225 where |
|
226 Self::DualSpace : HasDual<F, DualSpace = Self> |
|
227 { } |
|
228 |
|
229 |
|
230 pub trait HasDualExponent : NormExponent { |
|
231 type DualExp : NormExponent; |
|
232 |
|
233 fn dual_exponent(&self) -> Self::DualExp; |
|
234 } |
|
235 |
|
236 impl HasDualExponent for L2 { |
|
237 type DualExp = L2; |
|
238 |
|
239 #[inline] |
|
240 fn dual_exponent(&self) -> Self::DualExp { |
|
241 L2 |
|
242 } |
|
243 } |
|
244 |
|
245 impl HasDualExponent for L1 { |
|
246 type DualExp = Linfinity; |
|
247 |
|
248 #[inline] |
|
249 fn dual_exponent(&self) -> Self::DualExp { |
|
250 Linfinity |
|
251 } |
|
252 } |
|
253 |
|
254 |
|
255 impl HasDualExponent for Linfinity { |
|
256 type DualExp = L1; |
|
257 |
|
258 #[inline] |
|
259 fn dual_exponent(&self) -> Self::DualExp { |
|
260 L1 |
|
261 } |
|
262 } |
|
263 |
|
264 |
|
265 |
|
266 |