algeo/linalg/
util.rs

1use std::cmp::Ordering;
2
3use crate::core::num::Field;
4
5use super::mat::Mat;
6
7// (0,0), (0,1), ..., (0,cols)
8// (1,0), (1,1), ..., (1,cols)
9//  ...                 ...
10// (row,0) ...
11pub 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}