src/norms.rs

branch
dev
changeset 124
6aa955ad8122
parent 113
d97fcf22a61c
child 131
8264d72aa347
child 138
593912dc3293
equal deleted inserted replaced
122:495448cca603 124:6aa955ad8122
90 /// # use alg_tools::loc::Loc; 90 /// # use alg_tools::loc::Loc;
91 /// let x = Loc([1.0, 2.0, 3.0]); 91 /// let x = Loc([1.0, 2.0, 3.0]);
92 /// 92 ///
93 /// println!("{}, {} {}", x.norm(L1), x.norm(L2), x.norm(Linfinity)) 93 /// println!("{}, {} {}", x.norm(L1), x.norm(L2), x.norm(Linfinity))
94 /// ``` 94 /// ```
95 pub trait Norm<F: Num, Exponent: NormExponent> { 95 pub trait Norm<Exponent: NormExponent, F: Num = f64> {
96 /// Calculate the norm. 96 /// Calculate the norm.
97 fn norm(&self, _p: Exponent) -> F; 97 fn norm(&self, _p: Exponent) -> F;
98 } 98 }
99 99
100 /// Indicates that the `Self`-[`Norm`] is dominated by the `Exponent`-`Norm` on the space 100 /// Indicates that the `Self`-[`Norm`] is dominated by the `Exponent`-`Norm` on the space
108 p_norm * self.norm_factor(p) 108 p_norm * self.norm_factor(p)
109 } 109 }
110 } 110 }
111 111
112 /// Trait for distances with respect to a norm. 112 /// Trait for distances with respect to a norm.
113 pub trait Dist<F: Num, Exponent: NormExponent>: Norm<F, Exponent> + Space { 113 pub trait Dist<F: Num, Exponent: NormExponent>: Norm<Exponent, F> + Space {
114 /// Calculate the distance 114 /// Calculate the distance
115 fn dist<I: Instance<Self>>(&self, other: I, _p: Exponent) -> F; 115 fn dist<I: Instance<Self>>(&self, other: I, _p: Exponent) -> F;
116 } 116 }
117 117
118 /// Trait for Euclidean projections to the `Exponent`-[`Norm`]-ball. 118 /// Trait for Euclidean projections to the `Exponent`-[`Norm`]-ball.
123 /// # use alg_tools::loc::Loc; 123 /// # use alg_tools::loc::Loc;
124 /// let x = Loc([1.0, 2.0, 3.0]); 124 /// let x = Loc([1.0, 2.0, 3.0]);
125 /// 125 ///
126 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); 126 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity));
127 /// ``` 127 /// ```
128 pub trait Projection<F: Num, Exponent: NormExponent>: Norm<F, Exponent> + Sized 128 pub trait Projection<F: Num, Exponent: NormExponent>: Norm<Exponent, F> + Sized
129 where 129 where
130 F: Float, 130 F: Float,
131 { 131 {
132 /// Projection of `self` to the `q`-norm-ball of radius ρ. 132 /// Projection of `self` to the `q`-norm-ball of radius ρ.
133 fn proj_ball(mut self, ρ: F, q: Exponent) -> Self { 133 fn proj_ball(mut self, ρ: F, q: Exponent) -> Self {
137 137
138 /// In-place projection of `self` to the `q`-norm-ball of radius ρ. 138 /// In-place projection of `self` to the `q`-norm-ball of radius ρ.
139 fn proj_ball_mut(&mut self, ρ: F, q: Exponent); 139 fn proj_ball_mut(&mut self, ρ: F, q: Exponent);
140 } 140 }
141 141
142 /*impl<F : Float, E : Euclidean<F>> Norm<F, L2> for E { 142 /*impl<F : Float, E : Euclidean<F>> Norm<L2, F> for E {
143 #[inline] 143 #[inline]
144 fn norm(&self, _p : L2) -> F { self.norm2() } 144 fn norm(&self, _p : L2) -> F { self.norm2() }
145 145
146 fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) } 146 fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) }
147 }*/ 147 }*/
148 148
149 impl<F: Float, E: Euclidean<F> + Norm<F, L2>> Projection<F, L2> for E { 149 impl<F: Float, E: Euclidean<F> + Norm<L2, F>> Projection<F, L2> for E {
150 #[inline] 150 #[inline]
151 fn proj_ball(self, ρ: F, _p: L2) -> Self { 151 fn proj_ball(self, ρ: F, _p: L2) -> Self {
152 self.proj_ball2(ρ) 152 self.proj_ball2(ρ)
153 } 153 }
154 154
174 } 174 }
175 } 175 }
176 } 176 }
177 } 177 }
178 178
179 impl<F: Float, E: Euclidean<F> + Normed<F, NormExp = L2>> Norm<F, HuberL1<F>> for E { 179 impl<F: Float, E: Euclidean<F> + Normed<F, NormExp = L2>> Norm<HuberL1<F>, F> for E {
180 fn norm(&self, huber: HuberL1<F>) -> F { 180 fn norm(&self, huber: HuberL1<F>) -> F {
181 huber.apply(self.norm2_squared()) 181 huber.apply(self.norm2_squared())
182 } 182 }
183 } 183 }
184 184
186 fn dist<I: Instance<Self>>(&self, other: I, huber: HuberL1<F>) -> F { 186 fn dist<I: Instance<Self>>(&self, other: I, huber: HuberL1<F>) -> F {
187 huber.apply(self.dist2_squared(other)) 187 huber.apply(self.dist2_squared(other))
188 } 188 }
189 } 189 }
190 190
191 // impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> { 191 // impl<F : Float, E : Norm<L2, F>> Norm<L21, F> for Vec<E> {
192 // fn norm(&self, _l21 : L21) -> F { 192 // fn norm(&self, _l21 : L21) -> F {
193 // self.iter().map(|e| e.norm(L2)).sum() 193 // self.iter().map(|e| e.norm(L2)).sum()
194 // } 194 // }
195 // } 195 // }
196 196
202 202
203 impl<E, F, Domain> Mapping<Domain> for NormMapping<F, E> 203 impl<E, F, Domain> Mapping<Domain> for NormMapping<F, E>
204 where 204 where
205 F: Float, 205 F: Float,
206 E: NormExponent, 206 E: NormExponent,
207 Domain: Space + Norm<F, E>, 207 Domain: Space + Norm<E, F>,
208 { 208 {
209 type Codomain = F; 209 type Codomain = F;
210 210
211 #[inline] 211 #[inline]
212 fn apply<I: Instance<Domain>>(&self, x: I) -> F { 212 fn apply<I: Instance<Domain>>(&self, x: I) -> F {
213 x.eval(|r| r.norm(self.exponent)) 213 x.eval(|r| r.norm(self.exponent))
214 } 214 }
215 } 215 }
216 216
217 pub trait Normed<F: Num = f64>: Space + Norm<F, Self::NormExp> { 217 pub trait Normed<F: Num = f64>: Space + Norm<Self::NormExp, F> {
218 type NormExp: NormExponent; 218 type NormExp: NormExponent;
219 219
220 fn norm_exponent(&self) -> Self::NormExp; 220 fn norm_exponent(&self) -> Self::NormExp;
221 221
222 #[inline] 222 #[inline]
281 macro_rules! impl_weighted_norm { 281 macro_rules! impl_weighted_norm {
282 ($exponent : ty) => { 282 ($exponent : ty) => {
283 impl<C, F, D> Norm<F, Weighted<$exponent, C>> for D 283 impl<C, F, D> Norm<F, Weighted<$exponent, C>> for D
284 where 284 where
285 F: Float, 285 F: Float,
286 D: Norm<F, $exponent>, 286 D: Norm<$exponent, F>,
287 C: Constant<Type = F>, 287 C: Constant<Type = F>,
288 { 288 {
289 fn norm(&self, e: Weighted<$exponent, C>) -> F { 289 fn norm(&self, e: Weighted<$exponent, C>) -> F {
290 let v = e.weight.value(); 290 let v = e.weight.value();
291 assert!(v > F::ZERO); 291 assert!(v > F::ZERO);

mercurial