rulinalg/matrix/
iter.rs

1use std::iter::{ExactSizeIterator, FromIterator};
2use std::mem;
3
4use super::{Matrix, MatrixSlice, MatrixSliceMut};
5use super::{Column, ColumnMut, Cols, ColsMut, Row, RowMut, Rows, RowsMut, Diagonal, DiagonalMut};
6use super::{BaseMatrix, BaseMatrixMut, SliceIter, SliceIterMut};
7
8macro_rules! impl_slice_iter (
9    ($slice_iter:ident, $data_type:ty) => (
10/// Iterates over the matrix slice data in row-major order.
11impl<'a, T> Iterator for $slice_iter<'a, T> {
12    type Item = $data_type;
13
14    fn next(&mut self) -> Option<$data_type> {
15        let offset = self.row_pos * self.row_stride + self.col_pos;
16        let end = self.slice_rows * self.row_stride;
17        // Set the position of the next element
18        if offset < end {
19            unsafe {
20                let iter_ptr = self.slice_start.offset(offset as isize);
21
22                // If end of row, set to start of next row
23                if self.col_pos + 1 == self.slice_cols {
24                    self.row_pos += 1usize;
25                    self.col_pos = 0usize;
26                } else {
27                    self.col_pos += 1usize;
28                }
29
30                Some(mem::transmute(iter_ptr))
31            }
32        } else {
33            None
34        }
35    }
36}
37    );
38);
39
40impl_slice_iter!(SliceIter, &'a T);
41impl_slice_iter!(SliceIterMut, &'a mut T);
42
43macro_rules! impl_diag_iter (
44    ($diag:ident, $diag_base:ident, $diag_type:ty, $as_ptr:ident) => (
45
46/// Iterates over the diagonals in the matrix.
47impl<'a, T, M: $diag_base<T>> Iterator for $diag<'a, T, M> {
48    type Item = $diag_type;
49
50    fn next(&mut self) -> Option<Self::Item> {
51        if self.diag_pos < self.diag_end {
52            let pos = self.diag_pos as isize;
53            self.diag_pos += self.matrix.row_stride() + 1;
54            unsafe {
55                Some(mem::transmute(self.matrix.$as_ptr()
56                            .offset(pos)))
57            }
58        } else {
59            None
60        }
61    }
62
63    fn last(self) -> Option<Self::Item> {
64        if self.diag_pos < self.diag_end {
65            unsafe {
66                Some(mem::transmute(self.matrix.$as_ptr()
67                            .offset(self.diag_end as isize - 1)))
68            }
69        } else {
70            None
71        }
72    }
73
74    fn nth(&mut self, n: usize) -> Option<Self::Item> {
75        self.diag_pos += n * (self.matrix.row_stride() + 1);
76        if self.diag_pos < self.diag_end {
77            let pos = self.diag_pos as isize;
78            self.diag_pos += self.matrix.row_stride() + 1;
79            unsafe {
80                Some(mem::transmute(self.matrix.$as_ptr()
81                            .offset(pos)))
82            }
83        } else {
84            None
85        }
86    }
87
88    fn count(self) -> usize {
89        self.size_hint().0
90    }
91
92    fn size_hint(&self) -> (usize, Option<usize>) {
93        if self.diag_pos < self.diag_end {
94            let s = (self.diag_end - self.diag_pos) / (self.matrix.row_stride() + 1) + 1;
95            (s, Some(s))
96        } else {
97            (0, Some(0))
98        }
99    }
100}
101
102impl<'a, T, M: $diag_base<T>> ExactSizeIterator for $diag<'a, T, M> {}
103    );
104);
105
106impl_diag_iter!(Diagonal, BaseMatrix, &'a T, as_ptr);
107impl_diag_iter!(DiagonalMut, BaseMatrixMut, &'a mut T, as_mut_ptr);
108
109macro_rules! impl_col_iter (
110    ($cols:ident, $col_type:ty, $col_base:ident, $slice_base:ident) => (
111
112/// Iterates over the columns in the matrix.
113impl<'a, T> Iterator for $cols<'a, T> {
114    type Item = $col_type;
115
116    fn next(&mut self) -> Option<Self::Item> {
117        if self.col_pos >= self.slice_cols {
118            return None;
119        }
120
121        let column: $col_type;
122        unsafe {
123            let ptr = self.slice_start.offset(self.col_pos as isize);
124            column  = $col_base {
125                col: $slice_base::from_raw_parts(ptr, self.slice_rows, 1, self.row_stride as usize)
126            };
127        }
128        self.col_pos += 1;
129        Some(column)
130    }
131
132    fn last(self) -> Option<Self::Item> {
133        if self.col_pos >= self.slice_cols {
134            return None;
135        }
136
137        unsafe {
138            let ptr = self.slice_start.offset((self.slice_cols - 1) as isize);
139            Some($col_base {
140                col: $slice_base::from_raw_parts(ptr, self.slice_rows, 1, self.row_stride as usize)
141            })
142        }
143    }
144
145    fn nth(&mut self, n: usize) -> Option<Self::Item> {
146        if self.col_pos + n >= self.slice_cols {
147            return None;
148        }
149
150        let column: $col_type;
151        unsafe {
152            let ptr = self.slice_start.offset((self.col_pos + n) as isize);
153            column = $col_base {
154                col: $slice_base::from_raw_parts(ptr, self.slice_rows, 1, self.row_stride as usize)
155            }
156        }
157        self.col_pos += n + 1;
158        Some(column)
159    }
160
161    fn count(self) -> usize {
162        self.slice_cols - self.col_pos
163    }
164
165    fn size_hint(&self) -> (usize, Option<usize>) {
166        (self.slice_cols - self.col_pos, Some(self.slice_cols - self.col_pos))
167    }
168}
169    );
170);
171
172impl_col_iter!(Cols, Column<'a, T>, Column, MatrixSlice);
173impl_col_iter!(ColsMut, ColumnMut<'a, T>, ColumnMut, MatrixSliceMut);
174
175impl<'a, T> ExactSizeIterator for Cols<'a, T> {}
176impl<'a, T> ExactSizeIterator for ColsMut<'a, T> {}
177
178macro_rules! impl_row_iter (
179    ($rows:ident, $row_type:ty, $row_base:ident, $slice_base:ident) => (
180
181/// Iterates over the rows in the matrix.
182impl<'a, T> Iterator for $rows<'a, T> {
183    type Item = $row_type;
184
185    fn next(&mut self) -> Option<Self::Item> {
186// Check if we have reached the end
187        if self.row_pos < self.slice_rows {
188            let row: $row_type;
189            unsafe {
190// Get pointer and create a slice from raw parts
191                let ptr = self.slice_start.offset(self.row_pos as isize * self.row_stride);
192                row = $row_base {
193                    row: $slice_base::from_raw_parts(ptr, 1, self.slice_cols, self.row_stride as usize)
194                };
195            }
196
197            self.row_pos += 1;
198            Some(row)
199        } else {
200            None
201        }
202    }
203
204    fn last(self) -> Option<Self::Item> {
205// Check if already at the end
206        if self.row_pos < self.slice_rows {
207            unsafe {
208// Get pointer to last row and create a slice from raw parts
209                let ptr = self.slice_start.offset((self.slice_rows - 1) as isize * self.row_stride);
210                Some($row_base {
211                    row: $slice_base::from_raw_parts(ptr, 1, self.slice_cols, self.row_stride as usize)
212                })
213            }
214        } else {
215            None
216        }
217    }
218
219    fn nth(&mut self, n: usize) -> Option<Self::Item> {
220        if self.row_pos + n < self.slice_rows {
221            let row: $row_type;
222            unsafe {
223                let ptr = self.slice_start.offset((self.row_pos + n) as isize * self.row_stride);
224                row = $row_base {
225                    row: $slice_base::from_raw_parts(ptr, 1, self.slice_cols, self.row_stride as usize)
226                }
227            }
228
229            self.row_pos += n + 1;
230            Some(row)
231        } else {
232            None
233        }
234    }
235
236    fn count(self) -> usize {
237        self.slice_rows - self.row_pos
238    }
239
240    fn size_hint(&self) -> (usize, Option<usize>) {
241        (self.slice_rows - self.row_pos, Some(self.slice_rows - self.row_pos))
242    }
243}
244    );
245);
246
247impl_row_iter!(Rows, Row<'a, T>, Row, MatrixSlice);
248impl_row_iter!(RowsMut, RowMut<'a, T>, RowMut, MatrixSliceMut);
249
250impl<'a, T> ExactSizeIterator for Rows<'a, T> {}
251impl<'a, T> ExactSizeIterator for RowsMut<'a, T> {}
252
253/// Creates a `Matrix` from an iterator over slices.
254///
255/// Each of the slices produced by the iterator will become a row in the matrix.
256///
257/// # Panics
258///
259/// Will panic if the iterators items do not have constant length.
260///
261/// # Examples
262///
263/// We can create a new matrix from some data.
264///
265/// ```
266/// use rulinalg::matrix::{Matrix, BaseMatrix};
267///
268/// let a : Matrix<f64> = vec![4f64; 16].chunks(4).collect();
269///
270/// assert_eq!(a.rows(), 4);
271/// assert_eq!(a.cols(), 4);
272/// ```
273///
274/// We can also do more interesting things.
275///
276/// ```
277/// use rulinalg::matrix::{Matrix, BaseMatrix};
278///
279/// let a = Matrix::new(4,2, (0..8).collect::<Vec<usize>>());
280///
281/// // Here we skip the first row and take only those
282/// // where the first entry is less than 6.
283/// let b = a.row_iter()
284///          .skip(1)
285///          .filter(|x| x[0] < 6)
286///          .collect::<Matrix<usize>>();
287///
288/// // We take the middle rows
289/// assert_eq!(b.into_vec(), vec![2,3,4,5]);
290/// ```
291impl<'a, T: 'a + Copy> FromIterator<&'a [T]> for Matrix<T> {
292    fn from_iter<I: IntoIterator<Item = &'a [T]>>(iterable: I) -> Self {
293        let mut mat_data: Vec<T>;
294        let cols: usize;
295        let mut rows = 0;
296
297        let mut iterator = iterable.into_iter();
298
299        match iterator.next() {
300            None => {
301                return Matrix {
302                    data: Vec::new(),
303                    rows: 0,
304                    cols: 0,
305                }
306            }
307            Some(row) => {
308                rows += 1;
309                // Here we set the capacity - get iterator size and the cols
310                let (lower_rows, _) = iterator.size_hint();
311                cols = row.len();
312
313                mat_data = Vec::with_capacity(lower_rows.saturating_add(1).saturating_mul(cols));
314                mat_data.extend_from_slice(row);
315            }
316        }
317
318        for row in iterator {
319            assert!(row.len() == cols, "Iterator slice length must be constant.");
320            mat_data.extend_from_slice(row);
321            rows += 1;
322        }
323
324        mat_data.shrink_to_fit();
325
326        Matrix {
327            data: mat_data,
328            rows: rows,
329            cols: cols,
330        }
331    }
332}
333
334macro_rules! impl_from_iter_row(
335    ($row_type:ty) => (
336impl<'a, T: 'a + Copy> FromIterator<$row_type> for Matrix<T> {
337    fn from_iter<I: IntoIterator<Item = $row_type>>(iterable: I) -> Self {
338        let mut mat_data: Vec<T>;
339        let cols: usize;
340        let mut rows = 0;
341
342        let mut iterator = iterable.into_iter();
343
344        match iterator.next() {
345            None => {
346                return Matrix {
347                    data: Vec::new(),
348                    rows: 0,
349                    cols: 0,
350                }
351            }
352            Some(row) => {
353                rows += 1;
354                // Here we set the capacity - get iterator size and the cols
355                let (lower_rows, _) = iterator.size_hint();
356                cols = row.row.cols();
357
358                mat_data = Vec::with_capacity(lower_rows.saturating_add(1).saturating_mul(cols));
359                mat_data.extend_from_slice(row.raw_slice());
360            }
361        }
362
363        for row in iterator {
364            assert!(row.row.cols() == cols, "Iterator row size must be constant.");
365            mat_data.extend_from_slice(row.raw_slice());
366            rows += 1;
367        }
368
369        mat_data.shrink_to_fit();
370
371        Matrix {
372            data: mat_data,
373            rows: rows,
374            cols: cols,
375        }
376    }
377}
378    );
379);
380
381impl_from_iter_row!(Row<'a, T>);
382impl_from_iter_row!(RowMut<'a, T>);
383
384
385impl<'a, T> IntoIterator for MatrixSlice<'a, T> {
386    type Item = &'a T;
387    type IntoIter = SliceIter<'a, T>;
388
389    fn into_iter(self) -> Self::IntoIter {
390        self.iter()
391    }
392}
393
394impl<'a, T> IntoIterator for &'a MatrixSlice<'a, T> {
395    type Item = &'a T;
396    type IntoIter = SliceIter<'a, T>;
397
398    fn into_iter(self) -> Self::IntoIter {
399        self.iter()
400    }
401}
402
403impl<'a, T> IntoIterator for &'a mut MatrixSlice<'a, T> {
404    type Item = &'a T;
405    type IntoIter = SliceIter<'a, T>;
406
407    fn into_iter(self) -> Self::IntoIter {
408        self.iter()
409    }
410}
411
412impl<'a, T> IntoIterator for MatrixSliceMut<'a, T> {
413    type Item = &'a mut T;
414    type IntoIter = SliceIterMut<'a, T>;
415
416    fn into_iter(mut self) -> Self::IntoIter {
417        self.iter_mut()
418    }
419}
420
421impl<'a, T> IntoIterator for &'a MatrixSliceMut<'a, T> {
422    type Item = &'a T;
423    type IntoIter = SliceIter<'a, T>;
424
425    fn into_iter(self) -> Self::IntoIter {
426        self.iter()
427    }
428}
429
430impl<'a, T> IntoIterator for &'a mut MatrixSliceMut<'a, T> {
431    type Item = &'a mut T;
432    type IntoIter = SliceIterMut<'a, T>;
433
434    fn into_iter(self) -> Self::IntoIter {
435        self.iter_mut()
436    }
437}
438
439#[cfg(test)]
440mod tests {
441    use super::super::{DiagOffset, Matrix, MatrixSlice, MatrixSliceMut};
442    use super::super::{BaseMatrix, BaseMatrixMut};
443
444    #[test]
445    fn test_diag_offset_equivalence() {
446        // This test will check that `Main`,
447        // `Below(0)`, and `Above(0)` are all equivalent.
448        let a = matrix![0.0, 1.0, 2.0;
449                        3.0, 4.0, 5.0;
450                        6.0, 7.0, 8.0];
451
452        // Collect each diagonal and compare them
453        let d1 = a.diag_iter(DiagOffset::Main).collect::<Vec<_>>();
454        let d2 = a.diag_iter(DiagOffset::Above(0)).collect::<Vec<_>>();
455        let d3 = a.diag_iter(DiagOffset::Below(0)).collect::<Vec<_>>();
456        assert_eq!(d1, d2);
457        assert_eq!(d2, d3);
458
459        let b = MatrixSlice::from_matrix(&a, [0, 0], 2, 3);
460        let d1 = b.diag_iter(DiagOffset::Main).collect::<Vec<_>>();
461        let d2 = b.diag_iter(DiagOffset::Above(0)).collect::<Vec<_>>();
462        let d3 = b.diag_iter(DiagOffset::Below(0)).collect::<Vec<_>>();
463        assert_eq!(d1, d2);
464        assert_eq!(d2, d3);
465    }
466
467    #[test]
468    fn test_matrix_diag() {
469        let mut a = matrix![0.0, 1.0, 2.0;
470                            3.0, 4.0, 5.0;
471                            6.0, 7.0, 8.0];
472
473        let diags = vec![0.0, 4.0, 8.0];
474        assert_eq!(a.diag_iter(DiagOffset::Main).cloned().collect::<Vec<_>>(), diags);
475        let diags = vec![1.0, 5.0];
476        assert_eq!(a.diag_iter(DiagOffset::Above(1)).cloned().collect::<Vec<_>>(), diags);
477        let diags = vec![3.0, 7.0];
478        assert_eq!(a.diag_iter(DiagOffset::Below(1)).cloned().collect::<Vec<_>>(), diags);
479        let diags = vec![2.0];
480        assert_eq!(a.diag_iter(DiagOffset::Above(2)).cloned().collect::<Vec<_>>(), diags);
481        let diags = vec![6.0];
482        assert_eq!(a.diag_iter(DiagOffset::Below(2)).cloned().collect::<Vec<_>>(), diags);
483
484        {
485            let diags_iter_mut = a.diag_iter_mut(DiagOffset::Main);
486            for d in diags_iter_mut {
487                *d = 1.0;
488            }
489        }
490
491        for i in 0..3 {
492            assert_eq!(a[[i,i]], 1.0);
493        }
494    }
495
496    #[test]
497    fn test_empty_matrix_diag() {
498        let a: Matrix<f32> = matrix![];
499
500        assert_eq!(None, a.diag_iter(DiagOffset::Main).next());
501    }
502
503    #[test]
504    fn test_matrix_slice_diag() {
505        let mut a = matrix![0.0, 1.0, 2.0, 3.0;
506                            4.0, 5.0, 6.0, 7.0;
507                            8.0, 9.0, 10.0, 11.0];
508        {
509            let b = MatrixSlice::from_matrix(&a, [0, 0], 2, 4);
510
511            let diags = vec![0.0, 5.0];
512            assert_eq!(b.diag_iter(DiagOffset::Main).cloned().collect::<Vec<_>>(), diags);
513            let diags = vec![1.0, 6.0];
514            assert_eq!(b.diag_iter(DiagOffset::Above(1)).cloned().collect::<Vec<_>>(), diags);
515            let diags = vec![2.0, 7.0];
516            assert_eq!(b.diag_iter(DiagOffset::Above(2)).cloned().collect::<Vec<_>>(), diags);
517            let diags = vec![3.0];
518            assert_eq!(b.diag_iter(DiagOffset::Above(3)).cloned().collect::<Vec<_>>(), diags);
519            let diags = vec![4.0];
520            assert_eq!(b.diag_iter(DiagOffset::Below(1)).cloned().collect::<Vec<_>>(), diags);
521        }
522
523        {
524            let diags_iter_mut = a.diag_iter_mut(DiagOffset::Main);
525            for d in diags_iter_mut {
526                *d = 1.0;
527            }
528        }
529
530        for i in 0..3 {
531            assert_eq!(a[[i,i]], 1.0);
532        }
533    }
534
535    #[test]
536    fn test_matrix_diag_nth() {
537        let a = matrix![0.0, 1.0, 2.0, 3.0;
538                        4.0, 5.0, 6.0, 7.0;
539                        8.0, 9.0, 10.0, 11.0];
540
541        let mut diags_iter = a.diag_iter(DiagOffset::Main);
542        assert_eq!(0.0, *diags_iter.nth(0).unwrap());
543        assert_eq!(10.0, *diags_iter.nth(1).unwrap());
544        assert_eq!(None, diags_iter.next());
545
546        let mut diags_iter = a.diag_iter(DiagOffset::Above(1));
547        assert_eq!(6.0, *diags_iter.nth(1).unwrap());
548        assert_eq!(11.0, *diags_iter.next().unwrap());
549        assert_eq!(None, diags_iter.next());
550
551        let mut diags_iter = a.diag_iter(DiagOffset::Below(1));
552        assert_eq!(9.0, *diags_iter.nth(1).unwrap());
553        assert_eq!(None, diags_iter.next());
554    }
555
556    #[test]
557    fn test_matrix_slice_diag_nth() {
558        let a = matrix![0.0, 1.0, 2.0, 3.0;
559                        4.0, 5.0, 6.0, 7.0;
560                        8.0, 9.0, 10.0, 11.0];
561        let b = MatrixSlice::from_matrix(&a, [0, 0], 2, 4);
562
563        let mut diags_iter = b.diag_iter(DiagOffset::Main);
564        assert_eq!(5.0, *diags_iter.nth(1).unwrap());;
565        assert_eq!(None, diags_iter.next());
566
567        let mut diags_iter = b.diag_iter(DiagOffset::Above(1));
568        assert_eq!(6.0, *diags_iter.nth(1).unwrap());
569        assert_eq!(None, diags_iter.next());
570
571        let mut diags_iter = b.diag_iter(DiagOffset::Below(1));
572        assert_eq!(4.0, *diags_iter.nth(0).unwrap());
573        assert_eq!(None, diags_iter.next());
574    }
575
576    #[test]
577    fn test_matrix_diag_last() {
578        let a = matrix![0.0, 1.0, 2.0;
579                        3.0, 4.0, 5.0;
580                        6.0, 7.0, 8.0];
581
582        let diags_iter = a.diag_iter(DiagOffset::Main);
583        assert_eq!(8.0, *diags_iter.last().unwrap());
584
585        let diags_iter = a.diag_iter(DiagOffset::Above(2));
586        assert_eq!(2.0, *diags_iter.last().unwrap());
587
588        let diags_iter = a.diag_iter(DiagOffset::Below(2));
589        assert_eq!(6.0, *diags_iter.last().unwrap());
590    }
591
592    #[test]
593    fn test_matrix_slice_diag_last() {
594        let a = matrix![0.0, 1.0, 2.0;
595                        3.0, 4.0, 5.0;
596                        6.0, 7.0, 8.0];
597        let b = MatrixSlice::from_matrix(&a, [0, 0], 3, 2);
598
599        {
600            let diags_iter = b.diag_iter(DiagOffset::Main);
601            assert_eq!(4.0, *diags_iter.last().unwrap());
602        }
603
604        {
605            let diags_iter = b.diag_iter(DiagOffset::Above(1));
606            assert_eq!(1.0, *diags_iter.last().unwrap());
607        }
608
609        {
610            let diags_iter = b.diag_iter(DiagOffset::Below(2));
611            assert_eq!(6.0, *diags_iter.last().unwrap());
612        }
613    }
614
615    #[test]
616    fn test_matrix_diag_count() {
617        let a = matrix![0.0, 1.0, 2.0;
618                        3.0, 4.0, 5.0;
619                        6.0, 7.0, 8.0];
620
621        assert_eq!(3, a.diag_iter(DiagOffset::Main).count());
622        assert_eq!(2, a.diag_iter(DiagOffset::Above(1)).count());
623        assert_eq!(1, a.diag_iter(DiagOffset::Above(2)).count());
624        assert_eq!(2, a.diag_iter(DiagOffset::Below(1)).count());
625        assert_eq!(1, a.diag_iter(DiagOffset::Below(2)).count());
626
627        let mut diags_iter = a.diag_iter(DiagOffset::Main);
628        diags_iter.next();
629        assert_eq!(2, diags_iter.count());
630    }
631
632    #[test]
633    fn test_matrix_diag_size_hint() {
634        let a = matrix![0.0, 1.0, 2.0;
635                        3.0, 4.0, 5.0;
636                        6.0, 7.0, 8.0];
637
638        let mut diags_iter = a.diag_iter(DiagOffset::Main);
639        assert_eq!((3, Some(3)), diags_iter.size_hint());
640        diags_iter.next();
641
642        assert_eq!((2, Some(2)), diags_iter.size_hint());
643        diags_iter.next();
644        diags_iter.next();
645
646        assert_eq!((0, Some(0)), diags_iter.size_hint());
647        assert_eq!(None, diags_iter.next());
648        assert_eq!((0, Some(0)), diags_iter.size_hint());
649    }
650
651    #[test]
652    fn test_matrix_cols() {
653        let mut a = matrix![0, 1, 2, 3;
654                            4, 5, 6, 7;
655                            8, 9, 10, 11];
656        let data = [[0, 4, 8], [1, 5, 9], [2, 6, 10], [3, 7, 11]];
657
658        for (i, col) in a.col_iter().enumerate() {
659            for (j, value) in col.iter().enumerate() {
660                assert_eq!(data[i][j], *value);
661            }
662        }
663
664        for (i, mut col) in a.col_iter_mut().enumerate() {
665            for (j, value) in col.iter_mut().enumerate() {
666                assert_eq!(data[i][j], *value);
667            }
668        }
669
670        for mut col in a.col_iter_mut() {
671            for r in col.iter_mut() {
672                *r = 0;
673            }
674        }
675
676        assert_eq!(a.into_vec(), vec![0; 12]);
677    }
678
679    #[test]
680    fn test_matrix_slice_cols() {
681        let a = matrix![0, 1, 2, 3;
682                        4, 5, 6, 7;
683                        8, 9, 10, 11];
684
685        let b = MatrixSlice::from_matrix(&a, [0, 0], 3, 2);
686
687        let data = [[0, 4, 8], [1, 5, 9]];
688
689        for (i, col) in b.col_iter().enumerate() {
690            for (j, value) in col.iter().enumerate() {
691                assert_eq!(data[i][j], *value);
692            }
693        }
694    }
695
696    #[test]
697    fn test_matrix_slice_mut_cols() {
698        let mut a = matrix![0, 1, 2, 3;
699                            4, 5, 6, 7;
700                            8, 9, 10, 11];
701
702        {
703            let mut b = MatrixSliceMut::from_matrix(&mut a, [0, 0], 3, 2);
704
705            let data = [[0, 4, 8], [1, 5, 9]];
706
707            for (i, col) in b.col_iter().enumerate() {
708                for (j, value) in col.iter().enumerate() {
709                    assert_eq!(data[i][j], *value);
710                }
711            }
712
713            for (i, mut col) in b.col_iter_mut().enumerate() {
714                for (j, value) in col.iter_mut().enumerate() {
715                    assert_eq!(data[i][j], *value);
716                }
717            }
718
719            for mut col in b.col_iter_mut() {
720                for r in col.iter_mut() {
721                    *r = 0;
722                }
723            }
724        }
725
726        assert_eq!(a.into_vec(), vec![0, 0, 2, 3, 0, 0, 6, 7, 0, 0, 10, 11]);
727    }
728
729    #[test]
730    fn test_matrix_cols_nth() {
731        let a = matrix![0, 1, 2, 3;
732                        4, 5, 6, 7;
733                        8, 9, 10, 11];
734
735        let mut col_iter = a.col_iter();
736
737        let mut nth0 = col_iter.nth(0).unwrap().into_iter();
738
739        assert_eq!(0, *nth0.next().unwrap());
740        assert_eq!(4, *nth0.next().unwrap());
741        assert_eq!(8, *nth0.next().unwrap());
742
743        let mut nth1 = col_iter.nth(2).unwrap().into_iter();
744
745        assert_eq!(3, *nth1.next().unwrap());
746        assert_eq!(7, *nth1.next().unwrap());
747        assert_eq!(11, *nth1.next().unwrap());
748
749        assert!(col_iter.next().is_none());
750    }
751
752    #[test]
753    fn test_matrix_cols_last() {
754        let a = matrix![0, 1, 2, 3;
755                        4, 5, 6, 7;
756                        8, 9, 10, 11];
757
758        let mut col_iter = a.col_iter().last().unwrap().into_iter();
759
760        assert_eq!(3, *col_iter.next().unwrap());
761        assert_eq!(7, *col_iter.next().unwrap());
762        assert_eq!(11, *col_iter.next().unwrap());
763
764        let mut col_iter = a.col_iter();
765
766        col_iter.next();
767
768        let mut last_col_iter = col_iter.last().unwrap().into_iter();
769
770        assert_eq!(3, *last_col_iter.next().unwrap());
771        assert_eq!(7, *last_col_iter.next().unwrap());
772        assert_eq!(11, *last_col_iter.next().unwrap());
773
774        let mut col_iter = a.col_iter();
775
776        col_iter.next();
777        col_iter.next();
778        col_iter.next();
779        col_iter.next();
780
781        assert!(col_iter.last().is_none());
782    }
783
784    #[test]
785    fn test_matrix_cols_count() {
786        let a = matrix![0, 1, 2;
787                        3, 4, 5;
788                        6, 7, 8];
789
790        let col_iter = a.col_iter();
791
792        assert_eq!(3, col_iter.count());
793
794        let mut col_iter_2 = a.col_iter();
795        col_iter_2.next();
796        assert_eq!(2, col_iter_2.count());
797    }
798
799    #[test]
800    fn test_matrix_cols_size_hint() {
801        let a = matrix![0, 1, 2;
802                        3, 4, 5;
803                        6, 7, 8];
804
805        let mut col_iter = a.col_iter();
806
807        assert_eq!((3, Some(3)), col_iter.size_hint());
808
809        col_iter.next();
810
811        assert_eq!((2, Some(2)), col_iter.size_hint());
812        col_iter.next();
813        col_iter.next();
814
815        assert_eq!((0, Some(0)), col_iter.size_hint());
816
817        assert!(col_iter.next().is_none());
818        assert_eq!((0, Some(0)), col_iter.size_hint());
819    }
820
821    #[test]
822    fn test_matrix_rows() {
823        let mut a = matrix![0, 1, 2;
824                            3, 4, 5;
825                            6, 7, 8];
826
827        let data = [[0, 1, 2], [3, 4, 5], [6, 7, 8]];
828
829        for (i, row) in a.row_iter().enumerate() {
830            assert_eq!(data[i], *row.raw_slice());
831        }
832
833        for (i, row) in a.row_iter_mut().enumerate() {
834            assert_eq!(data[i], *row.raw_slice());
835        }
836
837        for mut row in a.row_iter_mut() {
838            for r in row.raw_slice_mut() {
839                *r = 0;
840            }
841        }
842
843        assert_eq!(a.into_vec(), vec![0; 9]);
844    }
845
846    #[test]
847    fn test_matrix_slice_rows() {
848        let a = matrix![0, 1, 2;
849                        3, 4, 5;
850                        6, 7, 8];
851
852        let b = MatrixSlice::from_matrix(&a, [0, 0], 2, 2);
853
854        let data = [[0, 1], [3, 4]];
855
856        for (i, row) in b.row_iter().enumerate() {
857            assert_eq!(data[i], *row.raw_slice());
858        }
859    }
860
861    #[test]
862    fn test_matrix_slice_mut_rows() {
863        let mut a = matrix![0, 1, 2;
864                            3, 4, 5;
865                            6, 7, 8];
866
867        {
868            let mut b = MatrixSliceMut::from_matrix(&mut a, [0, 0], 2, 2);
869
870            let data = [[0, 1], [3, 4]];
871
872            for (i, row) in b.row_iter().enumerate() {
873                assert_eq!(data[i], *row.raw_slice());
874            }
875
876            for (i, row) in b.row_iter_mut().enumerate() {
877                assert_eq!(data[i], *row.raw_slice());
878            }
879
880            for mut row in b.row_iter_mut() {
881                for r in row.raw_slice_mut() {
882                    *r = 0;
883                }
884            }
885        }
886
887        assert_eq!(a.into_vec(), vec![0, 0, 2, 0, 0, 5, 6, 7, 8]);
888    }
889
890    #[test]
891    fn test_matrix_rows_nth() {
892        let a = matrix![0, 1, 2;
893                        3, 4, 5;
894                        6, 7, 8];
895
896        let mut row_iter = a.row_iter();
897
898        assert_eq!([0, 1, 2], *row_iter.nth(0).unwrap().raw_slice());
899        assert_eq!([6, 7, 8], *row_iter.nth(1).unwrap().raw_slice());
900
901        assert!(row_iter.next().is_none());
902    }
903
904    #[test]
905    fn test_matrix_rows_last() {
906        let a = matrix![0, 1, 2;
907                        3, 4, 5;
908                        6, 7, 8];
909
910        let row_iter = a.row_iter();
911
912        assert_eq!([6, 7, 8], *row_iter.last().unwrap().raw_slice());
913
914        let mut row_iter = a.row_iter();
915
916        row_iter.next();
917        assert_eq!([6, 7, 8], *row_iter.last().unwrap().raw_slice());
918
919        let mut row_iter = a.row_iter();
920
921        row_iter.next();
922        row_iter.next();
923        row_iter.next();
924        row_iter.next();
925
926        assert!(row_iter.last().is_none());
927    }
928
929    #[test]
930    fn test_matrix_rows_count() {
931        let a = matrix![0, 1, 2;
932                        3, 4, 5;
933                        6, 7, 8];
934
935        let row_iter = a.row_iter();
936
937        assert_eq!(3, row_iter.count());
938
939        let mut row_iter_2 = a.row_iter();
940        row_iter_2.next();
941        assert_eq!(2, row_iter_2.count());
942    }
943
944    #[test]
945    fn test_matrix_rows_size_hint() {
946        let a = matrix![0, 1, 2;
947                        3, 4, 5;
948                        6, 7, 8];
949
950        let mut row_iter = a.row_iter();
951
952        assert_eq!((3, Some(3)), row_iter.size_hint());
953
954        row_iter.next();
955
956        assert_eq!((2, Some(2)), row_iter.size_hint());
957        row_iter.next();
958        row_iter.next();
959
960        assert_eq!((0, Some(0)), row_iter.size_hint());
961
962        assert!(row_iter.next().is_none());
963        assert_eq!((0, Some(0)), row_iter.size_hint());
964    }
965
966    #[test]
967    fn into_iter_compile() {
968        let a = Matrix::ones(3, 3) * 2.;
969        let mut b = MatrixSlice::from_matrix(&a, [1, 1], 2, 2);
970
971        for _ in b {
972        }
973
974        for _ in &b {
975        }
976
977        for _ in &mut b {
978        }
979    }
980
981    #[test]
982    fn into_iter_mut_compile() {
983        let mut a = Matrix::<f32>::ones(3, 3) * 2.;
984
985        {
986            let b = MatrixSliceMut::from_matrix(&mut a, [1, 1], 2, 2);
987
988            for v in b {
989                *v = 1.0;
990            }
991        }
992
993        {
994            let b = MatrixSliceMut::from_matrix(&mut a, [1, 1], 2, 2);
995
996            for _ in &b {
997            }
998        }
999
1000        {
1001            let mut b = MatrixSliceMut::from_matrix(&mut a, [1, 1], 2, 2);
1002
1003            for v in &mut b {
1004                *v = 1.0;
1005            }
1006        }
1007    }
1008
1009    #[test]
1010    fn iter_matrix_small_matrices() {
1011        {
1012            let x = matrix![ 1 ];
1013            let mut i = x.iter();
1014            assert_eq!(i.next(), Some(&1));
1015            assert_eq!(i.next(), None);
1016        }
1017
1018        {
1019            let x = matrix![ 1, 2 ];
1020            let mut i = x.iter();
1021            assert_eq!(i.next(), Some(&1));
1022            assert_eq!(i.next(), Some(&2));
1023            assert_eq!(i.next(), None);
1024        }
1025
1026        {
1027            let x = matrix![ 1; 2 ];
1028            let mut i = x.iter();
1029            assert_eq!(i.next(), Some(&1));
1030            assert_eq!(i.next(), Some(&2));
1031            assert_eq!(i.next(), None);
1032        }
1033
1034        {
1035            let x = matrix![ 1, 2;
1036                             3, 4 ];
1037            let mut i = x.iter();
1038            assert_eq!(i.next(), Some(&1));
1039            assert_eq!(i.next(), Some(&2));
1040            assert_eq!(i.next(), Some(&3));
1041            assert_eq!(i.next(), Some(&4));
1042            assert_eq!(i.next(), None);
1043        }
1044    }
1045
1046    #[test]
1047    fn iter_matrix_slice() {
1048        let x = matrix![1, 2, 3;
1049                        4, 5, 6;
1050                        7, 8, 9];
1051
1052        // Helper to simplify writing the below tests.
1053        // Note that .collect() is an implicit test of .next(),
1054        // including checking that None is returned when there
1055        // are no more elements.
1056        let collect_slice = |(i, j), rows, cols| {
1057            x.sub_slice([i, j], rows, cols)
1058             .iter()
1059             .cloned()
1060             .collect::<Vec<_>>()
1061        };
1062
1063        {
1064            // Zero elements
1065            for i in 0 .. 2 {
1066                for j in 0 .. 2 {
1067                    let y = x.sub_slice([i, j], 0, 0);
1068                    assert!(y.iter().next().is_none());
1069                }
1070            }
1071
1072        }
1073
1074        {
1075            // One element
1076            for i in 0 .. 2 {
1077                for j in 0 .. 2 {
1078                    let y = x.sub_slice([i, j], 1, 1);
1079                    assert_eq!(y.iter().next(), Some(&x[[i, j]]));
1080                }
1081            }
1082        }
1083
1084        {
1085            // 1x2 sub slices
1086            assert_eq!(collect_slice((0, 0), 1, 2), vec![1, 2]);
1087            assert_eq!(collect_slice((0, 1), 1, 2), vec![2, 3]);
1088            assert_eq!(collect_slice((1, 0), 1, 2), vec![4, 5]);
1089            assert_eq!(collect_slice((1, 1), 1, 2), vec![5, 6]);
1090            assert_eq!(collect_slice((2, 0), 1, 2), vec![7, 8]);
1091            assert_eq!(collect_slice((2, 1), 1, 2), vec![8, 9]);
1092        }
1093
1094        {
1095            // 2x1 sub slices
1096            assert_eq!(collect_slice((0, 0), 2, 1), vec![1, 4]);
1097            assert_eq!(collect_slice((1, 0), 2, 1), vec![4, 7]);
1098            assert_eq!(collect_slice((0, 1), 2, 1), vec![2, 5]);
1099            assert_eq!(collect_slice((1, 1), 2, 1), vec![5, 8]);
1100            assert_eq!(collect_slice((0, 2), 2, 1), vec![3, 6]);
1101            assert_eq!(collect_slice((1, 2), 2, 1), vec![6, 9]);
1102        }
1103
1104        {
1105            // 2x2 sub slices
1106            assert_eq!(collect_slice((0, 0), 2, 2), vec![1, 2, 4, 5]);
1107            assert_eq!(collect_slice((0, 1), 2, 2), vec![2, 3, 5, 6]);
1108            assert_eq!(collect_slice((1, 0), 2, 2), vec![4, 5, 7, 8]);
1109            assert_eq!(collect_slice((1, 1), 2, 2), vec![5, 6, 8, 9]);
1110        }
1111    }
1112
1113    #[test]
1114    fn iter_empty_matrix() {
1115        {
1116            let x = Matrix::<u32>::zeros(0, 0);
1117            assert!(x.iter().next().is_none());
1118        }
1119
1120        {
1121            let x = Matrix::<u32>::zeros(1, 0);
1122            assert!(x.iter().next().is_none());
1123        }
1124
1125        {
1126            let x = Matrix::<u32>::zeros(0, 1);
1127            assert!(x.iter().next().is_none());
1128        }
1129    }
1130}