import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class MatrixDeterminant { public static double[][] generateMatrix(int n) { double[][] matrix = new double[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { matrix[i][j] = Math.round((Math.random() * 5)); } } return matrix; } private static BigDecimal findDeterminantGauss(double[][] matrix) { int n = matrix.length; BigDecimal det = BigDecimal.ONE; for (int i = 0; i < n; i++) { int maxRow = i; for (int j = i + 1; j < n; j++) { if (Math.abs(matrix[j][i]) > Math.abs(matrix[maxRow][i])) { maxRow = j; } } if (maxRow != i) { double[] temp = matrix[i]; matrix[i] = matrix[maxRow]; matrix[maxRow] = temp; det = det.multiply(BigDecimal.valueOf(-1)); } for (int j = i + 1; j < n; j++) { double factor = matrix[j][i] / matrix[i][i]; for (int k = i; k < n; k++) { matrix[j][k] -= factor * matrix[i][k]; } } } for (int i = 0; i < n; i++) { det = det.multiply(BigDecimal.valueOf(matrix[i][i])); } return det; } private static BigDecimal findDeterminantGaussParallel(double[][] matrix, int threadsCount) { int n = matrix.length; final BigDecimal[] det = {BigDecimal.ONE}; ExecutorService executor = Executors.newFixedThreadPool(threadsCount); for (int i = 0; i < n; i++) { final int rowIdx = i; int maxRow = rowIdx; for (int j = rowIdx + 1; j < n; j++) { if (Math.abs(matrix[j][rowIdx]) > Math.abs(matrix[maxRow][rowIdx])) { maxRow = j; } } if (maxRow != rowIdx) { double[] temp = matrix[rowIdx]; matrix[rowIdx] = matrix[maxRow]; matrix[maxRow] = temp; det[0] = det[0].multiply(BigDecimal.valueOf(-1)); } executor.execute(() -> { for (int j = rowIdx + 1; j < n; j++) { double factor = matrix[j][rowIdx] / matrix[rowIdx][rowIdx]; for (int k = rowIdx; k < n; k++) { matrix[j][k] -= factor * matrix[rowIdx][k]; } } }); det[0] = det[0].multiply(BigDecimal.valueOf(matrix[rowIdx][rowIdx])); } executor.shutdown(); try { executor.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { e.printStackTrace(); } return det[0]; } public static void main(String[] args) { run(100); run(300); run(500); run(1000); run(3000); } public static void run(int n) { System.out.println("N = " + n); double[][] matrix = generateMatrix(n); double[][] matrixClone = Arrays.copyOf(matrix, n); long time = System.currentTimeMillis(); BigDecimal determinantGauss = findDeterminantGauss(matrix); System.out.println("Time gauss sync: " + (System.currentTimeMillis() - time)); time = System.currentTimeMillis(); BigDecimal determinantGaussAsync = findDeterminantGaussParallel(matrixClone, Runtime.getRuntime().availableProcessors()); System.out.println("Time gauss async: " + (System.currentTimeMillis() - time)); if (n < 101) { System.out.println("Determinant (gauss sync): " + new DecimalFormat("#0.##").format(determinantGauss)); System.out.println("Determinant (gauss async): " + new DecimalFormat("#0.##").format(determinantGaussAsync)); } System.out.println(); } }