open_hypergraphs/indexed_coproduct/
semifinite_iterator.rs

1//! [`IndexedCoproduct`] as collections of [`FiniteFunction`]s.
2//! NOTE: the implementations here are not optimized.
3use crate::array::*;
4#[allow(unused_imports)] // for docs
5use crate::finite_function::*;
6use crate::indexed_coproduct::*;
7use crate::semifinite::*;
8use core::iter::IntoIterator;
9use num_traits::{One, Zero};
10
11/// Iterator for IndexedCoproduct that yields each element
12pub struct IndexedCoproductSemifiniteFunctionIterator<K: ArrayKind, T> {
13    /// Cumulative sum of sources of an indexed coproduct
14    pointers: K::Type<K::I>,
15
16    /// Unchanged values array
17    values: SemifiniteFunction<K, T>,
18
19    /// index of next slice.
20    index: K::I,
21}
22
23impl<K: ArrayKind, T> Iterator for IndexedCoproductSemifiniteFunctionIterator<K, T>
24where
25    K::Type<K::I>: NaturalArray<K>,
26    K::Type<T>: Array<K, T>,
27    K::I: Into<usize>,
28{
29    type Item = SemifiniteFunction<K, T>;
30
31    fn next(&mut self) -> Option<Self::Item> {
32        // Check if we've reached the end of the iterator
33        if self.index >= self.pointers.len() - K::I::one() {
34            return None;
35        }
36
37        // Get the start and end indices for this slice
38        let start = self.pointers.get(self.index.clone());
39        let end = self.pointers.get(self.index.clone() + K::I::one());
40
41        // Create a SemifiniteFunction from the slice of values between start and end
42        let values = self.values.0.get_range(start.clone()..end.clone());
43
44        // Create a new SemifiniteFunction with the extracted values
45        let ff = SemifiniteFunction::new(K::Type::<T>::from_slice(values));
46
47        // Increment the index for the next call
48        self.index = self.index.clone() + K::I::one();
49
50        Some(ff)
51    }
52
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        let n = (self.pointers.len() - K::I::one()).into();
55        (n, Some(n)) // exact size is known
56    }
57}
58
59impl<K: ArrayKind, T> ExactSizeIterator for IndexedCoproductSemifiniteFunctionIterator<K, T>
60where
61    K::Type<K::I>: NaturalArray<K>,
62    K::Type<T>: Array<K, T>,
63    K::I: Into<usize>,
64{
65    fn len(&self) -> usize {
66        (self.pointers.len() - K::I::one()).into()
67    }
68}
69
70impl<K: ArrayKind, T> IntoIterator for IndexedCoproduct<K, SemifiniteFunction<K, T>>
71where
72    K::Type<K::I>: NaturalArray<K>,
73    K::Type<T>: Array<K, T>,
74    K::I: Into<usize>,
75{
76    type Item = SemifiniteFunction<K, T>;
77    type IntoIter = IndexedCoproductSemifiniteFunctionIterator<K, T>;
78
79    fn into_iter(self) -> Self::IntoIter {
80        IndexedCoproductSemifiniteFunctionIterator {
81            pointers: self.sources.table.into().cumulative_sum(),
82            values: self.values,
83            index: K::I::zero(),
84        }
85    }
86}