Using this class, you can calculate the determinant of a matrix with any dimension
This class uses many different methods to make the matrix triangular, and then calculates its determinant. It can be used for a matrix of high size, for example 500 x 500 or even more. The bright side of this class is that you can get the result in BigDecimal so that there is no infinity, and you always have the exact answer . By the way, using many different methods and avoiding recursion led to a much faster path with higher response performance. hope it will be helpful.
import java.math.BigDecimal; public class DeterminantCalc { private double[][] matrix; private int sign = 1; DeterminantCalc(double[][] matrix) { this.matrix = matrix; } public int getSign() { return sign; } public BigDecimal determinant() { BigDecimal deter; if (isUpperTriangular() || isLowerTriangular()) deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign)); else { makeTriangular(); deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign)); } return deter; } /* receives a matrix and makes it triangular using allowed operations on columns and rows */ public void makeTriangular() { for (int j = 0; j < matrix.length; j++) { sortCol(j); for (int i = matrix.length - 1; i > j; i--) { if (matrix[i][j] == 0) continue; double x = matrix[i][j]; double y = matrix[i - 1][j]; multiplyRow(i, (-y / x)); addRow(i, i - 1); multiplyRow(i, (-x / y)); } } } public boolean isUpperTriangular() { if (matrix.length < 2) return false; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < i; j++) { if (matrix[i][j] != 0) return false; } } return true; } public boolean isLowerTriangular() { if (matrix.length < 2) return false; for (int j = 0; j < matrix.length; j++) { for (int i = 0; j > i; i++) { if (matrix[i][j] != 0) return false; } } return true; } public BigDecimal multiplyDiameter() { BigDecimal result = BigDecimal.ONE; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix.length; j++) { if (i == j) result = result.multiply(BigDecimal.valueOf(matrix[i][j])); } } return result; } // when matrix[i][j] = 0 it makes it value non-zero public void makeNonZero(int rowPos, int colPos) { int len = matrix.length; outer: for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (matrix[i][j] != 0) { if (i == rowPos) { // found "!= 0" in it own row, so cols must be added addCol(colPos, j); break outer; } if (j == colPos) { // found "!= 0" in it own col, so rows must be added addRow(rowPos, i); break outer; } } } } } //add row1 to row2 and store in row1 public void addRow(int row1, int row2) { for (int j = 0; j < matrix.length; j++) matrix[row1][j] += matrix[row2][j]; } //add col1 to col2 and store in col1 public void addCol(int col1, int col2) { for (int i = 0; i < matrix.length; i++) matrix[i][col1] += matrix[i][col2]; } //multiply the whole row by num public void multiplyRow(int row, double num) { if (num < 0) sign *= -1; for (int j = 0; j < matrix.length; j++) { matrix[row][j] *= num; } } //multiply the whole column by num public void multiplyCol(int col, double num) { if (num < 0) sign *= -1; for (int i = 0; i < matrix.length; i++) matrix[i][col] *= num; } // sort the cols from the biggest to the lowest value public void sortCol(int col) { for (int i = matrix.length - 1; i >= col; i--) { for (int k = matrix.length - 1; k >= col; k--) { double tmp1 = matrix[i][col]; double tmp2 = matrix[k][col]; if (Math.abs(tmp1) < Math.abs(tmp2)) replaceRow(i, k); } } } //replace row1 with row2 public void replaceRow(int row1, int row2) { if (row1 != row2) sign *= -1; double[] tempRow = new double[matrix.length]; for (int j = 0; j < matrix.length; j++) { tempRow[j] = matrix[row1][j]; matrix[row1][j] = matrix[row2][j]; matrix[row2][j] = tempRow[j]; } } //replace col1 with col2 public void replaceCol(int col1, int col2) { if (col1 != col2) sign *= -1; System.out.printf("replace col%d with col%d, sign = %d%n", col1, col2, sign); double[][] tempCol = new double[matrix.length][1]; for (int i = 0; i < matrix.length; i++) { tempCol[i][0] = matrix[i][col1]; matrix[i][col1] = matrix[i][col2]; matrix[i][col2] = tempCol[i][0]; } } }
This class receives the nxn matrix from the user, and then calculates its determinant. The solution and the final triangular matrix are also shown.
import java.math.BigDecimal; import java.text.NumberFormat; import java.util.Scanner; public class DeterminantTest { public static void main(String[] args) { String determinant; //generating random numbers /*int len = 300; SecureRandom random = new SecureRandom(); double[][] matrix = new double[len][len]; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { matrix[i][j] = random.nextInt(500); System.out.printf("%15.2f", matrix[i][j]); } } System.out.println();*/ /*double[][] matrix = { {1, 5, 2, -2, 3, 2, 5, 1, 0, 5}, {4, 6, 0, -2, -2, 0, 1, 1, -2, 1}, {0, 5, 1, 0, 1, -5, -9, 0, 4, 1}, {2, 3, 5, -1, 2, 2, 0, 4, 5, -1}, {1, 0, 3, -1, 5, 1, 0, 2, 0, 2}, {1, 1, 0, -2, 5, 1, 2, 1, 1, 6}, {1, 0, 1, -1, 1, 1, 0, 1, 1, 1}, {1, 5, 5, 0, 3, 5, 5, 0, 0, 6}, {1, -5, 2, -2, 3, 2, 5, 1, 1, 5}, {1, 5, -2, -2, 3, 1, 5, 0, 0, 1} }; */ double[][] matrix = menu(); DeterminantCalc deter = new DeterminantCalc(matrix); BigDecimal det = deter.determinant(); determinant = NumberFormat.getInstance().format(det); for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix.length; j++) { System.out.printf("%15.2f", matrix[i][j]); } System.out.println(); } System.out.println(); System.out.printf("%s%s%n", "Determinant: ", determinant); System.out.printf("%s%d", "sign: ", deter.getSign()); } public static double[][] menu() { Scanner scanner = new Scanner(System.in); System.out.print("Matrix Dimension: "); int dim = scanner.nextInt(); double[][] inputMatrix = new double[dim][dim]; System.out.println("Set the Matrix: "); for (int i = 0; i < dim; i++) { System.out.printf("%5s%d%n", "row", i + 1); for (int j = 0; j < dim; j++) { System.out.printf("M[%d][%d] = ", i + 1, j + 1); inputMatrix[i][j] = scanner.nextDouble(); } System.out.println(); } scanner.close(); return inputMatrix; }}