diff --git a/tepechin_kirill_lab_6/README.md b/tepechin_kirill_lab_6/README.md new file mode 100644 index 0000000..1825437 --- /dev/null +++ b/tepechin_kirill_lab_6/README.md @@ -0,0 +1,106 @@ +## Лабораторная работа №6, Тепечин Кирилл + +### Код + +#### Обычный код +````java +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; + + } +```` + +#### Параллельный код +````java +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]; + + } +```` + +### Тесты + +Тесты проводились на 16 потоках + +![result](result.png) + +### Выводы + +* На матрицах от 100 до 500 последовательное вычисление быстрее. + +* Параллельное вычисление работает быстрее на матрицах от 1000 n. + +### Ссылка на видео + +https://youtu.be/ZK1qSvbUNTk \ No newline at end of file diff --git a/tepechin_kirill_lab_6/result.png b/tepechin_kirill_lab_6/result.png new file mode 100644 index 0000000..9f24979 Binary files /dev/null and b/tepechin_kirill_lab_6/result.png differ diff --git a/tepechin_kirill_lab_6/src/MatrixDeterminant.java b/tepechin_kirill_lab_6/src/MatrixDeterminant.java new file mode 100644 index 0000000..4a5b4ad --- /dev/null +++ b/tepechin_kirill_lab_6/src/MatrixDeterminant.java @@ -0,0 +1,138 @@ +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(); + + } + + +} + +