| 6 It also provides [`ToNalgebraRealField`] as a vomit-inducingly ugly workaround to nalgebra |
6 It also provides [`ToNalgebraRealField`] as a vomit-inducingly ugly workaround to nalgebra |
| 7 force-feeding its own versions of the same basic mathematical methods on `f32` and `f64` as |
7 force-feeding its own versions of the same basic mathematical methods on `f32` and `f64` as |
| 8 [`num_traits`] does. |
8 [`num_traits`] does. |
| 9 */ |
9 */ |
| 10 |
10 |
| |
11 use crate::euclidean::*; |
| |
12 use crate::instance::Instance; |
| |
13 use crate::linops::*; |
| |
14 use crate::mapping::{BasicDecomposition, Space}; |
| |
15 use crate::norms::*; |
| |
16 use crate::types::Float; |
| |
17 use nalgebra::base::allocator::Allocator; |
| |
18 use nalgebra::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; |
| |
19 use nalgebra::base::dimension::*; |
| 11 use nalgebra::{ |
20 use nalgebra::{ |
| 12 Matrix, Storage, StorageMut, OMatrix, Dim, DefaultAllocator, Scalar, |
21 ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, OMatrix, OVector, |
| 13 ClosedAddAssign, ClosedMulAssign, SimdComplexField, Vector, OVector, RealField, |
22 RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, Vector, |
| 14 LpNorm, UniformNorm |
|
| 15 }; |
23 }; |
| 16 use nalgebra::base::constraint::{ |
24 use num_traits::identities::{One, Zero}; |
| 17 ShapeConstraint, SameNumberOfRows, SameNumberOfColumns |
|
| 18 }; |
|
| 19 use nalgebra::base::dimension::*; |
|
| 20 use nalgebra::base::allocator::Allocator; |
|
| 21 use std::ops::Mul; |
25 use std::ops::Mul; |
| 22 use num_traits::identities::{Zero, One}; |
26 |
| 23 use crate::linops::*; |
27 impl<SM, N, M, E> Space for Matrix<E, N, M, SM> |
| 24 use crate::euclidean::*; |
28 where |
| 25 use crate::mapping::{Space, BasicDecomposition}; |
29 SM: Storage<E, N, M> + Clone, |
| 26 use crate::types::Float; |
30 N: Dim, |
| 27 use crate::norms::*; |
31 M: Dim, |
| 28 use crate::instance::Instance; |
32 E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
| 29 |
33 DefaultAllocator: Allocator<N, M>, |
| 30 impl<SM,N,M,E> Space for Matrix<E,N,M,SM> |
|
| 31 where |
|
| 32 SM: Storage<E,N,M> + Clone, |
|
| 33 N : Dim, M : Dim, E : Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
|
| 34 DefaultAllocator : Allocator<N,M>, |
|
| 35 { |
34 { |
| 36 type Decomp = BasicDecomposition; |
35 type Decomp = BasicDecomposition; |
| 37 } |
36 } |
| 38 |
37 |
| 39 impl<SM,SV,N,M,K,E> Mapping<Matrix<E,M,K,SV>> for Matrix<E,N,M,SM> |
38 impl<SM, SV, N, M, K, E> Mapping<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM> |
| 40 where SM: Storage<E,N,M>, SV: Storage<E,M,K> + Clone, |
39 where |
| 41 N : Dim, M : Dim, K : Dim, E : Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
40 SM: Storage<E, N, M>, |
| 42 DefaultAllocator : Allocator<N,K>, |
41 SV: Storage<E, M, K> + Clone, |
| 43 DefaultAllocator : Allocator<M,K>, |
42 N: Dim, |
| 44 DefaultAllocator : Allocator<N,M>, |
43 M: Dim, |
| 45 DefaultAllocator : Allocator<M,N> { |
44 K: Dim, |
| 46 type Codomain = OMatrix<E,N,K>; |
45 E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
| 47 |
46 DefaultAllocator: Allocator<N, K>, |
| 48 #[inline] |
47 DefaultAllocator: Allocator<M, K>, |
| 49 fn apply<I : Instance<Matrix<E,M,K,SV>>>( |
48 DefaultAllocator: Allocator<N, M>, |
| 50 &self, x : I |
49 DefaultAllocator: Allocator<M, N>, |
| 51 ) -> Self::Codomain { |
50 { |
| |
51 type Codomain = OMatrix<E, N, K>; |
| |
52 |
| |
53 #[inline] |
| |
54 fn apply<I: Instance<Matrix<E, M, K, SV>>>(&self, x: I) -> Self::Codomain { |
| 52 x.either(|owned| self.mul(owned), |refr| self.mul(refr)) |
55 x.either(|owned| self.mul(owned), |refr| self.mul(refr)) |
| 53 } |
56 } |
| 54 } |
57 } |
| 55 |
58 |
| 56 |
59 impl<'a, SM, SV, N, M, K, E> Linear<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM> |
| 57 impl<'a, SM,SV,N,M,K,E> Linear<Matrix<E,M,K,SV>> for Matrix<E,N,M,SM> |
60 where |
| 58 where SM: Storage<E,N,M>, SV: Storage<E,M,K> + Clone, |
61 SM: Storage<E, N, M>, |
| 59 N : Dim, M : Dim, K : Dim, E : Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
62 SV: Storage<E, M, K> + Clone, |
| 60 DefaultAllocator : Allocator<N,K>, |
63 N: Dim, |
| 61 DefaultAllocator : Allocator<M,K>, |
64 M: Dim, |
| 62 DefaultAllocator : Allocator<N,M>, |
65 K: Dim, |
| 63 DefaultAllocator : Allocator<M,N> { |
66 E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, |
| 64 } |
67 DefaultAllocator: Allocator<N, K>, |
| 65 |
68 DefaultAllocator: Allocator<M, K>, |
| 66 impl<SM,SV1,SV2,N,M,K,E> GEMV<E, Matrix<E,M,K,SV1>, Matrix<E,N,K,SV2>> for Matrix<E,N,M,SM> |
69 DefaultAllocator: Allocator<N, M>, |
| 67 where SM: Storage<E,N,M>, SV1: Storage<E,M,K> + Clone, SV2: StorageMut<E,N,K>, |
70 DefaultAllocator: Allocator<M, N>, |
| 68 N : Dim, M : Dim, K : Dim, E : Scalar + Zero + One + Float, |
71 { |
| 69 DefaultAllocator : Allocator<N,K>, |
72 } |
| 70 DefaultAllocator : Allocator<M,K>, |
73 |
| 71 DefaultAllocator : Allocator<N,M>, |
74 impl<SM, SV1, SV2, N, M, K, E> GEMV<E, Matrix<E, M, K, SV1>, Matrix<E, N, K, SV2>> |
| 72 DefaultAllocator : Allocator<M,N> { |
75 for Matrix<E, N, M, SM> |
| 73 |
76 where |
| 74 #[inline] |
77 SM: Storage<E, N, M>, |
| 75 fn gemv<I : Instance<Matrix<E,M,K,SV1>>>( |
78 SV1: Storage<E, M, K> + Clone, |
| 76 &self, y : &mut Matrix<E,N,K,SV2>, α : E, x : I, β : E |
79 SV2: StorageMut<E, N, K>, |
| |
80 N: Dim, |
| |
81 M: Dim, |
| |
82 K: Dim, |
| |
83 E: Scalar + Zero + One + Float, |
| |
84 DefaultAllocator: Allocator<N, K>, |
| |
85 DefaultAllocator: Allocator<M, K>, |
| |
86 DefaultAllocator: Allocator<N, M>, |
| |
87 DefaultAllocator: Allocator<M, N>, |
| |
88 { |
| |
89 #[inline] |
| |
90 fn gemv<I: Instance<Matrix<E, M, K, SV1>>>( |
| |
91 &self, |
| |
92 y: &mut Matrix<E, N, K, SV2>, |
| |
93 α: E, |
| |
94 x: I, |
| |
95 β: E, |
| 77 ) { |
96 ) { |
| 78 x.eval(|x̃| Matrix::gemm(y, α, self, x̃, β)) |
97 x.eval(|x̃| Matrix::gemm(y, α, self, x̃, β)) |
| 79 } |
98 } |
| 80 |
99 |
| 81 #[inline] |
100 #[inline] |
| 82 fn apply_mut<'a, I : Instance<Matrix<E,M,K,SV1>>>(&self, y : &mut Matrix<E,N,K,SV2>, x : I) { |
101 fn apply_mut<'a, I: Instance<Matrix<E, M, K, SV1>>>(&self, y: &mut Matrix<E, N, K, SV2>, x: I) { |
| 83 x.eval(|x̃| self.mul_to(x̃, y)) |
102 x.eval(|x̃| self.mul_to(x̃, y)) |
| 84 } |
103 } |
| 85 } |
104 } |
| 86 |
105 |
| 87 impl<SM,SV1,M,E> AXPY<E, Vector<E,M,SV1>> for Vector<E,M,SM> |
106 impl<SM, SV1, M, E> AXPY<E, Vector<E, M, SV1>> for Vector<E, M, SM> |
| 88 where SM: StorageMut<E,M> + Clone, SV1: Storage<E,M> + Clone, |
107 where |
| 89 M : Dim, E : Scalar + Zero + One + Float, |
108 SM: StorageMut<E, M> + Clone, |
| 90 DefaultAllocator : Allocator<M> { |
109 SV1: Storage<E, M> + Clone, |
| |
110 M: Dim, |
| |
111 E: Scalar + Zero + One + Float, |
| |
112 DefaultAllocator: Allocator<M>, |
| |
113 { |
| 91 type Owned = OVector<E, M>; |
114 type Owned = OVector<E, M>; |
| 92 |
115 |
| 93 #[inline] |
116 #[inline] |
| 94 fn axpy<I : Instance<Vector<E,M,SV1>>>(&mut self, α : E, x : I, β : E) { |
117 fn axpy<I: Instance<Vector<E, M, SV1>>>(&mut self, α: E, x: I, β: E) { |
| 95 x.eval(|x̃| Matrix::axpy(self, α, x̃, β)) |
118 x.eval(|x̃| Matrix::axpy(self, α, x̃, β)) |
| 96 } |
119 } |
| 97 |
120 |
| 98 #[inline] |
121 #[inline] |
| 99 fn copy_from<I : Instance<Vector<E,M,SV1>>>(&mut self, y : I) { |
122 fn copy_from<I: Instance<Vector<E, M, SV1>>>(&mut self, y: I) { |
| 100 y.eval(|ỹ| Matrix::copy_from(self, ỹ)) |
123 y.eval(|ỹ| Matrix::copy_from(self, ỹ)) |
| 101 } |
124 } |
| 102 |
125 |
| 103 #[inline] |
126 #[inline] |
| 104 fn set_zero(&mut self) { |
127 fn set_zero(&mut self) { |
| 123 self.iter_mut().for_each(|v| *v *= ρ/n) |
146 self.iter_mut().for_each(|v| *v *= ρ/n) |
| 124 } |
147 } |
| 125 } |
148 } |
| 126 }*/ |
149 }*/ |
| 127 |
150 |
| 128 impl<SM,M,E> Projection<E, Linfinity> for Vector<E,M,SM> |
151 impl<SM, M, E> Projection<E, Linfinity> for Vector<E, M, SM> |
| 129 where SM: StorageMut<E,M> + Clone, |
152 where |
| 130 M : Dim, E : Scalar + Zero + One + Float + RealField, |
153 SM: StorageMut<E, M> + Clone, |
| 131 DefaultAllocator : Allocator<M> { |
154 M: Dim, |
| 132 #[inline] |
155 E: Scalar + Zero + One + Float + RealField, |
| 133 fn proj_ball_mut(&mut self, ρ : E, _ : Linfinity) { |
156 DefaultAllocator: Allocator<M>, |
| 134 self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
157 { |
| 135 } |
158 #[inline] |
| 136 } |
159 fn proj_ball_mut(&mut self, ρ: E, _: Linfinity) { |
| 137 |
160 self.iter_mut() |
| 138 impl<'own,SV1,SV2,SM,N,M,K,E> Adjointable<Matrix<E,M,K,SV1>, Matrix<E,N,K,SV2>> |
161 .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
| 139 for Matrix<E,N,M,SM> |
162 } |
| 140 where SM: Storage<E,N,M>, SV1: Storage<E,M,K> + Clone, SV2: Storage<E,N,K> + Clone, |
163 } |
| 141 N : Dim, M : Dim, K : Dim, E : Scalar + Zero + One + SimdComplexField, |
164 |
| 142 DefaultAllocator : Allocator<N,K>, |
165 impl<'own, SV1, SV2, SM, N, M, K, E> Adjointable<Matrix<E, M, K, SV1>, Matrix<E, N, K, SV2>> |
| 143 DefaultAllocator : Allocator<M,K>, |
166 for Matrix<E, N, M, SM> |
| 144 DefaultAllocator : Allocator<N,M>, |
167 where |
| 145 DefaultAllocator : Allocator<M,N> { |
168 SM: Storage<E, N, M>, |
| 146 type AdjointCodomain = OMatrix<E,M,K>; |
169 SV1: Storage<E, M, K> + Clone, |
| 147 type Adjoint<'a> = OMatrix<E,M,N> where SM : 'a; |
170 SV2: Storage<E, N, K> + Clone, |
| |
171 N: Dim, |
| |
172 M: Dim, |
| |
173 K: Dim, |
| |
174 E: Scalar + Zero + One + SimdComplexField, |
| |
175 DefaultAllocator: Allocator<N, K>, |
| |
176 DefaultAllocator: Allocator<M, K>, |
| |
177 DefaultAllocator: Allocator<N, M>, |
| |
178 DefaultAllocator: Allocator<M, N>, |
| |
179 { |
| |
180 type AdjointCodomain = OMatrix<E, M, K>; |
| |
181 type Adjoint<'a> |
| |
182 = OMatrix<E, M, N> |
| |
183 where |
| |
184 SM: 'a; |
| 148 |
185 |
| 149 #[inline] |
186 #[inline] |
| 150 fn adjoint(&self) -> Self::Adjoint<'_> { |
187 fn adjoint(&self) -> Self::Adjoint<'_> { |
| 151 Matrix::adjoint(self) |
188 Matrix::adjoint(self) |
| 152 } |
189 } |
| 175 }) |
212 }) |
| 176 } |
213 } |
| 177 |
214 |
| 178 // TODO: should allow different input storages in `Euclidean`. |
215 // TODO: should allow different input storages in `Euclidean`. |
| 179 |
216 |
| 180 impl<E,M,S> Euclidean<E> |
217 impl<E, M, S> Euclidean<E> for Vector<E, M, S> |
| 181 for Vector<E,M,S> |
218 where |
| 182 where M : Dim, |
219 M: Dim, |
| 183 S : StorageMut<E,M> + Clone, |
220 S: StorageMut<E, M> + Clone, |
| 184 E : Float + Scalar + Zero + One + RealField, |
221 E: Float + Scalar + Zero + One + RealField, |
| 185 DefaultAllocator : Allocator<M> { |
222 DefaultAllocator: Allocator<M>, |
| 186 |
223 { |
| 187 type Output = OVector<E, M>; |
224 type Output = OVector<E, M>; |
| 188 |
225 |
| 189 #[inline] |
226 #[inline] |
| 190 fn dot<I : Instance<Self>>(&self, other : I) -> E { |
227 fn dot<I: Instance<Self>>(&self, other: I) -> E { |
| 191 Vector::<E,M,S>::dot(self, other.ref_instance()) |
228 Vector::<E, M, S>::dot(self, other.ref_instance()) |
| 192 } |
229 } |
| 193 |
230 |
| 194 #[inline] |
231 #[inline] |
| 195 fn norm2_squared(&self) -> E { |
232 fn norm2_squared(&self) -> E { |
| 196 Vector::<E,M,S>::norm_squared(self) |
233 Vector::<E, M, S>::norm_squared(self) |
| 197 } |
234 } |
| 198 |
235 |
| 199 #[inline] |
236 #[inline] |
| 200 fn dist2_squared<I : Instance<Self>>(&self, other : I) -> E { |
237 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E { |
| 201 metric_distance_squared(self, other.ref_instance()) |
238 metric_distance_squared(self, other.ref_instance()) |
| 202 } |
239 } |
| 203 } |
240 } |
| 204 |
241 |
| 205 impl<E,M,S> StaticEuclidean<E> |
242 impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> |
| 206 for Vector<E,M,S> |
243 where |
| 207 where M : DimName, |
244 M: DimName, |
| 208 S : StorageMut<E,M> + Clone, |
245 S: StorageMut<E, M> + Clone, |
| 209 E : Float + Scalar + Zero + One + RealField, |
246 E: Float + Scalar + Zero + One + RealField, |
| 210 DefaultAllocator : Allocator<M> { |
247 DefaultAllocator: Allocator<M>, |
| 211 |
248 { |
| 212 #[inline] |
249 #[inline] |
| 213 fn origin() -> OVector<E, M> { |
250 fn origin() -> OVector<E, M> { |
| 214 OVector::zeros() |
251 OVector::zeros() |
| 215 } |
252 } |
| 216 } |
253 } |
| 217 |
254 |
| 218 /// The default norm for `Vector` is [`L2`]. |
255 /// The default norm for `Vector` is [`L2`]. |
| 219 impl<E,M,S> Normed<E> |
256 impl<E, M, S> Normed<E> for Vector<E, M, S> |
| 220 for Vector<E,M,S> |
257 where |
| 221 where M : Dim, |
258 M: Dim, |
| 222 S : Storage<E,M> + Clone, |
259 S: Storage<E, M> + Clone, |
| 223 E : Float + Scalar + Zero + One + RealField, |
260 E: Float + Scalar + Zero + One + RealField, |
| 224 DefaultAllocator : Allocator<M> { |
261 DefaultAllocator: Allocator<M>, |
| 225 |
262 { |
| 226 type NormExp = L2; |
263 type NormExp = L2; |
| 227 |
264 |
| 228 #[inline] |
265 #[inline] |
| 229 fn norm_exponent(&self) -> Self::NormExp { |
266 fn norm_exponent(&self) -> Self::NormExp { |
| 230 L2 |
267 L2 |
| 231 } |
268 } |
| 232 |
269 |
| 233 #[inline] |
270 #[inline] |
| 234 fn is_zero(&self) -> bool { |
271 fn is_zero(&self) -> bool { |
| 235 Vector::<E,M,S>::norm_squared(self) == E::ZERO |
272 Vector::<E, M, S>::norm_squared(self) == E::ZERO |
| 236 } |
273 } |
| 237 } |
274 } |
| 238 |
275 |
| 239 impl<E,M,S> HasDual<E> |
276 impl<E, M, S> HasDual<E> for Vector<E, M, S> |
| 240 for Vector<E,M,S> |
277 where |
| 241 where M : Dim, |
278 M: Dim, |
| 242 S : Storage<E,M> + Clone, |
279 S: Storage<E, M> + Clone, |
| 243 E : Float + Scalar + Zero + One + RealField, |
280 E: Float + Scalar + Zero + One + RealField, |
| 244 DefaultAllocator : Allocator<M> { |
281 DefaultAllocator: Allocator<M>, |
| |
282 { |
| 245 // TODO: Doesn't work with different storage formats. |
283 // TODO: Doesn't work with different storage formats. |
| 246 type DualSpace = Self; |
284 type DualSpace = Self; |
| 247 } |
285 } |
| 248 |
286 |
| 249 impl<E,M,S> Norm<E, L1> |
287 impl<E, M, S> Norm<L1, E> for Vector<E, M, S> |
| 250 for Vector<E,M,S> |
288 where |
| 251 where M : Dim, |
289 M: Dim, |
| 252 S : Storage<E,M>, |
290 S: Storage<E, M>, |
| 253 E : Float + Scalar + Zero + One + RealField, |
291 E: Float + Scalar + Zero + One + RealField, |
| 254 DefaultAllocator : Allocator<M> { |
292 DefaultAllocator: Allocator<M>, |
| 255 |
293 { |
| 256 #[inline] |
294 #[inline] |
| 257 fn norm(&self, _ : L1) -> E { |
295 fn norm(&self, _: L1) -> E { |
| 258 nalgebra::Norm::norm(&LpNorm(1), self) |
296 nalgebra::Norm::norm(&LpNorm(1), self) |
| 259 } |
297 } |
| 260 } |
298 } |
| 261 |
299 |
| 262 impl<E,M,S> Dist<E, L1> |
300 impl<E, M, S> Dist<E, L1> for Vector<E, M, S> |
| 263 for Vector<E,M,S> |
301 where |
| 264 where M : Dim, |
302 M: Dim, |
| 265 S : Storage<E,M> + Clone, |
303 S: Storage<E, M> + Clone, |
| 266 E : Float + Scalar + Zero + One + RealField, |
304 E: Float + Scalar + Zero + One + RealField, |
| 267 DefaultAllocator : Allocator<M> { |
305 DefaultAllocator: Allocator<M>, |
| 268 #[inline] |
306 { |
| 269 fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> E { |
307 #[inline] |
| |
308 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E { |
| 270 nalgebra::Norm::metric_distance(&LpNorm(1), self, other.ref_instance()) |
309 nalgebra::Norm::metric_distance(&LpNorm(1), self, other.ref_instance()) |
| 271 } |
310 } |
| 272 } |
311 } |
| 273 |
312 |
| 274 impl<E,M,S> Norm<E, L2> |
313 impl<E, M, S> Norm<L2, E> for Vector<E, M, S> |
| 275 for Vector<E,M,S> |
314 where |
| 276 where M : Dim, |
315 M: Dim, |
| 277 S : Storage<E,M>, |
316 S: Storage<E, M>, |
| 278 E : Float + Scalar + Zero + One + RealField, |
317 E: Float + Scalar + Zero + One + RealField, |
| 279 DefaultAllocator : Allocator<M> { |
318 DefaultAllocator: Allocator<M>, |
| 280 |
319 { |
| 281 #[inline] |
320 #[inline] |
| 282 fn norm(&self, _ : L2) -> E { |
321 fn norm(&self, _: L2) -> E { |
| 283 nalgebra::Norm::norm(&LpNorm(2), self) |
322 nalgebra::Norm::norm(&LpNorm(2), self) |
| 284 } |
323 } |
| 285 } |
324 } |
| 286 |
325 |
| 287 impl<E,M,S> Dist<E, L2> |
326 impl<E, M, S> Dist<E, L2> for Vector<E, M, S> |
| 288 for Vector<E,M,S> |
327 where |
| 289 where M : Dim, |
328 M: Dim, |
| 290 S : Storage<E,M> + Clone, |
329 S: Storage<E, M> + Clone, |
| 291 E : Float + Scalar + Zero + One + RealField, |
330 E: Float + Scalar + Zero + One + RealField, |
| 292 DefaultAllocator : Allocator<M> { |
331 DefaultAllocator: Allocator<M>, |
| 293 #[inline] |
332 { |
| 294 fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> E { |
333 #[inline] |
| |
334 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E { |
| 295 nalgebra::Norm::metric_distance(&LpNorm(2), self, other.ref_instance()) |
335 nalgebra::Norm::metric_distance(&LpNorm(2), self, other.ref_instance()) |
| 296 } |
336 } |
| 297 } |
337 } |
| 298 |
338 |
| 299 impl<E,M,S> Norm<E, Linfinity> |
339 impl<E, M, S> Norm<Linfinity, E> for Vector<E, M, S> |
| 300 for Vector<E,M,S> |
340 where |
| 301 where M : Dim, |
341 M: Dim, |
| 302 S : Storage<E,M>, |
342 S: Storage<E, M>, |
| 303 E : Float + Scalar + Zero + One + RealField, |
343 E: Float + Scalar + Zero + One + RealField, |
| 304 DefaultAllocator : Allocator<M> { |
344 DefaultAllocator: Allocator<M>, |
| 305 |
345 { |
| 306 #[inline] |
346 #[inline] |
| 307 fn norm(&self, _ : Linfinity) -> E { |
347 fn norm(&self, _: Linfinity) -> E { |
| 308 nalgebra::Norm::norm(&UniformNorm, self) |
348 nalgebra::Norm::norm(&UniformNorm, self) |
| 309 } |
349 } |
| 310 } |
350 } |
| 311 |
351 |
| 312 impl<E,M,S> Dist<E, Linfinity> |
352 impl<E, M, S> Dist<E, Linfinity> for Vector<E, M, S> |
| 313 for Vector<E,M,S> |
353 where |
| 314 where M : Dim, |
354 M: Dim, |
| 315 S : Storage<E,M> + Clone, |
355 S: Storage<E, M> + Clone, |
| 316 E : Float + Scalar + Zero + One + RealField, |
356 E: Float + Scalar + Zero + One + RealField, |
| 317 DefaultAllocator : Allocator<M> { |
357 DefaultAllocator: Allocator<M>, |
| 318 #[inline] |
358 { |
| 319 fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> E { |
359 #[inline] |
| |
360 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E { |
| 320 nalgebra::Norm::metric_distance(&UniformNorm, self, other.ref_instance()) |
361 nalgebra::Norm::metric_distance(&UniformNorm, self, other.ref_instance()) |
| 321 } |
362 } |
| 322 } |
363 } |
| 323 |
364 |
| 324 /// Helper trait to hide the symbols of [`nalgebra::RealField`]. |
365 /// Helper trait to hide the symbols of [`nalgebra::RealField`]. |
| 327 /// functions can piggyback `nalgebra::RealField` without exponsing themselves to it. |
368 /// functions can piggyback `nalgebra::RealField` without exponsing themselves to it. |
| 328 /// Thus methods from [`num_traits`] can be used directly without similarly named methods |
369 /// Thus methods from [`num_traits`] can be used directly without similarly named methods |
| 329 /// from [`nalgebra`] conflicting with them. Only when absolutely necessary to work with |
370 /// from [`nalgebra`] conflicting with them. Only when absolutely necessary to work with |
| 330 /// nalgebra, one can convert to the nalgebra view of the same type using the methods of |
371 /// nalgebra, one can convert to the nalgebra view of the same type using the methods of |
| 331 /// this trait. |
372 /// this trait. |
| 332 pub trait ToNalgebraRealField : Float { |
373 pub trait ToNalgebraRealField: Float { |
| 333 /// The nalgebra type corresponding to this type. Usually same as `Self`. |
374 /// The nalgebra type corresponding to this type. Usually same as `Self`. |
| 334 /// |
375 /// |
| 335 /// This type only carries `nalgebra` traits. |
376 /// This type only carries `nalgebra` traits. |
| 336 type NalgebraType : RealField; |
377 type NalgebraType: RealField; |
| 337 /// The “mixed” type corresponding to this type. Usually same as `Self`. |
378 /// The “mixed” type corresponding to this type. Usually same as `Self`. |
| 338 /// |
379 /// |
| 339 /// This type carries both `num_traits` and `nalgebra` traits. |
380 /// This type carries both `num_traits` and `nalgebra` traits. |
| 340 type MixedType : RealField + Float; |
381 type MixedType: RealField + Float; |
| 341 |
382 |
| 342 /// Convert to the nalgebra view of `self`. |
383 /// Convert to the nalgebra view of `self`. |
| 343 fn to_nalgebra(self) -> Self::NalgebraType; |
384 fn to_nalgebra(self) -> Self::NalgebraType; |
| 344 |
385 |
| 345 /// Convert to the mixed (nalgebra and num_traits) view of `self`. |
386 /// Convert to the mixed (nalgebra and num_traits) view of `self`. |
| 346 fn to_nalgebra_mixed(self) -> Self::MixedType; |
387 fn to_nalgebra_mixed(self) -> Self::MixedType; |
| 347 |
388 |
| 348 /// Convert from the nalgebra view of `self`. |
389 /// Convert from the nalgebra view of `self`. |
| 349 fn from_nalgebra(t : Self::NalgebraType) -> Self; |
390 fn from_nalgebra(t: Self::NalgebraType) -> Self; |
| 350 |
391 |
| 351 /// Convert from the mixed (nalgebra and num_traits) view to `self`. |
392 /// Convert from the mixed (nalgebra and num_traits) view to `self`. |
| 352 fn from_nalgebra_mixed(t : Self::MixedType) -> Self; |
393 fn from_nalgebra_mixed(t: Self::MixedType) -> Self; |
| 353 } |
394 } |
| 354 |
395 |
| 355 impl ToNalgebraRealField for f32 { |
396 impl ToNalgebraRealField for f32 { |
| 356 type NalgebraType = f32; |
397 type NalgebraType = f32; |
| 357 type MixedType = f32; |
398 type MixedType = f32; |
| 358 |
399 |
| 359 #[inline] |
400 #[inline] |
| 360 fn to_nalgebra(self) -> Self::NalgebraType { self } |
401 fn to_nalgebra(self) -> Self::NalgebraType { |
| 361 |
402 self |
| 362 #[inline] |
403 } |
| 363 fn to_nalgebra_mixed(self) -> Self::MixedType { self } |
404 |
| 364 |
405 #[inline] |
| 365 #[inline] |
406 fn to_nalgebra_mixed(self) -> Self::MixedType { |
| 366 fn from_nalgebra(t : Self::NalgebraType) -> Self { t } |
407 self |
| 367 |
408 } |
| 368 #[inline] |
409 |
| 369 fn from_nalgebra_mixed(t : Self::MixedType) -> Self { t } |
410 #[inline] |
| 370 |
411 fn from_nalgebra(t: Self::NalgebraType) -> Self { |
| |
412 t |
| |
413 } |
| |
414 |
| |
415 #[inline] |
| |
416 fn from_nalgebra_mixed(t: Self::MixedType) -> Self { |
| |
417 t |
| |
418 } |
| 371 } |
419 } |
| 372 |
420 |
| 373 impl ToNalgebraRealField for f64 { |
421 impl ToNalgebraRealField for f64 { |
| 374 type NalgebraType = f64; |
422 type NalgebraType = f64; |
| 375 type MixedType = f64; |
423 type MixedType = f64; |
| 376 |
424 |
| 377 #[inline] |
425 #[inline] |
| 378 fn to_nalgebra(self) -> Self::NalgebraType { self } |
426 fn to_nalgebra(self) -> Self::NalgebraType { |
| 379 |
427 self |
| 380 #[inline] |
428 } |
| 381 fn to_nalgebra_mixed(self) -> Self::MixedType { self } |
429 |
| 382 |
430 #[inline] |
| 383 #[inline] |
431 fn to_nalgebra_mixed(self) -> Self::MixedType { |
| 384 fn from_nalgebra(t : Self::NalgebraType) -> Self { t } |
432 self |
| 385 |
433 } |
| 386 #[inline] |
434 |
| 387 fn from_nalgebra_mixed(t : Self::MixedType) -> Self { t } |
435 #[inline] |
| 388 } |
436 fn from_nalgebra(t: Self::NalgebraType) -> Self { |
| 389 |
437 t |
| |
438 } |
| |
439 |
| |
440 #[inline] |
| |
441 fn from_nalgebra_mixed(t: Self::MixedType) -> Self { |
| |
442 t |
| |
443 } |
| |
444 } |