rust_linear_algebra/matrix/
row_echelon.rs1use 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}