1use std::cmp::Ordering;
2
3use crate::core::num::Field;
4
5use super::mat::Mat;
6
7pub fn get_box_iter(rows: usize, cols: usize) -> impl Iterator<Item=(usize, usize)>{
12 (0..rows).map(move |r| ((0..cols).map(move |c| (r,c) ) ) ).flatten()
13}
14
15pub fn get_max_index<T, I, C>(slice: I, le: C) -> usize where
16 I: Iterator<Item=T>,
17 C: Fn(&T, &T)->Option<Ordering> {
18
19 slice
20 .enumerate()
21 .max_by(|(_n, x), (_m, y)| le(x, y).unwrap())
22 .unwrap()
23 .0
24}
25
26pub fn num_to_seq(n: usize, base: usize) -> impl Iterator<Item=(usize)> {
27 BaseSeqIterator::new(n, base)
28}
29
30struct BaseSeqIterator {
31 n: usize,
32 base: usize
33}
34
35impl BaseSeqIterator {
36 pub fn new(n: usize, base: usize) -> BaseSeqIterator {
37 BaseSeqIterator {
38 n: n*base,
39 base
40 }
41 }
42}
43
44impl Iterator for BaseSeqIterator {
45 type Item = usize;
46
47 fn next(&mut self) -> Option<Self::Item> {
48 self.n /= self.base;
49
50 if self.n == 0 {
51 None
52 } else {
53 Some(self.n % self.base)
54 }
55 }
56}
57
58pub fn mat_iterator<'a, F: Field>(n: usize, m: usize, values: &'a [F])-> impl 'a + Iterator<Item=Mat<F>>{
59 MatIterator {
60 values,
61 n,
62 m,
63 num: 0
64 }
65}
66
67pub struct MatIterator<'a, F: Field> {
68 values: &'a [F],
69 n: usize,
70 m: usize,
71 num: usize,
72}
73
74impl<'a, F: Field> Iterator for MatIterator<'a, F> {
75 type Item = Mat<F>;
76
77 fn next(&mut self) -> Option<Mat<F>> {
78 if self.num >= self.values.len().pow((self.n * self.m) as u32) {
79 None
80 } else {
81 let mut entries: Vec<F> = num_to_seq(self.num, self.values.len())
82 .map(|i| self.values[i]).collect();
83
84 for _i in (entries.len())..(self.n * self.m) {
85 entries.push(self.values[0]);
86 }
87
88 self.num += 1;
89
90 Some(Mat::new(self.n, self.m, entries))
91 }
92 }
93}