| 15 use crate::types::Float; |
15 use crate::types::Float; |
| 16 use nalgebra::base::allocator::Allocator; |
16 use nalgebra::base::allocator::Allocator; |
| 17 use nalgebra::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; |
17 use nalgebra::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; |
| 18 use nalgebra::base::dimension::*; |
18 use nalgebra::base::dimension::*; |
| 19 use nalgebra::{ |
19 use nalgebra::{ |
| 20 ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, MatrixView, OMatrix, |
20 ArrayStorage, ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, |
| 21 OVector, RawStorage, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, |
21 MatrixView, OMatrix, OVector, RawStorage, RealField, Scalar, SimdComplexField, Storage, |
| 22 Vector, U1, |
22 StorageMut, UniformNorm, VecStorage, Vector, ViewStorage, ViewStorageMut, U1, |
| 23 }; |
23 }; |
| 24 use num_traits::identities::{One, Zero}; |
24 use num_traits::identities::{One, Zero}; |
| 25 use std::ops::Mul; |
25 use std::ops::Mul; |
| 26 |
26 |
| 27 impl<S, M, N, E> Ownable for Matrix<E, M, N, S> |
27 impl<S, M, N, E> Ownable for Matrix<E, M, N, S> |
| 58 MyCow::Owned(self.clone_owned()) |
58 MyCow::Owned(self.clone_owned()) |
| 59 } |
59 } |
| 60 } |
60 } |
| 61 |
61 |
| 62 trait StridesOk<E, N, M = U1, S = <DefaultAllocator as Allocator<N, M>>::Buffer<E>>: |
62 trait StridesOk<E, N, M = U1, S = <DefaultAllocator as Allocator<N, M>>::Buffer<E>>: |
| 63 DimEq<Dyn, S::RStride> |
63 DimEq<Dyn, S::RStride> + DimEq<Dyn, S::CStride> |
| 64 + DimEq<Dyn, S::CStride> |
|
| 65 + DimEq<Dyn, <<DefaultAllocator as Allocator<N, M>>::Buffer<E> as RawStorage<E, N, M>>::RStride> |
|
| 66 + DimEq<Dyn, <<DefaultAllocator as Allocator<N, M>>::Buffer<E> as RawStorage<E, N, M>>::CStride> |
|
| 67 where |
64 where |
| 68 S: RawStorage<E, N, M>, |
65 S: RawStorage<E, N, M>, |
| 69 E: Scalar, |
66 E: Scalar, |
| 70 N: Dim, |
67 N: Dim, |
| 71 M: Dim, |
68 M: Dim, |
| 72 DefaultAllocator: Allocator<N, M>, |
69 DefaultAllocator: Allocator<N, M>, |
| 73 { |
70 { |
| 74 } |
71 } |
| 75 |
72 |
| 76 impl<S, E, N, M> StridesOk<E, N, M, S> for ShapeConstraint |
73 impl<E, M> StridesOk<E, Dyn, M, VecStorage<E, Dyn, M>> for ShapeConstraint |
| 77 where |
74 where |
| 78 ShapeConstraint: DimEq<Dyn, S::RStride> |
75 M: Dim, |
| 79 + DimEq<Dyn, S::CStride> |
|
| 80 + DimEq< |
|
| 81 Dyn, |
|
| 82 <<DefaultAllocator as Allocator<N, M>>::Buffer<E> as RawStorage<E, N, M>>::RStride, |
|
| 83 > + DimEq< |
|
| 84 Dyn, |
|
| 85 <<DefaultAllocator as Allocator<N, M>>::Buffer<E> as RawStorage<E, N, M>>::CStride, |
|
| 86 >, |
|
| 87 S: Storage<E, N, M>, |
|
| 88 E: Scalar, |
76 E: Scalar, |
| 89 N: Dim, |
77 DefaultAllocator: Allocator<Dyn, M>, |
| 90 M: Dim, |
78 { |
| 91 DefaultAllocator: Allocator<N, M>, |
79 } |
| 92 { |
80 |
| 93 } |
81 impl<E, const N: usize, const M: usize> StridesOk<E, Const<N>, Const<M>, ArrayStorage<E, N, M>> |
| |
82 for ShapeConstraint |
| |
83 where |
| |
84 E: Scalar, |
| |
85 { |
| |
86 } |
| |
87 |
| |
88 macro_rules! strides_ok { |
| |
89 ($R:ty, $C:ty where $($qual:tt)*) => { |
| |
90 impl<'a, E, N, M, $($qual)*> StridesOk<E, N, M, ViewStorage<'a, E, N, M, $R, $C>> for ShapeConstraint |
| |
91 where |
| |
92 N: Dim, |
| |
93 M: Dim, |
| |
94 E: Scalar, |
| |
95 DefaultAllocator: Allocator<N, M>, |
| |
96 { |
| |
97 } |
| |
98 impl<'a, E, N, M, $($qual)*> StridesOk<E, N, M, ViewStorageMut<'a, E, N, M, $R, $C>> for ShapeConstraint |
| |
99 where |
| |
100 N: Dim, |
| |
101 M: Dim, |
| |
102 E: Scalar, |
| |
103 DefaultAllocator: Allocator<N, M>, |
| |
104 { |
| |
105 } |
| |
106 }; |
| |
107 } |
| |
108 |
| |
109 strides_ok!(Dyn, Dyn where ); |
| |
110 strides_ok!(Dyn, Const<C> where const C : usize); |
| |
111 strides_ok!(Const<R>, Dyn where const R : usize); |
| |
112 strides_ok!(Const<R>, Const<C> where const R : usize, const C : usize); |
| 94 |
113 |
| 95 impl<SM, N, M, E> Space for Matrix<E, N, M, SM> |
114 impl<SM, N, M, E> Space for Matrix<E, N, M, SM> |
| 96 where |
115 where |
| 97 SM: Storage<E, N, M>, |
116 SM: Storage<E, N, M>, |
| 98 N: Dim, |
117 N: Dim, |
| 99 M: Dim, |
118 M: Dim, |
| 100 E: Scalar + Zero + One + Copy, |
119 E: Scalar + Zero + One + Copy, |
| 101 DefaultAllocator: Allocator<N, M>, |
120 DefaultAllocator: Allocator<N, M>, |
| 102 ShapeConstraint: StridesOk<E, N, M, SM> + StridesOk<E, N, M>, |
121 ShapeConstraint: StridesOk<E, N, M>, |
| 103 { |
122 { |
| 104 type Principal = OMatrix<E, N, M>; |
123 type Principal = OMatrix<E, N, M>; |
| 105 type Decomp = MatrixDecomposition; |
124 type Decomp = MatrixDecomposition; |
| 106 } |
125 } |
| 107 |
126 |
| 113 S: Storage<E, M, K>, |
132 S: Storage<E, M, K>, |
| 114 M: Dim, |
133 M: Dim, |
| 115 K: Dim, |
134 K: Dim, |
| 116 E: Scalar + Zero + One + Copy, |
135 E: Scalar + Zero + One + Copy, |
| 117 DefaultAllocator: Allocator<M, K>, |
136 DefaultAllocator: Allocator<M, K>, |
| 118 ShapeConstraint: StridesOk<E, M, K, S> + StridesOk<E, M, K>, |
137 ShapeConstraint: StridesOk<E, M, K>, |
| 119 { |
138 { |
| 120 type Decomposition<'b> |
139 type Decomposition<'b> |
| 121 = MyCow<'b, OMatrix<E, M, K>> |
140 = MyCow<'b, OMatrix<E, M, K>> |
| 122 where |
141 where |
| 123 Matrix<E, M, K, S>: 'b; |
142 Matrix<E, M, K, S>: 'b; |
| 141 S2: Storage<E, M, K>, |
160 S2: Storage<E, M, K>, |
| 142 M: Dim, |
161 M: Dim, |
| 143 K: Dim, |
162 K: Dim, |
| 144 E: Scalar + Zero + One + Copy, |
163 E: Scalar + Zero + One + Copy, |
| 145 DefaultAllocator: Allocator<M, K>, |
164 DefaultAllocator: Allocator<M, K>, |
| 146 ShapeConstraint: StridesOk<E, M, K, S1> + StridesOk<E, M, K, S2>, |
165 ShapeConstraint: StridesOk<E, M, K, S2> + StridesOk<E, M, K>, |
| 147 { |
166 { |
| 148 #[inline] |
167 #[inline] |
| 149 fn eval_ref<'b, R>( |
168 fn eval_ref<'b, R>( |
| 150 &'b self, |
169 &'b self, |
| 151 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
170 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
| 186 S2: Storage<E, M, K>, |
205 S2: Storage<E, M, K>, |
| 187 M: Dim, |
206 M: Dim, |
| 188 K: Dim, |
207 K: Dim, |
| 189 E: Scalar + Zero + One + Copy, |
208 E: Scalar + Zero + One + Copy, |
| 190 DefaultAllocator: Allocator<M, K>, |
209 DefaultAllocator: Allocator<M, K>, |
| 191 ShapeConstraint: StridesOk<E, M, K, S1> + StridesOk<E, M, K, S2>, |
210 ShapeConstraint: StridesOk<E, M, K, S2> + StridesOk<E, M, K>, |
| 192 { |
211 { |
| 193 fn eval_ref<'b, R>( |
212 fn eval_ref<'b, R>( |
| 194 &'b self, |
213 &'b self, |
| 195 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
214 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
| 196 ) -> R |
215 ) -> R |
| 229 S1: Storage<E, M, K>, |
248 S1: Storage<E, M, K>, |
| 230 M: Dim, |
249 M: Dim, |
| 231 K: Dim, |
250 K: Dim, |
| 232 E: Scalar + Zero + One + Copy, |
251 E: Scalar + Zero + One + Copy, |
| 233 DefaultAllocator: Allocator<M, K>, |
252 DefaultAllocator: Allocator<M, K>, |
| 234 ShapeConstraint: StridesOk<E, M, K, S1> + StridesOk<E, M, K>, |
253 ShapeConstraint: StridesOk<E, M, K>, |
| 235 { |
254 { |
| 236 #[inline] |
255 #[inline] |
| 237 fn eval_ref<'b, R>( |
256 fn eval_ref<'b, R>( |
| 238 &'b self, |
257 &'b self, |
| 239 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
258 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
| 273 N: Dim, |
292 N: Dim, |
| 274 M: Dim, |
293 M: Dim, |
| 275 K: Dim, |
294 K: Dim, |
| 276 E: Scalar + Zero + One + Copy + ClosedMulAssign + ClosedAddAssign, |
295 E: Scalar + Zero + One + Copy + ClosedMulAssign + ClosedAddAssign, |
| 277 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
296 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
| 278 ShapeConstraint: StridesOk<E, N, M, SM> + StridesOk<E, M, K> + StridesOk<E, N, K>, |
297 ShapeConstraint: StridesOk<E, M, K> + StridesOk<E, N, K>, |
| 279 { |
298 { |
| 280 type Codomain = OMatrix<E, N, K>; |
299 type Codomain = OMatrix<E, N, K>; |
| 281 |
300 |
| 282 #[inline] |
301 #[inline] |
| 283 fn apply<I: Instance<OMatrix<E, M, K>>>(&self, x: I) -> Self::Codomain { |
302 fn apply<I: Instance<OMatrix<E, M, K>>>(&self, x: I) -> Self::Codomain { |
| 291 N: Dim, |
310 N: Dim, |
| 292 M: Dim, |
311 M: Dim, |
| 293 K: Dim, |
312 K: Dim, |
| 294 E: Scalar + Zero + One + Copy + ClosedMulAssign + ClosedAddAssign, |
313 E: Scalar + Zero + One + Copy + ClosedMulAssign + ClosedAddAssign, |
| 295 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
314 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
| 296 ShapeConstraint: StridesOk<E, N, M, SM> + StridesOk<E, M, K> + StridesOk<E, N, K>, |
315 ShapeConstraint: StridesOk<E, M, K> + StridesOk<E, N, K>, |
| 297 { |
316 { |
| 298 } |
317 } |
| 299 |
318 |
| 300 impl<SM, SV2, N, M, K, E> GEMV<E, OMatrix<E, M, K>, Matrix<E, N, K, SV2>> for Matrix<E, N, M, SM> |
319 impl<SM, SV2, N, M, K, E> GEMV<E, OMatrix<E, M, K>, Matrix<E, N, K, SV2>> for Matrix<E, N, M, SM> |
| 301 where |
320 where |
| 304 N: Dim, |
323 N: Dim, |
| 305 M: Dim, |
324 M: Dim, |
| 306 K: Dim, |
325 K: Dim, |
| 307 E: Scalar + Zero + One + Float, |
326 E: Scalar + Zero + One + Float, |
| 308 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
327 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M>, |
| 309 ShapeConstraint: StridesOk<E, N, M, SM> + StridesOk<E, N, K, SV2> + StridesOk<E, M, K>, |
328 ShapeConstraint: StridesOk<E, M, K> + StridesOk<E, N, K>, |
| 310 { |
329 { |
| 311 #[inline] |
330 #[inline] |
| 312 fn gemv<I: Instance<OMatrix<E, M, K>>>( |
331 fn gemv<I: Instance<OMatrix<E, M, K>>>( |
| 313 &self, y: &mut Matrix<E, N, K, SV2>, α: E, x: I, β: E |
332 &self, y: &mut Matrix<E, N, K, SV2>, α: E, x: I, β: E |
| 314 ) { |
333 ) { |
| 346 SV1: Storage<E, M, N>, |
365 SV1: Storage<E, M, N>, |
| 347 M: Dim, |
366 M: Dim, |
| 348 N: Dim, |
367 N: Dim, |
| 349 E: Scalar + Zero + One + Float, |
368 E: Scalar + Zero + One + Float, |
| 350 DefaultAllocator: Allocator<M, N>, |
369 DefaultAllocator: Allocator<M, N>, |
| 351 ShapeConstraint: StridesOk<E, M, N, SM> + StridesOk<E, M, N, SV1>, |
370 ShapeConstraint: StridesOk<E, M, N>, |
| 352 { |
371 { |
| 353 #[inline] |
372 #[inline] |
| 354 fn axpy<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, α: E, x: I, β: E) { |
373 fn axpy<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, α: E, x: I, β: E) { |
| 355 x.eval(|x̃| { |
374 x.eval(|x̃| { |
| 356 assert_eq!(self.ncols(), x̃.ncols()); |
375 assert_eq!(self.ncols(), x̃.ncols()); |
| 391 where |
410 where |
| 392 SM: StorageMut<E, M>, |
411 SM: StorageMut<E, M>, |
| 393 M: Dim, |
412 M: Dim, |
| 394 E: Scalar + Zero + One + Float + RealField, |
413 E: Scalar + Zero + One + Float + RealField, |
| 395 DefaultAllocator: Allocator<M>, |
414 DefaultAllocator: Allocator<M>, |
| 396 ShapeConstraint: StridesOk<E, M, U1, SM>, |
415 ShapeConstraint: StridesOk<E, M>, |
| 397 { |
416 { |
| 398 #[inline] |
417 #[inline] |
| 399 fn proj_ball(self, ρ: E, exp: Linfinity) -> <Self as Space>::Principal { |
418 fn proj_ball(self, ρ: E, exp: Linfinity) -> <Self as Space>::Principal { |
| 400 let mut owned = self.into_owned(); |
419 let mut owned = self.into_owned(); |
| 401 owned.proj_ball_mut(ρ, exp); |
420 owned.proj_ball_mut(ρ, exp); |
| 407 where |
426 where |
| 408 SM: StorageMut<E, M>, |
427 SM: StorageMut<E, M>, |
| 409 M: Dim, |
428 M: Dim, |
| 410 E: Scalar + Zero + One + Copy + Float + RealField, |
429 E: Scalar + Zero + One + Copy + Float + RealField, |
| 411 DefaultAllocator: Allocator<M>, |
430 DefaultAllocator: Allocator<M>, |
| 412 ShapeConstraint: StridesOk<E, M, U1, SM>, |
431 ShapeConstraint: StridesOk<E, M>, |
| 413 { |
432 { |
| 414 #[inline] |
433 #[inline] |
| 415 fn proj_ball_mut(&mut self, ρ: E, _: Linfinity) { |
434 fn proj_ball_mut(&mut self, ρ: E, _: Linfinity) { |
| 416 self.iter_mut() |
435 self.iter_mut() |
| 417 .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
436 .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
| 424 N: Dim, |
443 N: Dim, |
| 425 M: Dim, |
444 M: Dim, |
| 426 K: Dim, |
445 K: Dim, |
| 427 E: Scalar + Zero + One + Copy + SimdComplexField, |
446 E: Scalar + Zero + One + Copy + SimdComplexField, |
| 428 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M> + Allocator<M, N>, |
447 DefaultAllocator: Allocator<N, K> + Allocator<M, K> + Allocator<N, M> + Allocator<M, N>, |
| 429 ShapeConstraint: |
448 ShapeConstraint: StridesOk<E, N, K> + StridesOk<E, M, K>, |
| 430 StridesOk<E, N, M, SM> + StridesOk<E, N, K> + StridesOk<E, M, N> + StridesOk<E, M, K>, |
|
| 431 { |
449 { |
| 432 type AdjointCodomain = OMatrix<E, M, K>; |
450 type AdjointCodomain = OMatrix<E, M, K>; |
| 433 type Adjoint<'a> |
451 type Adjoint<'a> |
| 434 = OMatrix<E, M, N> |
452 = OMatrix<E, M, N> |
| 435 where |
453 where |
| 533 M: Dim, |
551 M: Dim, |
| 534 N: Dim, |
552 N: Dim, |
| 535 S: Storage<E, M, N>, |
553 S: Storage<E, M, N>, |
| 536 E: Float + Scalar + Zero + One + RealField, |
554 E: Float + Scalar + Zero + One + RealField, |
| 537 DefaultAllocator: Allocator<M, N>, |
555 DefaultAllocator: Allocator<M, N>, |
| 538 ShapeConstraint: StridesOk<E, M, N, S>, |
556 ShapeConstraint: StridesOk<E, M, N>, |
| 539 { |
557 { |
| 540 type DualSpace = OMatrix<E, M, N>; |
558 type DualSpace = OMatrix<E, M, N>; |
| 541 |
559 |
| 542 fn dual_origin(&self) -> OMatrix<E, M, N> { |
560 fn dual_origin(&self) -> OMatrix<E, M, N> { |
| 543 let (m, n) = self.shape_generic(); |
561 let (m, n) = self.shape_generic(); |