lattice_graph/square/
nodes.rs

1use petgraph::{
2    graph::IndexType,
3    visit::{NodeCompactIndexable, NodeCount},
4};
5
6use super::*;
7use ndarray;
8
9impl<N, E, Ix, S> IntoNodeIdentifiers for &SquareGraph<N, E, Ix, S>
10where
11    Ix: IndexType,
12    Range<Ix>: Iterator<Item = Ix>,
13{
14    type NodeIdentifiers = NodeIndices<Ix>;
15
16    fn node_identifiers(self) -> Self::NodeIdentifiers {
17        NodeIndices::new(self.horizontal_node_count(), self.vertical_node_count())
18    }
19}
20
21/// Iterate all index of [`SquareGraph`]. See [`node_identifiers`](`IntoNodeIdentifiers::node_identifiers`).
22#[derive(Clone, Debug)]
23pub struct NodeIndices<Ix> {
24    pub(crate) h_max: usize,
25    h: usize,
26    pub(crate) v_max: usize,
27    v: usize,
28    pd: PhantomData<Ix>,
29}
30
31impl<Ix> NodeIndices<Ix> {
32    pub(crate) fn new(h: usize, v: usize) -> Self {
33        Self {
34            h_max: h,
35            h: 0,
36            v_max: v,
37            v: 0,
38            pd: PhantomData,
39        }
40    }
41}
42
43impl<Ix: IndexType> Iterator for NodeIndices<Ix> {
44    type Item = NodeIndex<Ix>;
45
46    fn next(&mut self) -> Option<Self::Item> {
47        let nv: usize;
48        if self.v < self.v_max {
49            nv = self.v;
50            self.v += 1;
51        } else if self.h + 1 < self.h_max {
52            nv = 0;
53            self.v = 1;
54            self.h += 1;
55        } else {
56            return None;
57        }
58        Some(NodeIndex::new(Ix::new(self.h), Ix::new(nv)))
59    }
60
61    fn size_hint(&self) -> (usize, Option<usize>) {
62        let len = self.v_max * (self.h_max - self.h) - self.v;
63        (len, Some(len))
64    }
65}
66
67impl<Ix: IndexType> FusedIterator for NodeIndices<Ix> {}
68impl<Ix: IndexType> ExactSizeIterator for NodeIndices<Ix> {}
69
70impl<'a, N: Clone, E, Ix, S> IntoNodeReferences for &'a SquareGraph<N, E, Ix, S>
71where
72    Ix: IndexType,
73    Range<Ix>: Iterator<Item = Ix>,
74{
75    type NodeRef = (NodeIndex<Ix>, &'a N);
76    type NodeReferences = NodeReferences<'a, N, Ix>;
77
78    fn node_references(self) -> Self::NodeReferences {
79        NodeReferences {
80            indices: self.node_identifiers(),
81            nodes: self.nodes.iter(),
82        }
83    }
84}
85
86/// Iterate all nodes of [`SquareGraph`]. See [`node_references`](`IntoNodeReferences::node_references`).
87#[derive(Clone)]
88pub struct NodeReferences<'a, N, Ix> {
89    indices: NodeIndices<Ix>,
90    nodes: ndarray::iter::Iter<'a, N, ndarray::Dim<[usize; 2]>>,
91}
92
93impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
94where
95    Ix: IndexType,
96    Range<Ix>: Iterator<Item = Ix>,
97{
98    type Item = (NodeIndex<Ix>, &'a N);
99
100    fn next(&mut self) -> Option<Self::Item> {
101        let n = self.nodes.next()?;
102        Some((self.indices.next()?, n))
103    }
104
105    fn size_hint(&self) -> (usize, Option<usize>) {
106        self.nodes.size_hint()
107    }
108
109    fn count(self) -> usize
110    where
111        Self: Sized,
112    {
113        self.nodes.count()
114    }
115}
116
117impl<'a, N, Ix> FusedIterator for NodeReferences<'a, N, Ix>
118where
119    Ix: IndexType,
120    Range<Ix>: Iterator<Item = Ix>,
121{
122}
123
124impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix>
125where
126    Ix: IndexType,
127    Range<Ix>: Iterator<Item = Ix>,
128{
129}
130
131impl<N, E, Ix, S> NodeCompactIndexable for SquareGraph<N, E, Ix, S> where Ix: IndexType {}
132
133impl<N, E, Ix, S> NodeCount for SquareGraph<N, E, Ix, S>
134where
135    Ix: IndexType,
136{
137    fn node_count(&self) -> usize {
138        self.nodes.len()
139    }
140}
141
142impl<N, E, Ix, S> NodeIndexable for SquareGraph<N, E, Ix, S>
143where
144    Ix: IndexType,
145{
146    fn node_bound(&self) -> usize {
147        self.nodes.len()
148    }
149
150    fn to_index(&self, a: Self::NodeId) -> usize {
151        a.horizontal.index() * self.vertical_node_count() + a.vertical.index()
152    }
153
154    fn from_index(&self, i: usize) -> Self::NodeId {
155        let h = self.vertical_node_count();
156        (i / h, i % h).into()
157    }
158}