src/nalgebra_support.rs

branch
dev
changeset 124
6aa955ad8122
parent 70
672aec2e1acd
child 129
d2994e34a5f5
equal deleted inserted replaced
122:495448cca603 124:6aa955ad8122
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 }
158 /*ed: &EuclideanNorm,*/ 195 /*ed: &EuclideanNorm,*/
159 m1: &Matrix<T, R1, C1, S1>, 196 m1: &Matrix<T, R1, C1, S1>,
160 m2: &Matrix<T, R2, C2, S2>, 197 m2: &Matrix<T, R2, C2, S2>,
161 ) -> T::SimdRealField 198 ) -> T::SimdRealField
162 where 199 where
163 T: SimdComplexField, 200 T: SimdComplexField,
164 R1: Dim, 201 R1: Dim,
165 C1: Dim, 202 C1: Dim,
166 S1: Storage<T, R1, C1>, 203 S1: Storage<T, R1, C1>,
167 R2: Dim, 204 R2: Dim,
168 C2: Dim, 205 C2: Dim,
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 }

mercurial