rust_linear_algebra/matrix/
row_echelon.rs

1use super::Matrix;
2use crate::num::MinusOne;
3use crate::num::One;
4use std::fmt::Debug;
5use std::ops::{Add, Div, Mul, Sub, SubAssign};
6
7impl<K> Matrix<K>
8where
9    K: Debug
10        + Copy
11        + One
12        + MinusOne
13        + Default
14        + PartialEq
15        + Add<Output = K>
16        + Sub<Output = K>
17        + SubAssign<K>
18        + Mul<Output = K>
19        + Div<Output = K>,
20{
21    pub fn row_echelon(&self) -> Matrix<K> {
22        if self.elements.is_empty() || self.elements[0].is_empty() {
23            return self.clone();
24        }
25        if self.is_row_echelon_form() {
26            return self.clone();
27        }
28        self.gaussian_elimination(None, None)
29    }
30}
31
32impl<K> Matrix<K>
33where
34    K: Debug + Copy + Default + PartialEq,
35{
36    pub fn is_row_echelon_form(&self) -> bool {
37        let mut last_pivot_col = None;
38
39        for row in 0..self.rows() {
40            let pivot_col = self.elements[row].iter().position(|&x| x != K::default());
41
42            match pivot_col {
43                Some(col) => {
44                    if let Some(last_col) = last_pivot_col {
45                        if col <= last_col {
46                            return false;
47                        }
48                    }
49                    last_pivot_col = Some(col);
50
51                    for below_row in row + 1..self.rows() {
52                        if self.elements[below_row][col] != K::default() {
53                            return false;
54                        }
55                    }
56                }
57                None => {
58                    for below_row in row + 1..self.rows() {
59                        if self.elements[below_row].iter().any(|&x| x != K::default()) {
60                            return false;
61                        }
62                    }
63                }
64            }
65        }
66
67        true
68    }
69}