| 12 use crate::instance::{Decomposition, Instance, Ownable, Space}; |
12 use crate::instance::{Decomposition, Instance, Ownable, Space}; |
| 13 use crate::linops::*; |
13 use crate::linops::*; |
| 14 use crate::norms::*; |
14 use crate::norms::*; |
| 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::{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 ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, MatrixView, OMatrix, |
| 21 OVector, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, Vector, |
21 OVector, RawStorage, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, |
| |
22 Vector, |
| 22 }; |
23 }; |
| 23 use num_traits::identities::{One, Zero}; |
24 use num_traits::identities::{One, Zero}; |
| 24 use std::ops::Mul; |
25 use std::ops::Mul; |
| 25 |
26 |
| 26 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> |
| 57 } |
58 } |
| 58 |
59 |
| 59 #[derive(Copy, Clone, Debug)] |
60 #[derive(Copy, Clone, Debug)] |
| 60 pub struct MatrixDecomposition; |
61 pub struct MatrixDecomposition; |
| 61 |
62 |
| 62 impl<E, M, K, S, RS, CS> Decomposition<Matrix<E, M, K, S>> for MatrixDecomposition |
63 impl<E, M, K, S> Decomposition<Matrix<E, M, K, S>> for MatrixDecomposition |
| 63 where |
64 where |
| 64 S: Storage<E, M, K, RStride = RS, CStride = CS>, |
65 S: Storage<E, M, K>, |
| 65 M: Dim, |
66 M: Dim, |
| 66 K: Dim, |
67 K: Dim, |
| 67 RS: Dim, |
|
| 68 CS: Dim, |
|
| 69 E: Scalar + Zero + One, |
68 E: Scalar + Zero + One, |
| 70 DefaultAllocator: Allocator<M, K>, |
69 DefaultAllocator: Allocator<M, K>, |
| 71 { |
70 { |
| 72 type OwnedInstance = OMatrix<E, M, K>; |
71 type OwnedInstance = OMatrix<E, M, K>; |
| 73 |
72 |
| 74 type Decomposition<'b> |
73 type Decomposition<'b> |
| 75 = OMatrix<E, M, K> |
74 = OMatrix<E, M, K> |
| 76 where |
75 where |
| 77 Matrix<E, M, K, S>: 'b; |
76 Matrix<E, M, K, S>: 'b; |
| 78 type Reference<'b> |
77 type Reference<'b> |
| 79 = &'b MatrixView<'b, E, M, K, RS, CS> |
78 = MatrixView<'b, E, M, K, Dyn, Dyn> |
| 80 where |
79 where |
| 81 Matrix<E, M, K, S>: 'b; |
80 Matrix<E, M, K, S>: 'b; |
| 82 |
81 |
| 83 #[inline] |
82 #[inline] |
| 84 fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b> |
83 fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b> |
| 87 { |
86 { |
| 88 r.into_owned() |
87 r.into_owned() |
| 89 } |
88 } |
| 90 } |
89 } |
| 91 |
90 |
| 92 impl<S, SV, M, K, E, RS, CS> Instance<Matrix<E, M, K, S>, MatrixDecomposition> |
91 macro_rules! impl_instances { |
| 93 for Matrix<E, M, K, SV> |
92 ($rstride:ty, $cstride:ty where $($qual:tt)*) => { |
| 94 where |
93 impl<$($qual)* S1, S2, M, K, E> Instance<Matrix<E, M, K, S1>, MatrixDecomposition> for Matrix<E, M, K, S2> |
| 95 S: Storage<E, M, K, RStride = RS, CStride = CS>, |
94 where |
| 96 SV: Storage<E, M, K>, |
95 S1: Storage<E, M, K>, |
| 97 M: Dim, |
96 S2: RawStorage<E, M, K, RStride=$rstride, CStride=$cstride>, |
| 98 K: Dim, |
97 //ShapeConstraint: DimEq<Dyn, <S2 as RawStorage<E, M, K>>::RStride> |
| 99 E: Scalar + Zero + One, |
98 // + DimEq<Dyn, <S2 as RawStorage<E, M, K>>::CStride>, |
| 100 DefaultAllocator: Allocator<M, K>, |
99 M: Dim, |
| 101 { |
100 K: Dim, |
| 102 fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R |
101 E: Scalar + Zero + One, |
| 103 where |
102 DefaultAllocator: Allocator<M, K>, |
| 104 Self: 'b, |
103 { |
| 105 { |
104 fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R |
| 106 f(self.into_owned()) |
105 where |
| 107 } |
106 Self: 'b, |
| 108 |
107 { |
| 109 fn eval_ref_decompose<'b, R>( |
108 f(self.into_owned()) |
| 110 &'b self, |
109 } |
| 111 f: impl FnOnce(<MatrixDecomposition as Decomposition<Self>>::Reference<'b>) -> R, |
110 |
| 112 ) -> R |
111 fn eval_ref_decompose<'b, R>( |
| 113 where |
112 &'b self, |
| 114 Self: 'b, |
113 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
| 115 Matrix<E, M, K, SM>: 'b, |
114 ) -> R |
| 116 { |
115 where |
| 117 f(&self.as_view::<M, K, Dyn, Dyn>()) |
116 Self: 'b, |
| 118 } |
117 Matrix<E, M, K, S1>: 'b, |
| 119 |
118 { |
| 120 #[inline] |
119 f(self.as_view::<M, K, Dyn, Dyn>()) |
| 121 fn own(self) -> OMatrix<E, M, K> { |
120 } |
| 122 self.into_owned() |
121 |
| 123 } |
122 #[inline] |
| 124 } |
123 fn own(self) -> OMatrix<E, M, K> { |
| |
124 self.into_owned() |
| |
125 } |
| |
126 } |
| |
127 |
| |
128 impl<'a, $($qual)* S1, S2, M, K, E> Instance<Matrix<E, M, K, S1>, MatrixDecomposition> |
| |
129 for &'a Matrix<E, M, K, S2> |
| |
130 where |
| |
131 S1: Storage<E, M, K>, |
| |
132 S2: RawStorage<E, M, K, RStride=$rstride, CStride=$cstride>, |
| |
133 M: Dim, |
| |
134 K: Dim, |
| |
135 E: Scalar + Zero + One, |
| |
136 DefaultAllocator: Allocator<M, K>, |
| |
137 { |
| |
138 fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R |
| |
139 where |
| |
140 Self: 'b, |
| |
141 { |
| |
142 f(self.into_owned()) |
| |
143 } |
| |
144 |
| |
145 fn eval_ref_decompose<'b, R>( |
| |
146 &'b self, |
| |
147 f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R, |
| |
148 ) -> R |
| |
149 where |
| |
150 Self: 'b, |
| |
151 Matrix<E, M, K, S1>: 'b, |
| |
152 { |
| |
153 f((*self).as_view::<M, K, Dyn, Dyn>()) |
| |
154 } |
| |
155 |
| |
156 #[inline] |
| |
157 fn own(self) -> OMatrix<E, M, K> { |
| |
158 self.into_owned() |
| |
159 } |
| |
160 } |
| |
161 }; |
| |
162 } |
| |
163 |
| |
164 impl_instances!(Dyn, Dyn where ); |
| |
165 impl_instances!(Const<RS>, Dyn where const RS : usize,); |
| |
166 impl_instances!(Dyn, Const<CS> where const CS : usize,); |
| |
167 impl_instances!(Const<RS>, Const<CS> where const RS : usize, const CS : usize,); |
| 125 |
168 |
| 126 impl<SM, SV, N, M, K, E> Mapping<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM> |
169 impl<SM, SV, N, M, K, E> Mapping<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM> |
| 127 where |
170 where |
| 128 SM: Storage<E, N, M>, |
171 SM: Storage<E, N, M>, |
| 129 SV: Storage<E, M, K> + Clone, |
172 SV: Storage<E, M, K> + Clone, |
| 345 { |
388 { |
| 346 type OwnedEuclidean = OVector<E, M>; |
389 type OwnedEuclidean = OVector<E, M>; |
| 347 |
390 |
| 348 #[inline] |
391 #[inline] |
| 349 fn dot<I: Instance<Self>>(&self, other: I) -> E { |
392 fn dot<I: Instance<Self>>(&self, other: I) -> E { |
| 350 other.eval_ref_decompose(|r| Vector::<E, M, S>::dot(self, r)) |
393 other.eval_ref_decompose(|ref r| Vector::<E, M, S>::dot(self, r)) |
| 351 } |
394 } |
| 352 |
395 |
| 353 #[inline] |
396 #[inline] |
| 354 fn norm2_squared(&self) -> E { |
397 fn norm2_squared(&self) -> E { |
| 355 Vector::<E, M, S>::norm_squared(self) |
398 Vector::<E, M, S>::norm_squared(self) |
| 356 } |
399 } |
| 357 |
400 |
| 358 #[inline] |
401 #[inline] |
| 359 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E { |
402 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E { |
| 360 other.eval_ref_decompose(|r| metric_distance_squared(self, r)) |
403 other.eval_ref_decompose(|ref r| metric_distance_squared(self, r)) |
| 361 } |
404 } |
| 362 } |
405 } |
| 363 |
406 |
| 364 impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> |
407 impl<E, M, S> StaticEuclidean<E> for Vector<E, M, S> |
| 365 where |
408 where |