sparse_bin_mat/matrix/
non_trivial_elements.rs1use super::SparseBinMat;
2
3#[derive(Debug, Clone)]
7pub struct NonTrivialElements<'a> {
8 matrix: &'a SparseBinMat,
9 row_index: usize,
10 column_index: usize,
11}
12
13impl<'a> NonTrivialElements<'a> {
14 pub(super) fn new(matrix: &'a SparseBinMat) -> Self {
15 Self {
16 matrix,
17 row_index: 0,
18 column_index: 0,
19 }
20 }
21
22 fn next_element(&mut self) -> Option<(usize, usize)> {
23 self.matrix
24 .row(self.row_index)
25 .and_then(|row| row.as_slice().get(self.column_index).cloned())
26 .map(|column| (self.row_index, column))
27 }
28
29 fn move_to_next_row(&mut self) {
30 self.row_index += 1;
31 self.column_index = 0;
32 }
33
34 fn move_to_next_column(&mut self) {
35 self.column_index += 1;
36 }
37
38 fn is_done(&self) -> bool {
39 self.row_index >= self.matrix.number_of_rows()
40 }
41}
42
43impl<'a> Iterator for NonTrivialElements<'a> {
44 type Item = (usize, usize);
45
46 fn next(&mut self) -> Option<Self::Item> {
47 if self.is_done() {
48 None
49 } else {
50 match self.next_element() {
51 Some(element) => {
52 self.move_to_next_column();
53 Some(element)
54 }
55 None => {
56 self.move_to_next_row();
57 self.next()
58 }
59 }
60 }
61 }
62}
63
64#[cfg(test)]
65mod test {
66 use super::*;
67
68 #[test]
69 fn non_trivial_elements_of_small_matrix() {
70 let matrix = SparseBinMat::new(3, vec![vec![1], vec![0, 2], vec![0, 1, 2]]);
71 let mut iter = NonTrivialElements::new(&matrix);
72
73 assert_eq!(iter.next(), Some((0, 1)));
74 assert_eq!(iter.next(), Some((1, 0)));
75 assert_eq!(iter.next(), Some((1, 2)));
76 assert_eq!(iter.next(), Some((2, 0)));
77 assert_eq!(iter.next(), Some((2, 1)));
78 assert_eq!(iter.next(), Some((2, 2)));
79 assert_eq!(iter.next(), None);
80 }
81}