distributed-computing/tasks/khalitova-am/lab_6/App/Program.cs

187 lines
4.7 KiB
C#
Raw Permalink Normal View History

2023-12-18 12:25:15 +04:00
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
public class MatrixDeterminant
{
public static double DeterminantSequential(double[][] matrix)
{
int size = matrix.Length;
if (size == 1)
{
return matrix[0][0];
}
if (size == 2)
{
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
}
double determinant = 0;
for (int i = 0; i < size; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double cofactor = sign * matrix[0][i] * DeterminantSequential(GetSubMatrix(matrix, 0, i));
determinant += cofactor;
}
return determinant;
}
public static double DeterminantParallel(double[][] matrix, int numThreads)
{
int size = matrix.Length;
if (size == 1)
{
return matrix[0][0];
}
if (size == 2)
{
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
}
double determinant = 0;
Parallel.For(0, size, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, i =>
{
double sign = (i % 2 == 0) ? 1 : -1;
double cofactor = sign * matrix[0][i] * DeterminantSequential(GetSubMatrix(matrix, 0, i));
determinant += cofactor;
});
return determinant;
}
[Benchmark]
public void DeterminantSequential_2x2()
{
double[][] matrix = GenerateRandomMatrix(2, 2);
DeterminantSequential(matrix);
}
[Benchmark]
public void DeterminantParallel_2x2_4TH()
{
double[][] matrix = GenerateRandomMatrix(2, 2);
DeterminantParallel(matrix, 4);
}
[Benchmark]
public void DeterminantParallel_2x2_8TH()
{
double[][] matrix = GenerateRandomMatrix(2, 2);
DeterminantParallel(matrix, 8);
}
[Benchmark]
public void DeterminantParallel_2x2_16TH()
{
double[][] matrix = GenerateRandomMatrix(2, 2);
DeterminantParallel(matrix, 16);
}
[Benchmark]
public void DeterminantSequential_4x4()
{
double[][] matrix = GenerateRandomMatrix(4, 4);
DeterminantSequential(matrix);
}
[Benchmark]
public void DeterminantParallel_4x4_4TH()
{
double[][] matrix = GenerateRandomMatrix(4, 4);
DeterminantParallel(matrix, 4);
}
[Benchmark]
public void DeterminantParallel_4x4_8TH()
{
double[][] matrix = GenerateRandomMatrix(4, 4);
DeterminantParallel(matrix, 8);
}
[Benchmark]
public void DeterminantParallel_4x4_16TH()
{
double[][] matrix = GenerateRandomMatrix(4, 4);
DeterminantParallel(matrix, 16);
}
[Benchmark]
public void DeterminantSequential_8x8()
{
double[][] matrix = GenerateRandomMatrix(8, 8);
DeterminantSequential(matrix);
}
[Benchmark]
public void DeterminantParallel_8x8_4TH()
{
double[][] matrix = GenerateRandomMatrix(8, 8);
DeterminantParallel(matrix, 4);
}
[Benchmark]
public void DeterminantParallel_8x8_8TH()
{
double[][] matrix = GenerateRandomMatrix(8, 8);
DeterminantParallel(matrix, 8);
}
[Benchmark]
public void DeterminantParallel_8x8_16TH()
{
double[][] matrix = GenerateRandomMatrix(8, 8);
DeterminantParallel(matrix, 16);
}
public static double[][] GenerateRandomMatrix(int rows, int cols)
{
double[][] matrix = new double[rows][];
Random rand = new Random();
for (int i = 0; i < rows; i++)
{
matrix[i] = new double[cols];
for (int j = 0; j < cols; j++)
{
matrix[i][j] = rand.Next(1, 10);
}
}
return matrix;
}
private static double[][] GetSubMatrix(double[][] matrix, int rowToRemove, int colToRemove)
{
int size = matrix.Length;
double[][] subMatrix = new double[size - 1][];
for (int i = 0, newRow = 0; i < size; i++)
{
if (i != rowToRemove)
{
subMatrix[newRow] = new double[size - 1];
for (int j = 0, newCol = 0; j < size; j++)
{
if (j != colToRemove)
{
subMatrix[newRow][newCol] = matrix[i][j];
newCol++;
}
}
newRow++;
}
}
return subMatrix;
}
}
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<MatrixDeterminant>();
Console.ReadLine();
}
}