src/nalgebra_support.rs

branch
dev
changeset 158
9c720f822c79
parent 157
2ac69af65636
child 159
279b1f5b8608
equal deleted inserted replaced
157:2ac69af65636 158:9c720f822c79
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
429 E: Float + Scalar + Zero + One + RealField, 472 E: Float + Scalar + Zero + One + RealField,
430 DefaultAllocator: Allocator<M>, 473 DefaultAllocator: Allocator<M>,
431 { 474 {
432 #[inline] 475 #[inline]
433 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E { 476 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E {
434 other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r)) 477 other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r))
435 } 478 }
436 } 479 }
437 480
438 impl<E, M, S> Norm<L2, E> for Vector<E, M, S> 481 impl<E, M, S> Norm<L2, E> for Vector<E, M, S>
439 where 482 where
455 E: Float + Scalar + Zero + One + RealField, 498 E: Float + Scalar + Zero + One + RealField,
456 DefaultAllocator: Allocator<M>, 499 DefaultAllocator: Allocator<M>,
457 { 500 {
458 #[inline] 501 #[inline]
459 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E { 502 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E {
460 other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r)) 503 other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r))
461 } 504 }
462 } 505 }
463 506
464 impl<E, M, S> Norm<Linfinity, E> for Vector<E, M, S> 507 impl<E, M, S> Norm<Linfinity, E> for Vector<E, M, S>
465 where 508 where
481 E: Float + Scalar + Zero + One + RealField, 524 E: Float + Scalar + Zero + One + RealField,
482 DefaultAllocator: Allocator<M>, 525 DefaultAllocator: Allocator<M>,
483 { 526 {
484 #[inline] 527 #[inline]
485 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E { 528 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E {
486 other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&UniformNorm, self, r)) 529 other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r))
487 } 530 }
488 } 531 }
489 532
490 /// Helper trait to hide the symbols of [`nalgebra::RealField`]. 533 /// Helper trait to hide the symbols of [`nalgebra::RealField`].
491 /// 534 ///

mercurial