pub fn row_reduce(mat: &mut Vec<Vec<i32>>) -> usize {
    let row_n = mat.len();
    let col_n = mat[0].len();

    let mut row_i = 0;
    let mut col_i = 0;

    while row_i < row_n && col_i < col_n {
        // Locate a pivot with the least absolute value.
        let pivot = mat
            .iter()
            .map(|row| row[col_i])
            .enumerate()
            .skip(row_i)
            .filter(|(_, n)| *n != 0)
            .min_by_key(|(_, n)| n.unsigned_abs());

        let (prev_pivot_i, pivot) = match pivot {
            Some(p) => p,
            // All zero.
            None => {
                col_i += 1;
                continue;
            }
        };

        mat.swap(row_i, prev_pivot_i);
        let (pivot_row, rest) = mat[row_i..].split_first_mut().unwrap();

        for cur_row in rest {
            let cur = cur_row[col_i];
            if cur == 0 {
                continue;
            }

            let (cur_m, pivot_m) = lcm_div(cur, pivot);

            row_mul_sub(cur_row, cur_m, pivot_row, pivot_m);
        }

        row_i += 1;
        col_i += 1;
    }
    row_i
}
/// Transforms a matrix into row echelon form by Gaussian elimination and returns its rank.
Transforms a matrix into row echelon form by Gaussian elimination and returns its rank.
Transforms a matrix into row echelon form by Gaussian elimination and returns its rank .
pub fn row_reduce(mat: &mut Vec<Vec<i32>>) -> usize {
    let row_n = mat.len();
    let col_n = mat[0].len();
    let mut row_i = 0;
    let mut col_i = 0;
    while row_i < row_n && col_i < col_n {
        // Locate a pivot with the least absolute value.
        let pivot = mat
            .iter()
            .map(|row| row[col_i])
            .enumerate()
            .skip(row_i)
            .filter(|(_, n)| *n != 0)
            .min_by_key(|(_, n)| n.unsigned_abs());
        let (prev_pivot_i, pivot) = match pivot {
            Some(p) => p,
            // All zero.
            None => {
                col_i += 1;
                continue;
            }
        };
        mat.swap(row_i, prev_pivot_i);
        let (pivot_row, rest) = mat[row_i..].split_first_mut().unwrap();
        for cur_row in rest {
            let cur = cur_row[col_i];
            if cur == 0 {
                continue;
            }
            let (cur_m, pivot_m) = lcm_div(cur, pivot);
            row_mul_sub(cur_row, cur_m, pivot_row, pivot_m);
        }
        row_i += 1;
        col_i += 1;
    }
    row_i
}
pub fn row_reduce ( mat : & mut Vec < Vec < i32 > > ) -> usize { let row_n = mat . len ( ) ; let col_n = mat [ 0 ] . len ( ) ; let mut row_i = 0 ; let mut col_i = 0 ; while row_i < row_n && col_i < col_n { // Locate a pivot with the least absolute value. let pivot = mat . iter ( ) . map ( | row | row [ col_i ] ) . enumerate ( ) . skip ( row_i ) . filter ( | ( _ , n ) | * n != 0 ) . min_by_key ( | ( _ , n ) | n . unsigned_abs ( ) ) ; let ( prev_pivot_i , pivot ) = match pivot { Some ( p ) => p , // All zero. None => { col_i += 1 ; continue ; } } ; mat . swap ( row_i , prev_pivot_i ) ; let ( pivot_row , rest ) = mat [ row_i .. ] . split_first_mut ( ) . unwrap ( ) ; for cur_row in rest { let cur = cur_row [ col_i ] ; if cur == 0 { continue ; } let ( cur_m , pivot_m ) = lcm_div ( cur , pivot ) ; row_mul_sub ( cur_row , cur_m , pivot_row , pivot_m ) ; } row_i += 1 ; col_i += 1 ; } row_i }
Transforms a matrix into row echelon form by Gaussian elimination and returns its rank.
Transforms a matrix into row echelon form by Gaussian elimination and returns its rank .
mat
&mut Vec<Vec<i32>>
mat
&mut Vec<Vec<i32>>