Repository: TheAlgorithms/Java
File: src/main/java/com/thealgorithms/maths/MatrixRank.java (Java)

Code before:
package com.thealgorithms.maths;

/**
 * This class provides a method to compute the rank of a matrix.
 * In linear algebra, the rank of a matrix is the maximum number of linearly independent rows or columns in the matrix.
 * For example, consider the following 3x3 matrix:
 * 1 2 3
 * 2 4 6
 * 3 6 9
 * Despite having 3 rows and 3 columns, this matrix only has a rank of 1 because all rows (and columns) are multiples of each other.
 * It's a fundamental concept that gives key insights into the structure of the matrix.
 * It's important to note that the rank is not only defined for square matrices but for any m x n matrix.
 *
 * @author Anup Omkar
 */
public class MatrixRank {

    private final static double EPSILON = 1e-10;

    /**
     * @brief Computes the rank of the input matrix
     *
     * @param matrix The input matrix
     * @return The rank of the input matrix
     */
    public static int computeRank(double[][] matrix) {
        int numRows = matrix.length;
        int numColumns = matrix[0].length;
        int rank = 0;

        boolean[] rowMarked = new boolean[numRows];
        if (isJaggedMatrix(matrix)) {
            throw new IllegalArgumentException("The input matrix is a jagged matrix");
        }
        for (int colIndex = 0; colIndex < numColumns; ++colIndex) {
            int pivotRow = findPivotRow(matrix, rowMarked, colIndex);
            if (pivotRow != numRows) {
                ++rank;
                rowMarked[pivotRow] = true;
                normalizePivotRow(matrix, pivotRow, colIndex);
                eliminateRows(matrix, pivotRow, colIndex);
            }
        }

Review comment (refactor):
@siriak what is a proper way of handling that? Having an abstract class with abstract method `isZero` is an overkill in my opinion. Sending an additional `epsilon` argument to `computeRank` is cumbersome. Or am I just exaggerating and it should be left as it is?

Code after:
package com.thealgorithms.maths;

/**
 * This class provides a method to compute the rank of a matrix.
 * In linear algebra, the rank of a matrix is the maximum number of linearly independent rows or columns in the matrix.
 * For example, consider the following 3x3 matrix:
 * 1 2 3
 * 2 4 6
 * 3 6 9
 * Despite having 3 rows and 3 columns, this matrix only has a rank of 1 because all rows (and columns) are multiples of each other.
 * It's a fundamental concept that gives key insights into the structure of the matrix.
 * It's important to note that the rank is not only defined for square matrices but for any m x n matrix.
 *
 * @author Anup Omkar
 */
public final class MatrixRank {

    private MatrixRank() {
    }

    private static final double EPSILON = 1e-10;

    /**
     * @brief Computes the rank of the input matrix
     *
     * @param matrix The input matrix
     * @return The rank of the input matrix
     */
    public static int computeRank(double[][] matrix) {
        validateInputMatrix(matrix);

        int numRows = matrix.length;
        int numColumns = matrix[0].length;
        int rank = 0;

        boolean[] rowMarked = new boolean[numRows];

        double[][] matrixCopy = deepCopy(matrix);

        for (int colIndex = 0; colIndex < numColumns; ++colIndex) {
            int pivotRow = findPivotRow(matrixCopy, rowMarked, colIndex);
            if (pivotRow != numRows) {
                ++rank;