1use crate::traits::{MatrixMut, MatrixRef, Scalar};
39use crate::Matrix;
40
41impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
44 From<Matrix<T, M, N>> for nalgebra::SMatrix<T, M, N>
45where
46 nalgebra::Const<M>: nalgebra::DimName,
47 nalgebra::Const<N>: nalgebra::DimName,
48{
49 #[inline]
50 fn from(m: Matrix<T, M, N>) -> Self {
51 nalgebra::SMatrix::from_column_slice(m.as_slice())
52 }
53}
54
55impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
56 From<&Matrix<T, M, N>> for nalgebra::SMatrix<T, M, N>
57where
58 nalgebra::Const<M>: nalgebra::DimName,
59 nalgebra::Const<N>: nalgebra::DimName,
60{
61 #[inline]
62 fn from(m: &Matrix<T, M, N>) -> Self {
63 nalgebra::SMatrix::from_column_slice(m.as_slice())
64 }
65}
66
67impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
68 From<nalgebra::SMatrix<T, M, N>> for Matrix<T, M, N>
69where
70 nalgebra::Const<M>: nalgebra::DimName,
71 nalgebra::Const<N>: nalgebra::DimName,
72{
73 #[inline]
74 fn from(m: nalgebra::SMatrix<T, M, N>) -> Self {
75 Matrix::from_slice(m.as_slice())
76 }
77}
78
79impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
80 From<&nalgebra::SMatrix<T, M, N>> for Matrix<T, M, N>
81where
82 nalgebra::Const<M>: nalgebra::DimName,
83 nalgebra::Const<N>: nalgebra::DimName,
84{
85 #[inline]
86 fn from(m: &nalgebra::SMatrix<T, M, N>) -> Self {
87 Matrix::from_slice(m.as_slice())
88 }
89}
90
91impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
100 MatrixRef<T> for nalgebra::SMatrix<T, M, N>
101where
102 nalgebra::Const<M>: nalgebra::DimName,
103 nalgebra::Const<N>: nalgebra::DimName,
104{
105 #[inline]
106 fn nrows(&self) -> usize {
107 M
108 }
109
110 #[inline]
111 fn ncols(&self) -> usize {
112 N
113 }
114
115 #[inline]
116 fn get(&self, row: usize, col: usize) -> &T {
117 &self[(row, col)]
118 }
119
120 #[inline]
121 fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
122 let start = col * M + row_start;
123 let end = (col + 1) * M;
124 &self.as_slice()[start..end]
125 }
126}
127
128impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
129 MatrixMut<T> for nalgebra::SMatrix<T, M, N>
130where
131 nalgebra::Const<M>: nalgebra::DimName,
132 nalgebra::Const<N>: nalgebra::DimName,
133{
134 #[inline]
135 fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
136 &mut self[(row, col)]
137 }
138
139 #[inline]
140 fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
141 let start = col * M + row_start;
142 let end = (col + 1) * M;
143 &mut self.as_mut_slice()[start..end]
144 }
145}
146
147#[cfg(feature = "alloc")]
150mod dyn_interop {
151 use crate::dynmatrix::{DynMatrix, DynVector};
152 use crate::traits::{MatrixMut, MatrixRef, Scalar};
153
154 impl<T: Scalar + nalgebra::Scalar> From<DynMatrix<T>> for nalgebra::DMatrix<T> {
155 #[inline]
156 fn from(m: DynMatrix<T>) -> Self {
157 nalgebra::DMatrix::from_column_slice(m.nrows(), m.ncols(), m.as_slice())
158 }
159 }
160
161 impl<T: Scalar + nalgebra::Scalar> From<&DynMatrix<T>> for nalgebra::DMatrix<T> {
162 #[inline]
163 fn from(m: &DynMatrix<T>) -> Self {
164 nalgebra::DMatrix::from_column_slice(m.nrows(), m.ncols(), m.as_slice())
165 }
166 }
167
168 impl<T: Scalar + nalgebra::Scalar> From<nalgebra::DMatrix<T>> for DynMatrix<T> {
169 #[inline]
170 fn from(m: nalgebra::DMatrix<T>) -> Self {
171 DynMatrix::from_slice(m.nrows(), m.ncols(), m.as_slice())
172 }
173 }
174
175 impl<T: Scalar + nalgebra::Scalar> From<&nalgebra::DMatrix<T>> for DynMatrix<T> {
176 #[inline]
177 fn from(m: &nalgebra::DMatrix<T>) -> Self {
178 DynMatrix::from_slice(m.nrows(), m.ncols(), m.as_slice())
179 }
180 }
181
182 impl<T: Scalar + nalgebra::Scalar> From<DynVector<T>> for nalgebra::DVector<T> {
183 #[inline]
184 fn from(v: DynVector<T>) -> Self {
185 nalgebra::DVector::from_column_slice(v.as_slice())
186 }
187 }
188
189 impl<T: Scalar + nalgebra::Scalar> From<&DynVector<T>> for nalgebra::DVector<T> {
190 #[inline]
191 fn from(v: &DynVector<T>) -> Self {
192 nalgebra::DVector::from_column_slice(v.as_slice())
193 }
194 }
195
196 impl<T: Scalar + nalgebra::Scalar> From<nalgebra::DVector<T>> for DynVector<T> {
197 #[inline]
198 fn from(v: nalgebra::DVector<T>) -> Self {
199 DynVector::from_slice(v.as_slice())
200 }
201 }
202
203 impl<T: Scalar + nalgebra::Scalar> From<&nalgebra::DVector<T>> for DynVector<T> {
204 #[inline]
205 fn from(v: &nalgebra::DVector<T>) -> Self {
206 DynVector::from_slice(v.as_slice())
207 }
208 }
209
210 impl<T: Scalar + nalgebra::Scalar> MatrixRef<T> for nalgebra::DMatrix<T> {
213 #[inline]
214 fn nrows(&self) -> usize {
215 self.nrows()
216 }
217
218 #[inline]
219 fn ncols(&self) -> usize {
220 self.ncols()
221 }
222
223 #[inline]
224 fn get(&self, row: usize, col: usize) -> &T {
225 &self[(row, col)]
226 }
227
228 #[inline]
229 fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
230 let nrows = self.nrows();
231 let start = col * nrows + row_start;
232 let end = (col + 1) * nrows;
233 &self.as_slice()[start..end]
234 }
235 }
236
237 impl<T: Scalar + nalgebra::Scalar> MatrixMut<T> for nalgebra::DMatrix<T> {
238 #[inline]
239 fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
240 &mut self[(row, col)]
241 }
242
243 #[inline]
244 fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
245 let nrows = self.nrows();
246 let start = col * nrows + row_start;
247 let end = (col + 1) * nrows;
248 &mut self.as_mut_slice()[start..end]
249 }
250 }
251}
252
253#[cfg(test)]
256mod tests {
257 use super::*;
258
259 #[test]
260 fn matrix_to_smatrix_roundtrip() {
261 let nm = Matrix::new([[1.0_f64, 2.0], [3.0, 4.0]]);
262 let na: nalgebra::SMatrix<f64, 2, 2> = nm.into();
263 assert_eq!(na[(0, 0)], 1.0);
264 assert_eq!(na[(0, 1)], 2.0);
265 assert_eq!(na[(1, 0)], 3.0);
266 assert_eq!(na[(1, 1)], 4.0);
267 let back: Matrix<f64, 2, 2> = na.into();
268 assert_eq!(back, nm);
269 }
270
271 #[test]
272 fn matrix_ref_roundtrip() {
273 let nm = Matrix::new([[1.0_f64, 2.0, 3.0], [4.0, 5.0, 6.0]]);
274 let na: nalgebra::SMatrix<f64, 2, 3> = (&nm).into();
275 let back: Matrix<f64, 2, 3> = (&na).into();
276 assert_eq!(back, nm);
277 }
278
279 #[test]
280 fn vector_to_svector_roundtrip() {
281 use crate::Vector;
284 let nv = Vector::from_array([1.0_f64, 2.0, 3.0]);
285 let na: nalgebra::SVector<f64, 3> = nv.into();
286 assert_eq!(na[0], 1.0);
287 assert_eq!(na[1], 2.0);
288 assert_eq!(na[2], 3.0);
289 assert_eq!(na.nrows(), 3);
290 assert_eq!(na.ncols(), 1);
291 let back: Vector<f64, 3> = na.into();
292 assert_eq!(back, nv);
293 }
294
295 #[test]
296 fn vector_ref_roundtrip() {
297 use crate::Vector;
298 let nv = Vector::from_array([10.0_f32, 20.0, 30.0, 40.0]);
299 let na: nalgebra::SMatrix<f32, 4, 1> = (&nv).into();
300 let back: Vector<f32, 4> = (&na).into();
301 assert_eq!(back, nv);
302 }
303
304 #[test]
305 fn smatrix_matrix_ref_trait() {
306 let na = nalgebra::SMatrix::<f64, 3, 3>::new(
307 1.0, 2.0, 3.0,
308 4.0, 5.0, 6.0,
309 7.0, 8.0, 9.0,
310 );
311 assert_eq!(na.nrows(), 3);
312 assert_eq!(na.ncols(), 3);
313 assert_eq!(*MatrixRef::get(&na, 0, 0), 1.0);
314 assert_eq!(*MatrixRef::get(&na, 1, 0), 4.0);
315 assert_eq!(*MatrixRef::get(&na, 0, 1), 2.0);
316
317 let col1 = MatrixRef::col_as_slice(&na, 1, 0);
318 assert_eq!(col1, &[2.0, 5.0, 8.0]);
319
320 let col2_from1 = MatrixRef::col_as_slice(&na, 2, 1);
321 assert_eq!(col2_from1, &[6.0, 9.0]);
322 }
323
324 #[test]
325 fn smatrix_matrix_mut_trait() {
326 let mut na = nalgebra::SMatrix::<f64, 2, 2>::zeros();
327 *MatrixMut::get_mut(&mut na, 0, 1) = 42.0;
328 assert_eq!(na[(0, 1)], 42.0);
329
330 let col = MatrixMut::col_as_mut_slice(&mut na, 0, 0);
331 col[0] = 10.0;
332 col[1] = 20.0;
333 assert_eq!(na[(0, 0)], 10.0);
334 assert_eq!(na[(1, 0)], 20.0);
335 }
336
337 #[test]
338 fn lu_on_nalgebra_smatrix() {
339 use crate::linalg::lu::lu_in_place;
340
341 let mut na = nalgebra::SMatrix::<f64, 3, 3>::new(
342 2.0, 1.0, -1.0,
343 -3.0, -1.0, 2.0,
344 -2.0, 1.0, 2.0,
345 );
346 let mut perm = [0usize; 3];
347 let result = lu_in_place(&mut na, &mut perm);
348 assert!(result.is_ok());
349 }
350
351 #[test]
352 fn cholesky_on_nalgebra_smatrix() {
353 use crate::linalg::cholesky::cholesky_in_place;
354
355 let mut na = nalgebra::SMatrix::<f64, 2, 2>::new(4.0, 2.0, 2.0, 3.0);
357 let result = cholesky_in_place(&mut na);
358 assert!(result.is_ok());
359 }
360
361 #[test]
362 fn nonsquare_matrix_roundtrip() {
363 let nm = Matrix::new([[1.0_f64, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]]);
364 let na: nalgebra::SMatrix<f64, 3, 4> = nm.into();
365 let back: Matrix<f64, 3, 4> = na.into();
366 assert_eq!(back, nm);
367 }
368
369 #[test]
370 fn i32_matrix_roundtrip() {
371 let nm = Matrix::new([[1_i32, 2], [3, 4]]);
372 let na: nalgebra::SMatrix<i32, 2, 2> = nm.into();
373 let back: Matrix<i32, 2, 2> = na.into();
374 assert_eq!(back, nm);
375 }
376
377 #[cfg(feature = "alloc")]
378 mod dyn_tests {
379 use crate::dynmatrix::{DynMatrix, DynVector};
380 use crate::traits::{MatrixMut, MatrixRef};
381
382 #[test]
383 fn dynmatrix_to_dmatrix_roundtrip() {
384 let dm = DynMatrix::from_rows(2, 3, &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0]);
385 let na: nalgebra::DMatrix<f64> = (&dm).into();
386 assert_eq!(na.nrows(), 2);
387 assert_eq!(na.ncols(), 3);
388 assert_eq!(na[(0, 0)], 1.0);
389 assert_eq!(na[(0, 2)], 3.0);
390 assert_eq!(na[(1, 0)], 4.0);
391 let back: DynMatrix<f64> = na.into();
392 assert_eq!(back, dm);
393 }
394
395 #[test]
396 fn dynvector_to_dvector_roundtrip() {
397 let dv = DynVector::from_slice(&[1.0_f64, 2.0, 3.0]);
398 let na: nalgebra::DVector<f64> = (&dv).into();
399 assert_eq!(na.len(), 3);
400 assert_eq!(na[0], 1.0);
401 assert_eq!(na[2], 3.0);
402 let back: DynVector<f64> = na.into();
403 assert_eq!(back, dv);
404 }
405
406 #[test]
407 fn dmatrix_matrix_ref_trait() {
408 let na = nalgebra::DMatrix::from_row_slice(2, 3, &[
409 1.0_f64, 2.0, 3.0,
410 4.0, 5.0, 6.0,
411 ]);
412 assert_eq!(MatrixRef::nrows(&na), 2);
413 assert_eq!(MatrixRef::ncols(&na), 3);
414 assert_eq!(*MatrixRef::get(&na, 0, 0), 1.0);
415 assert_eq!(*MatrixRef::get(&na, 1, 0), 4.0);
416 assert_eq!(*MatrixRef::get(&na, 0, 2), 3.0);
417
418 let col1 = MatrixRef::col_as_slice(&na, 1, 0);
419 assert_eq!(col1, &[2.0, 5.0]);
420 }
421
422 #[test]
423 fn dmatrix_matrix_mut_trait() {
424 let mut na = nalgebra::DMatrix::zeros(3, 3);
425 *MatrixMut::get_mut(&mut na, 1, 2) = 99.0;
426 assert_eq!(na[(1, 2)], 99.0);
427
428 let col = MatrixMut::col_as_mut_slice(&mut na, 0, 1);
429 col[0] = 10.0;
430 col[1] = 20.0;
431 assert_eq!(na[(1, 0)], 10.0);
432 assert_eq!(na[(2, 0)], 20.0);
433 }
434
435 #[test]
436 fn lu_on_nalgebra_dmatrix() {
437 use crate::linalg::lu::lu_in_place;
438
439 let mut na = nalgebra::DMatrix::from_row_slice(3, 3, &[
440 2.0_f64, 1.0, -1.0,
441 -3.0, -1.0, 2.0,
442 -2.0, 1.0, 2.0,
443 ]);
444 let mut perm = [0usize; 3];
445 let result = lu_in_place(&mut na, &mut perm);
446 assert!(result.is_ok());
447 }
448 }
449}