Merge pull request 'tepechin_kirill_lab_6' (#49) from tepechin_kirill_lab_6 into main

Reviewed-on: http://student.git.athene.tech/Alexey/DAS_2023_1/pulls/49
This commit is contained in:
Alexey 2023-12-28 11:08:22 +04:00
commit 86d0303d8d
3 changed files with 244 additions and 0 deletions

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -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();
}
}