qmat/
mat.rs

1#![warn(clippy::all, clippy::pedantic)]
2
3use std::{
4    iter::Sum,
5    ops::{Add, Index, IndexMut, Mul, Sub},
6};
7
8use crate::{
9    errors::{MatrixOperationError, NewMatrixError},
10    identities::Identity,
11    math::arr_dot,
12    position::Position,
13};
14
15/// A matrix of `M` rows and `N` columns. <br/>
16/// `LEN` is the length of the internal array `data: [T; LEN]` that stores all the elements (i.e. `LEN` = `M` * `N`).
17#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct Matrix<T, const M: usize, const N: usize, const LEN: usize> {
19    data: [T; LEN],
20}
21
22impl<T, const M: usize, const N: usize, const LEN: usize> Matrix<T, M, N, LEN> {
23    /// Creates a new Matrix from given dimensions and flat data.
24    ///
25    /// # Errors
26    /// * `NewMatrixError::IllegalGenerics` if `M * N != LEN`
27    ///
28    /// # Examples
29    /// ```rust
30    /// use qmat::prelude::*;
31    /// let mat = Matrix::<_, 3, 2, 6>::new([4, 2, 10, 5, 5, 6]);
32    /// assert!(mat.is_ok());
33    /// ```
34    pub fn new(data: [T; LEN]) -> Result<Self, NewMatrixError> {
35        if M * N != LEN {
36            return Err(NewMatrixError::IllegalGenerics);
37        }
38        Ok(Matrix { data })
39    }
40
41    /// Returns an immutable reference to the underlying 1-dimensional data.
42    ///
43    /// Flattened such that the matrix <br/>
44    /// &nbsp;&nbsp;&nbsp;&nbsp;`[a, b, c]` <br/>
45    /// &nbsp;&nbsp;&nbsp;&nbsp;`[d, e, f]`<br/>
46    /// becomes `[a, b, c, d, e, f]`.
47    #[must_use]
48    pub fn as_flat_array(&self) -> &[T; LEN] {
49        &self.data
50    }
51
52    /// Returns the constant number of rows, `M`.
53    #[must_use]
54    #[allow(clippy::unused_self)] // so you can call someMatrix.rows()
55    pub fn rows(&self) -> usize {
56        M
57    }
58
59    /// Returns the constant number of columns, `N`.
60    #[must_use]
61    #[allow(clippy::unused_self)] // so you can call someMatrix.cols()
62    pub fn cols(&self) -> usize {
63        N
64    }
65
66    /// The number of elements in the matrix (i.e. the number of rows times the number of cols).
67    #[must_use]
68    #[allow(clippy::unused_self)] // so you can call someMatrix.vol()
69    pub fn vol(&self) -> usize {
70        LEN
71    }
72
73    /// Iterates over immutable references to all of the elements of a matrix.
74    pub fn iter(&self) -> Iter<T, M, N, LEN> {
75        Iter {
76            data: &self.data,
77            i: 0,
78        }
79    }
80
81    /// TODO: implement myself.
82    /// Currently just passes the `iter_mut` call to the underlying array.
83    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
84        self.data.iter_mut()
85    }
86
87    /// Creates an iterator for the matrix's rows by moving matrix ownership.
88    pub fn into_iter_row(self) -> IntoIterRow<T, M, N, LEN> {
89        IntoIterRow {
90            i: 0,
91            data: self.data,
92        }
93    }
94
95    /// Iterates over rows, using immutable references to the original array's data.
96    pub fn iter_row(&self) -> IterRow<'_, T, M, N, LEN> {
97        IterRow {
98            i: 0,
99            data: &self.data,
100        }
101    }
102
103    /// Unimplemented method.
104    /// Iterates over rows, using mutable references to the original array's data.
105    #[allow(clippy::unused_self)]
106    pub fn iter_row_mut(&mut self) {
107        unimplemented!();
108    }
109
110    /// Creates an iterator for the matrix's columns by moving matrix ownership.
111    pub fn into_iter_col(self) -> IntoIterCol<T, M, N, LEN> {
112        IntoIterCol {
113            i: 0,
114            data: self.data,
115        }
116    }
117
118    /// Iterates over columns, using immutable references to the original array's data.
119    pub fn iter_col(&self) -> IterCol<'_, T, M, N, LEN> {
120        IterCol {
121            i: 0,
122            data: &self.data,
123        }
124    }
125
126    /// Iterates over columns, using mutable references to the original array's data.
127    /// Unimplemented method.
128    #[allow(clippy::unused_self)]
129    pub fn iter_col_mut(&mut self) {
130        unimplemented!();
131    }
132}
133
134impl<T, const M: usize, const N: usize, const LEN: usize> Matrix<T, M, N, LEN>
135where
136    T: Default + Copy,
137{
138    /// # Errors
139    /// * `NewMatrixError::IllegalGenerics` if `M * N != LEN`
140    ///
141    /// # Examples
142    /// ```rust
143    /// use qmat::prelude::*;
144    /// let mat = Matrix::<i32, 5, 5, 25>::empty().unwrap();
145    /// println!("{:?}", mat);
146    /// ```
147    pub fn empty() -> Result<Self, NewMatrixError> {
148        Self::new([Default::default(); LEN])
149    }
150
151    /// Errors
152    /// * Same as `Matrix::new`
153    #[allow(clippy::missing_errors_doc)] // idk why clippy can't read
154    pub fn from_rows(data: [[T; N]; M]) -> Result<Self, NewMatrixError> {
155        let mut flat_data: [T; LEN] = [Default::default(); LEN];
156        let mut i: usize = 0;
157        for row in data {
158            for elem in row {
159                flat_data[i] = elem;
160                i += 1;
161            }
162        }
163        Self::new(flat_data)
164    }
165
166    /// Gets a specific row of the matrix.
167    ///  
168    /// # Panics
169    /// * When it fails to make an empty matrix.
170    ///
171    /// # Examples
172    /// ```rust
173    /// use qmat::prelude::*;
174    /// let mat = Matrix::<_, 2, 2, 4>::new([0, 1, 2, 3]).unwrap(); // [[0, 1], [2, 3]]
175    /// assert_eq!(mat.get_row(0)[[0, 0]], 0);
176    /// assert_eq!(mat.get_row(0)[[0, 1]], 1);
177    /// assert_eq!(mat.get_row(1)[[0, 0]], 2);
178    /// assert_eq!(mat.get_row(1)[[0, 1]], 3);
179    /// ```
180    #[must_use]
181    pub fn get_row(&self, row: usize) -> Matrix<T, N, 1, N> {
182        let mut output = Matrix::empty().unwrap();
183        for i in 0..N {
184            output.data[i] = self.data[row * N + i];
185        }
186        output
187    }
188
189    /// Gets a specific column of the matrix.
190    ///  
191    /// # Panics
192    /// * When it fails to make an empty matrix.
193    ///
194    /// # Examples
195    /// ```rust
196    /// use qmat::prelude::*;
197    /// let mat = Matrix::<_, 2, 2, 4>::new([0, 1, 2, 3]).unwrap(); // [[0, 1], [2, 3]]
198    /// assert_eq!(mat.get_col(0)[[0, 0]], 0);
199    /// assert_eq!(mat.get_col(0)[[0, 1]], 2);
200    /// assert_eq!(mat.get_col(1)[[0, 0]], 1);
201    /// assert_eq!(mat.get_col(1)[[0, 1]], 3);
202    /// ```
203    #[must_use]
204    pub fn get_col(&self, col: usize) -> Matrix<T, M, 1, M> {
205        let mut output = Matrix::empty().unwrap();
206        for row in 0..M {
207            output.data[row] = self[[row, col]];
208        }
209        output
210    }
211}
212
213impl<T, const M: usize, const N: usize, const LEN: usize> Matrix<T, M, N, LEN>
214where
215    T: Default + Copy + Mul + Sum<<T as Mul>::Output>,
216{
217    /// Turbofish `::<O, Q, RES_LEN>` where
218    /// * `O` is the number of columns in the other matrix,
219    /// * `Q` is the array length in the other matrix,
220    /// * `RES_LEN` is the number of elements in the resulting matrix (`M` * `O`) where `M` is rows in `self`
221    ///
222    /// # Panics
223    /// * When it fails to make an empty matrix.
224    ///
225    /// # Examples
226    /// ```rust
227    /// use qmat::prelude::*;
228    ///
229    /// let a = Matrix::<_, 2, 2, 4>::new([3, 4, 2, 1]).unwrap();
230    /// let b = Matrix::<_, 2, 2, 4>::new([1, 5, 3, 7]).unwrap();
231    /// let output = a.multiply::<2, 4, 4>(&b);
232    ///
233    /// assert_eq!(output[[0, 0]], 15);
234    /// assert_eq!(output[[0, 1]], 43);
235    /// assert_eq!(output[[1, 0]], 5);
236    /// assert_eq!(output[[1, 1]], 17);
237    /// ```
238    pub fn multiply<const O: usize, const Q: usize, const RES_LEN: usize>(
239        &self,
240        other: &Matrix<T, N, O, Q>,
241    ) -> Matrix<T, M, O, RES_LEN> {
242        let mut out: Matrix<T, M, O, RES_LEN> = Matrix::empty().unwrap();
243
244        for row in 0..N {
245            for col in 0..O {
246                out[[row, col]] = self.get_row(row).dot(&other.get_col(col));
247            }
248        }
249
250        out
251    }
252}
253
254impl<T, const M: usize, const N: usize, const LEN: usize> Matrix<T, M, N, LEN>
255where
256    T: Default + Copy + Mul<Output = T>,
257{
258    /// Multiplies a matrix with and scalar value.
259    /// Iterates over all elements in the matrix and multiplies it by the given scalar.
260    ///
261    /// # Examples
262    /// ```rust
263    /// use qmat::prelude::*;
264    /// let mat = matrix!{[[0, 1, 2]]};
265    /// let res = mat.mul_scalar(3);
266    /// assert_eq!(res[[0, 0]], 0);
267    /// assert_eq!(res[[0, 1]], 3);
268    /// assert_eq!(res[[0, 2]], 6);
269    /// ```
270    ///
271    /// # Panics
272    /// * When it fails to make an empty matrix.
273    #[must_use]
274    pub fn mul_scalar(&self, scalar: T) -> Self {
275        let mut out = Matrix::empty().unwrap();
276        for i in 0..LEN {
277            out.data[i] = self.data[i] * scalar;
278        }
279        out
280    }
281}
282
283impl<T, const M: usize, const N: usize, const LEN: usize> Index<Position> for Matrix<T, M, N, LEN> {
284    type Output = T;
285    fn index(&self, pos: Position) -> &Self::Output {
286        &self.data[pos.0 * N + pos.1]
287    }
288}
289
290impl<T, const M: usize, const N: usize, const LEN: usize> IndexMut<Position>
291    for Matrix<T, M, N, LEN>
292{
293    fn index_mut(&mut self, pos: Position) -> &mut Self::Output {
294        &mut self.data[pos.0 * N + pos.1]
295    }
296}
297
298impl<T, const M: usize, const N: usize, const LEN: usize> Index<[usize; 2]>
299    for Matrix<T, M, N, LEN>
300{
301    type Output = T;
302
303    /// # Examples
304    /// ```
305    /// use qmat::prelude::*;
306    /// let mat = Matrix::<_, 2, 3, 6>::new([0, 1, 2, 3, 4, 5]).unwrap();
307    /// assert_eq!(mat[[0, 0]], 0); // [0, 0] => 0*3 + 0 = 0
308    /// assert_eq!(mat[[0, 1]], 1); // [0, 1] => 0*3 + 1 = 1
309    /// assert_eq!(mat[[0, 2]], 2); // [0, 2] => 0*3 + 2 = 2
310    /// assert_eq!(mat[[1, 0]], 3); // [0, 0] => 1*3 + 0 = 3
311    /// assert_eq!(mat[[1, 1]], 4); // [1, 1] => 1*3 + 1 = 4
312    /// assert_eq!(mat[[1, 2]], 5); // [2, 2] => 1*3 + 2 = 5
313    /// ```
314    fn index(&self, pos: [usize; 2]) -> &Self::Output {
315        // it should panic anyways, no need to add an extra check
316        //assert!(pos[0] <= M);
317        //assert!(pos[1] <= N);
318        &self.data[pos[0] * N + pos[1]]
319    }
320}
321
322impl<T, const M: usize, const N: usize, const LEN: usize> IndexMut<[usize; 2]>
323    for Matrix<T, M, N, LEN>
324{
325    /// # Examples
326    /// ```
327    /// use qmat::prelude::*;
328    /// let mut mat = Matrix::<_, 2, 3, 6>::new([0, 1, 2, 3, 4, 5]).unwrap();
329    /// mat[[0, 2]] = 12;
330    /// assert_eq!(mat[[0, 2]], 12);
331    /// ```
332    fn index_mut(&mut self, pos: [usize; 2]) -> &mut Self::Output {
333        // it should panic anyways, no need to add an extra check
334        //assert!(pos[0] <= M);
335        //assert!(pos[1] <= N);
336        &mut self.data[pos[0] * N + pos[1]]
337    }
338}
339
340impl<T, const M: usize, const N: usize, const LEN: usize> Add for Matrix<T, M, N, LEN>
341where
342    T: Add<Output = T> + Default + Copy,
343{
344    type Output = Self;
345
346    /// Returns a matrix where element `i` is `lhs[i] + rhs[i]`.
347    ///
348    /// # Examples
349    /// ```rust
350    /// use qmat::prelude::*;
351    ///
352    /// let lhs = matrix!([[3, 17], [128, 5]]);
353    /// let rhs = matrix!([[63, 12], [4, 3]]);
354    /// let added = lhs + rhs;
355    ///
356    /// assert_eq!(added[[0, 0]], 66); // 3 + 63
357    /// assert_eq!(added[[0, 1]], 29); // 17 + 12
358    /// assert_eq!(added[[1, 0]], 132); // 128 + 4
359    /// assert_eq!(added[[1, 1]], 8); // 5 + 3
360    /// ```
361    fn add(self, rhs: Self) -> Self::Output {
362        let mut added = Self::empty().unwrap();
363
364        for i in 0..LEN {
365            added.data[i] = self.data[i] + rhs.data[i];
366        }
367
368        added
369    }
370}
371
372impl<T, const M: usize> Matrix<T, M, 1, M>
373where
374    T: Copy + Mul + Sum<<T as Mul>::Output>,
375{
376    /// # Examples
377    /// ```rust
378    /// use qmat::prelude::*;
379    ///
380    /// let vec1 = Matrix::<i32, 3, 1, 3>::new([2, 4, 3]).unwrap();
381    /// let vec2 = Matrix::<i32, 3, 1, 3>::new([1, 3, 3]).unwrap();
382    ///
383    /// assert_eq!(vec1.dot(&vec2), 23);
384    /// ```
385    #[must_use]
386    pub fn dot(&self, other: &Self) -> T {
387        //self.data.iter().enumerate().map(|(i, x)| {*x * other.data[i]}).sum()
388        arr_dot(*self.as_flat_array(), *other.as_flat_array())
389    }
390}
391
392impl<T, const M: usize, const N: usize, const LEN: usize> Sub for Matrix<T, M, N, LEN>
393where
394    T: Sub<Output = T> + Default + Copy,
395{
396    type Output = Self;
397
398    /// # Examples
399    /// ```rust
400    /// use qmat::prelude::*;
401    ///
402    /// let lhs = matrix!([[3, 17], [128, 5]]);
403    /// let rhs = matrix!([[63, 12], [4, 3]]);
404    /// let subbed = lhs - rhs;
405    ///
406    /// assert_eq!(subbed[[0, 0]], -60);  // 3 - 63
407    /// assert_eq!(subbed[[0, 1]], 5);  // 17 - 12
408    /// assert_eq!(subbed[[1, 0]], 124); // 128 - 4
409    /// assert_eq!(subbed[[1, 1]], 2);   // 5 - 3
410    /// ```
411    fn sub(self, rhs: Self) -> Self::Output {
412        let mut subbed = Self::empty().unwrap();
413        for i in 0..LEN {
414            subbed.data[i] = self.data[i] - rhs.data[i];
415        }
416        subbed
417    }
418}
419
420impl<T, const M: usize, const LEN: usize> Matrix<T, M, M, LEN>
421where
422    T: Default + Copy,
423{
424    /// Creates a new matrix such that every value in the diagonal from the top left (`[0, 0]`) to the bottom left (`[M, M]`) are equal to `val`.
425    ///
426    /// # Examples
427    /// ```rust
428    /// use qmat::prelude::Matrix;
429    ///
430    /// let mat: Matrix<i32, 3, 3, 9> = Matrix::diag(3);
431    /// assert_eq!(mat[[0, 0]], 3);
432    /// assert_eq!(mat[[1, 1]], 3);
433    /// assert_eq!(mat[[2, 2]], 3);
434    /// ```
435    ///
436    /// # Panics
437    /// * If it fails to create an empty matrix.
438    #[must_use]
439    pub fn diag(val: T) -> Self {
440        let mut mat = Self::empty().unwrap();
441
442        for i in 0..M {
443            mat[[i, i]] = val;
444        }
445
446        mat
447    }
448}
449
450impl<T, const M: usize, const N: usize, const LEN: usize> Matrix<T, M, N, LEN>
451where
452    T: num_traits::Num + Copy,
453{
454    /// Returns the [determinant](https://en.wikipedia.org/wiki/Determinant) of a matrix.
455    #[must_use]
456    pub fn det(&self) -> T {
457        let mat = self;
458        let mut mat = *mat; // hopefully dereferences a copy of self?
459        let mut temp = [T::zero(); N]; // temp array for row storage
460        let mut total: T = T::one();
461        let mut det: T = T::one(); // init res
462
463        // loop for traversing diagonal elems
464        for i in 0..N {
465            let mut index = i;
466
467            // finding non-zero value
468            while index < N && self[[index, i]] == T::zero() {
469                index += 1;
470            }
471
472            if index == N {
473                // there is non-zero elem
474                // det of matrix is 0
475                continue;
476            }
477            if index != i {
478                // loop for swapping the diagonal element row and index row
479                for j in 0..N {
480                    (mat[[index, j]], mat[[i, j]]) = (mat[[i, j]], mat[[index, j]]);
481                }
482
483                // det sign changes when row is shifted
484                let exp = index - i;
485                if exp % 2 == 1 {
486                    det = det * (T::zero() - T::one());
487                }
488            }
489
490            // storing diagonal row elems
491            for j in 0..N {
492                temp[j] = mat[[i, j]];
493            }
494
495            // traversing every col of row and mul to every row
496            for j in (i + 1)..N {
497                let num1 = temp[i]; // value of diagonal elem
498                let num2 = mat[[j, i]]; // value of next row elem
499
500                // traverse every column of row and mul to every row
501                for k in 0..N {
502                    // multiply to make the diagonal element and next row element equal
503                    mat[[j, k]] = (num1 * mat[[j, k]]) - (num2 * temp[k]);
504                }
505
506                total = total * num1; // Det(kA)=Det(A)
507            }
508        }
509
510        for i in 0..N {
511            det = det * mat[[i, i]];
512        }
513
514        det / total
515    }
516}
517
518impl<T, const M: usize, const LEN: usize> Matrix<T, M, M, LEN>
519where
520    T: num_traits::Num + Copy + Default + Identity,
521{
522    /// # Errors
523    /// * `MatrixOperationError::InvalidDeterminant` is `self.det() == 0`.
524    ///
525    /// # Panics
526    /// * If it fails to create an empty matrix.
527    /// * When trying to get the inverse of a matrix that isn't 2x2. (Currently unimplemented.)
528    pub fn inverse(&self) -> Result<Self, MatrixOperationError> {
529        match M {
530            2 => self.inverse_2x2(),
531            _ => self.inverse_gauss_jordan(),
532        }
533    }
534
535    fn inverse_2x2(&self) -> Result<Self, MatrixOperationError> {
536        let det = self.det();
537        if det.is_zero() {
538            return Err(MatrixOperationError::InvalidDeterminant);
539        }
540
541        let min1 = T::zero() - T::one();
542
543        let mut augmented = Self::empty().unwrap();
544        augmented.data[0] = self.data[3]; // a
545        augmented.data[1] = self.data[1] * min1; // b
546        augmented.data[2] = self.data[2] * min1; // c
547        augmented.data[3] = self.data[0]; // d
548
549        Ok(augmented.mul_scalar(T::one() / det))
550    }
551
552    /// <https://www.mathsisfun.com/algebra/matrix-inverse-row-operations-gauss-jordan.html>
553    /// <https://www.codesansar.com/numerical-methods/python-program-inverse-matrix-using-gauss-jordan.htm>
554    fn inverse_gauss_jordan(&self) -> Result<Self, MatrixOperationError> {
555        todo!();
556    }
557}
558
559impl<T, const M: usize, const N: usize, const LEN: usize> IntoIterator for Matrix<T, M, N, LEN>
560where
561    T: Clone,
562{
563    type IntoIter = IntoIter<T, M, N, LEN>;
564    type Item = T;
565
566    fn into_iter(self) -> Self::IntoIter {
567        Self::IntoIter {
568            data: self.data,
569            i: 0,
570        }
571    }
572}
573
574#[derive(Debug)]
575pub struct IntoIter<T, const M: usize, const N: usize, const LEN: usize> {
576    i: usize,
577    data: [T; LEN],
578}
579impl<T, const M: usize, const N: usize, const LEN: usize> Iterator for IntoIter<T, M, N, LEN>
580where
581    T: Clone,
582{
583    type Item = T;
584
585    fn next(&mut self) -> Option<Self::Item> {
586        if self.i >= LEN {
587            None
588        } else {
589            let val = self.data[self.i].clone();
590            self.i += 1;
591            Some(val)
592        }
593    }
594}
595
596#[derive(Debug)]
597pub struct Iter<'a, T, const M: usize, const N: usize, const LEN: usize> {
598    i: usize,
599    data: &'a [T; LEN],
600}
601impl<'a, T, const M: usize, const N: usize, const LEN: usize> Iterator for Iter<'a, T, M, N, LEN> {
602    type Item = &'a T;
603
604    fn next(&mut self) -> Option<Self::Item> {
605        if self.i >= LEN {
606            None
607        } else {
608            let val = &self.data[self.i];
609            self.i += 1;
610            Some(val)
611        }
612    }
613}
614
615#[derive(Debug)]
616pub struct IntoIterRow<T, const M: usize, const N: usize, const LEN: usize> {
617    i: usize,
618    data: [T; LEN],
619}
620impl<T, const M: usize, const N: usize, const LEN: usize> Iterator for IntoIterRow<T, M, N, LEN>
621where
622    T: Copy + Default,
623{
624    type Item = Matrix<T, M, 1, M>;
625    fn next(&mut self) -> Option<Self::Item> {
626        if self.i >= N {
627            return None;
628        }
629
630        let offset = self.i * M;
631        let mut row: [T; M] = [Default::default(); M];
632
633        for (j, elem) in row.iter_mut().enumerate() {
634            *elem = self.data[offset + j];
635        }
636
637        self.i += 1;
638
639        if let Ok(mat) = Matrix::<T, M, 1, M>::new(row) {
640            Some(mat)
641        } else {
642            None
643        }
644    }
645}
646
647#[derive(Debug)]
648pub struct IterRow<'a, T, const M: usize, const N: usize, const LEN: usize> {
649    i: usize,
650    data: &'a [T; LEN],
651}
652impl<'a, T, const M: usize, const N: usize, const LEN: usize> Iterator for IterRow<'a, T, M, N, LEN>
653where
654    T: 'a,
655{
656    type Item = Matrix<&'a T, M, 1, M>;
657    fn next(&mut self) -> Option<Self::Item> {
658        if self.i >= N {
659            return None;
660        }
661
662        let offset = self.i * M;
663        let mut row: [&'a T; M] = [&self.data[offset]; M];
664
665        for (j, elem) in row.iter_mut().enumerate() {
666            *elem = &self.data[offset + j];
667        }
668
669        self.i += 1;
670
671        if let Ok(mat) = Matrix::<&T, M, 1, M>::new(row) {
672            Some(mat)
673        } else {
674            None
675        }
676    }
677}
678
679#[derive(Debug)]
680pub struct IntoIterCol<T, const M: usize, const N: usize, const LEN: usize> {
681    i: usize,
682    data: [T; LEN],
683}
684impl<T, const M: usize, const N: usize, const LEN: usize> Iterator for IntoIterCol<T, M, N, LEN>
685where
686    T: Copy + Default,
687{
688    type Item = Matrix<T, 1, N, N>;
689    fn next(&mut self) -> Option<Self::Item> {
690        if self.i >= M {
691            return None;
692        }
693
694        let mut col: [T; N] = [Default::default(); N];
695
696        for (j, elem) in col.iter_mut().enumerate() {
697            *elem = self.data[M * j + self.i];
698        }
699
700        self.i += 1;
701
702        if let Ok(mat) = Matrix::<T, 1, N, N>::new(col) {
703            Some(mat)
704        } else {
705            None
706        }
707    }
708}
709
710#[derive(Debug)]
711pub struct IterCol<'a, T, const M: usize, const N: usize, const LEN: usize> {
712    i: usize,
713    data: &'a [T; LEN],
714}
715impl<'a, T, const M: usize, const N: usize, const LEN: usize> Iterator for IterCol<'a, T, M, N, LEN>
716where
717    T: 'a,
718{
719    type Item = Matrix<&'a T, 1, N, N>;
720    fn next(&mut self) -> Option<Self::Item> {
721        if self.i >= N {
722            return None;
723        }
724
725        let mut col: [&'a T; N] = [&self.data[M + self.i]; N];
726        for (j, elem) in col.iter_mut().enumerate() {
727            *elem = &self.data[M * j + self.i];
728        }
729
730        self.i += 1;
731
732        if let Ok(mat) = Matrix::<&T, 1, N, N>::new(col) {
733            Some(mat)
734        } else {
735            None
736        }
737    }
738}